Pull to refresh

Comments 17

Одна из основных вещей, которые должен уметь компилятор — это нормальные сообщения об ошибках. А в тестах я бы написал тест со строкой ( (только открывающая скобка) одновременно с тестами на правильных выражениях — и точно до того, как считать что‐либо связанное с разбором достаточно законченным для выкладки. Насколько я знаю, отсутствие вменяемых сообщения об ошибках разбора — это одна из проблем различных генераторов парсеров. Как с ошибками здесь? И, в частности, насколько хорошо debug_parser! может сослаться на исходный код? Т.е. к примеру, для https://github.com/alexander-smoktal/rust-macroparser/blob/dde3099d580a6b21db83a7ce88ba292be9e1e921/src/main.rs#L136-L139 может ли debug_parser! понять (вывести в терминал)


  • Где находится вызов rule!?
  • Какой строке определения rule! соответствует вызов debug_parser!?
  • Где находится вызов and!?
  • В какой строке определения and! находится вызов debug_parser!?
  • Где находится код самого определения debug_parser!?

Да, обработка ошибок является довольно сложным аспектом синтаксического разбора. Я не стал писать обработчик, что бы не усложнять код.


Rust содержит макросы file!, line! и column!, которые можно использовать для сохранении информации о вызовах.


Так же лексический анализатор может содержать информации о позиции в исходном коде, что помогает значительно улучшить сообщение об ошибках.

file!, line! и column! дают только информацию о том, где вызов rule!. Уже предчувствую обычный для C ад отладки макросов (когда весь код, раскрытый из макроса — одна строчка с точки зрения gdb и из всех методик отладки доступен только printf (ну и stepi, но это жутко неудобно)).

В процессе разбора можно сохранять информацию о парсинге. Например использовать монады (тонкая шутка).

Отладка парсера сама по себе штука сложная. Часто даже отладчик не сильно помогает, когда на стеке пару десятков рекурсивных вызовов функций и конкретно к этой последовательности вызовов парсер может прийти сотнями вариантов разбора.

Я знаю один действенный вариант отладки анализатора — покрывать все правила тестами. Во всех других случаях отладчик помогает очень слабо.
Немного поискал и нашел cargo-expand. Он позволяет выводить сгенерированный макросами код. При желании, можно сначала разворачивать, а потом включать в проект и отлаживать.

Спасибо за труд!


Но не думали ли вы скооперироваться с сообществом и написать свой ANTLR рантайм для Rust? Интерес есть, а плюсов много: стабильность, оптимизированность и поддержка фич ANTLR (левая рекурсия, семантические предикаты, большое количество грамматик и другое). Также это по-моему неплохой опыт по Rust + значимая строчка в резюме.

Пожалуйста.

Не думал. Моего ентузиазма, к сожалению, хватает ненадолго. Если кто-то будет писать, я бы мог вносить вклад. Но если я начну его писать, есть очень большой риск, что разработка затянется.
Ну по крайней мере можно в задаче написать, что типа готов помогать. :) Может и других мотивации станет больше.

У ANTLR больше всего грамматик и скорее всего самое большое комьюнити.


Ну и вообще я уже писал выше:


стабильность, оптимизированность и поддержка фич ANTLR (левая рекурсия, семантические предикаты, большое количество грамматик и другое)
Спойлер Функции разбора числа и терминалов отформатирован неверно. Поправьте, пожалуйста
А можно ли таким образом выполнять нужный код в зависимости от типа параметра? Например иметь разный код для stat и для expr:

macro_rule! fancy_macro => {
  [$arg: expr, $($ex: expr),? $($st:stat),?] => {
    $($expr($arg)),?
    $(
        $st;
        $arg
     ),?
  }
}
Не знаю, надо проверять, но идея интересная. Но мне кажется, что это не соответствует правилам подстановки по образцу.
Результат внешне очень похож на Boost.Spirit, разве что чуть более многословный. Но при этом насколько же проще оно выглядит внутри! Синтаксические макросы безусловно намного более удобный инструмент метапрограммирования в сравнение с шаблонами C++ (что впрочем совсем не удивительно, т.к. при создание шаблонов о МП никто и не думал).
Sign up to leave a comment.

Articles