Mam konwerter bbcode -> html, który reaguje na zdarzenie change w obszarze tekstowym. Obecnie odbywa się to za pomocą serii wyrażeń regularnych i istnieje wiele patologicznych przypadków. Zawsze chciałem wyostrzyć ołówek w tej gramatyce, ale nie chciałem zagłębiać się w golenie. Ale ... niedawno dowiedziałem się o pegjs, co wydaje się całkiem kompletną implementacją generacji parserów PEG. Mam większość gramatyki określonej, ale teraz zastanawiam się, czy jest to odpowiednie użycie pełnowymiarowego parsera.Korzystanie z PEG Parser do BBCode Parsing: pegjs lub ... co?
Moje konkretne pytania:
Ponieważ mój wniosek opiera się na tłumaczenia, co mogę do HTML i pozostawiając resztę w postaci czystego tekstu, czy wdrożenie BBcode użyciu parser, które mogą nie działać na błąd składni ma sens ? Na przykład:
[url=/foo/bar]click me![/url]
z pewnością odniosą sukces po wprowadzeniu nawiasu zamykającego na znaczniku zamykającym. Ale co zobaczy użytkownik w międzyczasie? W przypadku wyrażenia regularnego mogę po prostu zignorować niezgodne elementy i traktować je jako zwykły tekst do celów podglądu. Z formalną gramatyką nie wiem, czy jest to możliwe, ponieważ polegam na tworzeniu kodu HTML z drzewa parsowania, a co nie, parsowanie jest ... co?Nie jestem pewien, gdzie należy dokonać transformacji. W formalnym parserze opartym na lex/yacc będę miał pliki nagłówkowe i symbole, które oznaczają typ węzła. W pegjs otrzymuję tablice zagnieżdżone z tekstem węzła. Mogę wyemitować przetłumaczony kod jako działanie parsera generowanego przez pegjs, ale wydaje się, że jest to zapach kodu łączący parser i emiter. Jednakże, jeśli zadzwonię
PEG.parse.parse()
, wrócę mniej więcej tak:
[
[
"[",
"img",
"",
[
"/",
"f",
"o",
"o",
"/",
"b",
"a",
"r"
],
"",
"]"
],
[
"[/",
"img",
"]"
]
]
podane gramatyki jak:
document
= (open_tag/close_tag/new_line/text)*
open_tag
= ("[" tag_name "="? tag_data? tag_attributes? "]")
close_tag
= ("[/" tag_name "]")
text
= non_tag+
non_tag
= [\n\[\]]
new_line
= ("\r\n"/"\n")
mam abbreviating gramatykę, oczywiście, ale wpadnij na pomysł. Tak więc, jeśli zauważysz, nie ma informacji kontekstowych w tablicy tablic, która mówi mi, jaki rodzaj węzła mam i mam zamiar zrobić porównania ciągów ponownie, nawet jeśli parser już to zrobił. Oczekuję, że możliwe jest zdefiniowanie wywołań zwrotnych i użycie akcji w celu ich uruchomienia podczas analizy, ale w Internecie jest niewiele informacji na temat tego, jak można to zrobić.
Czy szczerzę złe drzewo? Czy powinienem wrócić do skanowania regex i zapomnieć o parsowaniu?
Dzięki
Steve, twoje pytanie jest bardzo interesujące (+1), po prostu chcę zrobić to samo w rozszerzeniu: parsowanie BBCode w textarea (niestety jest to format, którego wciąż używa forum) i tworzenie "live" "podgląd z wpisanego tekstu za pomocą PEG.js lub cokolwiek innego oprócz wyrażeń regularnych. Czy udało Ci się stworzyć gramatykę dla parsera BBCode? Czy nie możesz podzielić się swoim rozwiązaniem za pośrednictwem GitHub lub cokolwiek innego? To bardzo mi pomogło. Bardzo dziękuję z góry! – Sk8erPeter
Użyłem [parsera bbcode patorjk] (https://github.com/patorjk/Extendible-BBCode-Parser). Działa świetnie i można go dostosować do własnych potrzeb, jeśli masz specjalne tagi. –
Dzięki, ja już widziałem tę bibliotekę, ale używa wyrażeń regularnych, których chciałem uniknąć, ponieważ teoretycznie, parsowanie BBCode za pomocą wyrażeń regularnych nie może być wykonane bez błędów ([»» link] (http: // kore- nordmann.de/blog/do_NOT_parse_using_regexp.html)) w niektórych przypadkach, np. kiedy zagnieżdżam je w sobie nawzajem itd. Dlatego chciałem to zrobić za pomocą analizowania formalizmu ekspresji gramatycznej. Czy nie próbowałeś ulepszyć gramatyki, którą zacząłeś? :) Nie możesz podzielić się z tym podstawą? :) – Sk8erPeter