Я работаю над транспилятором reStructuredText в Rust, и мне нужен совет относительно того, как следует структурировать лексирование в языках с рекурсивными структурами. Например, списки внутри списков возможны в rST:
* This is a list item
* This is a sub list item
* And here we are at the preceding indentation level again.
По умолчанию docutils.parsers.rst
использует подход сканирования ввод по одной строке за раз:
Синтаксический анализатор reStructuredText реализован как конечный автомат, проверяющий ввод по одной строке за раз.
Упомянутый конечный автомат в основном работает с набором состояний в форме (regex, match_method, next_state)
. Он пытается сопоставить текущую строку с regex
на основе текущего состояния и запускает match_method
при переходе к next_state
, если совпадение завершается успешно, делая это до тех пор, пока не закончатся строки для сканирования.
Тогда мой вопрос: это лучший подход к сканированию такого языка, как rST? До сих пор мой подход заключался в создании итератора Chars
для источник и разъедают источник, пытаясь сопоставить со структурами в текущем скаляре Unicode. В какой-то степени это работает, когда все, что я делаю, - это сканирование встроенного контента, но теперь я пришел к осознанию того, что обработка рекурсивных структур уровня тела, таких как вложенные списки, будет головной болью. Похоже, мне понадобится целая куча состояний с повторяющимися регулярными выражениями и родственными методами во многих состояниях для сопоставления с отступами перед новыми строками и т. Д.
Было бы лучше иметь итератор строк исходного кода и сопоставить их на построчной основе, и если такая строка, как
* this is an indented list item
встречается в State::Body
, просто перейти в такое состояние, как State::BulletList
, и начать лексирование строк в соответствии с указанными там правилами? Вышеупомянутая строка может быть преобразована, например, в последовательность
TokenType::Indent, TokenType::Bullet, TokenType::BodyText
Есть мысли по этому поводу?
*
для (1) маркированного списка, (2) начала курсива или (3) начала жирного шрифта. В этом смысле лексический анализатор не зависит от контекста. И поэтому вашему лексеру не должен требоваться конечный автомат. - person Matthieu M.   schedule 05.06.2020