Комментарии 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, но это жутко неудобно)).
Отладка парсера сама по себе штука сложная. Часто даже отладчик не сильно помогает, когда на стеке пару десятков рекурсивных вызовов функций и конкретно к этой последовательности вызовов парсер может прийти сотнями вариантов разбора.
Я знаю один действенный вариант отладки анализатора — покрывать все правила тестами. Во всех других случаях отладчик помогает очень слабо.
Спасибо за труд!
Но не думали ли вы скооперироваться с сообществом и написать свой ANTLR рантайм для Rust? Интерес есть, а плюсов много: стабильность, оптимизированность и поддержка фич ANTLR (левая рекурсия, семантические предикаты, большое количество грамматик и другое). Также это по-моему неплохой опыт по Rust + значимая строчка в резюме.
Не думал. Моего ентузиазма, к сожалению, хватает ненадолго. Если кто-то будет писать, я бы мог вносить вклад. Но если я начну его писать, есть очень большой риск, что разработка затянется.
А зачем, когда есть, например, rust-peg, да и вообще, уже десятки их
К слову, в nightly версии компилятора, помимо существующих +
и *
добавили квантификатор ?
для задания опционального шаблона.
Теперь, например, можно финальную запятую обрабатывать как $(,)?
macro_rule! fancy_macro => {
[$arg: expr, $($ex: expr),? $($st:stat),?] => {
$($expr($arg)),?
$(
$st;
$arg
),?
}
}
LL(*) парсер с использованием Rust макросов