У меня есть конвертер bbcode -> html, который реагирует на событие изменения в текстовом поле. В настоящее время это делается с использованием ряда регулярных выражений, и существует ряд патологических случаев. Я всегда хотел заострить карандаш на этой грамматике, но не хотел вдаваться в бритье яков. Но ... недавно я узнал о pegjs, который кажется довольно полной реализацией генерации парсера PEG. У меня есть большая часть указанной грамматики, но теперь мне осталось интересно, подходит ли это полномасштабному парсеру.Использование PEG Parser для BBode Parsing: pegjs или ... что?
Мои конкретные вопросы:
Поскольку мое приложение полагается на перевод, что я могу HTML и оставить остальное в качестве исходного текста, делает реализацию BBCode с использованием парсер, который может потерпеть неудачу на косметическим смысле ошибки синтаксиса ? Например:
[url=/foo/bar]click me![/url]
, несомненно, будет успешным после ввода закрывающей скобки на теге закрытия. Но что бы тогда увидел пользователь? С регулярным выражением я могу просто игнорировать несоответствующие вещи и рассматривать его как обычный текст для целей предварительного просмотра. С формальной грамматикой я не знаю, возможно ли это, потому что я полагаюсь на создание HTML из дерева синтаксического анализа и что не удается разобрать ... что?Непонятно, где должны быть сделаны преобразования. В формальном анализаторе на основе lex/yacc я бы имел заголовочные файлы и символы, обозначающие тип узла. В pegjs я получаю вложенные массивы с текстом узла. Я могу испускать переведенный код как действие генерируемого парсером pegjs, но кажется, что запах кода сочетается с парсером и эмиттером. Однако, если я позвоню
PEG.parse.parse()
, я получаю ответ что-то вроде этого:
[
[
"[",
"img",
"",
[
"/",
"f",
"o",
"o",
"/",
"b",
"a",
"r"
],
"",
"]"
],
[
"[/",
"img",
"]"
]
]
дается грамматика как:
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")
Я сокращающий грамматику, конечно, но ты Получите эту идею. Итак, если вы заметили, в массиве массивов нет контекстуальной информации, которая говорит мне, какой у меня есть узел, и мне осталось сделать сравнения строк снова даже подумал, что парсер уже сделал это. Я ожидаю, что можно определить обратные вызовы и использовать действия для их запуска во время синтаксического разбора, но в Интернете есть небольшая информация о том, как это можно сделать.
Я лаю неправильное дерево? Должен ли я вернуться к просмотру регулярных выражений и забыть о разборе?
Благодаря
Steve, ваш вопрос очень интересный (+1), я просто хочу сделать то же самое в расширении: разбор BBCode в текстовом поле (к сожалению, это формат, который по-прежнему используется форумом) и создать «живую» «Предварительный просмотр из введенного текста с использованием PEG.js или всего остального, кроме регулярных выражений. Вам удалось создать грамматику для парсера BBCode? Не могли бы вы поделиться своим решением через GitHub или что-нибудь еще? Это очень помогло бы мне. Большое спасибо заранее! – Sk8erPeter
Я использовал парсер bbcode [patorjk] (https://github.com/patorjk/Extendible-BBCode-Parser). Отлично работает и может быть изменен в соответствии с вашими потребностями, если у вас есть специальные теги. –
Спасибо, я уже видел эту библиотеку, но она использует регулярные выражения, которых я хотел избежать, потому что теоретически разбор BBCode с использованием регулярных выражений не может быть выполнен без ошибок ([»» link] (http: // kore- nordmann.de/blog/do_NOT_parse_using_regexp.html)) в некоторых случаях, например при их вложении друг в друга и т. д. Вот почему я хотел это сделать, используя синтаксический анализ выражения грамматического формализма. Так вы не пытались улучшить грамматику, которую вы начали? :) Разве вы не разделили его? :) – Sk8erPeter