Я написал грамматику для ANTLR v4 с целью C#, которая использует некоторые леворекурсивные правила синтаксического анализа, и каждый раз, когда я пытаюсь проанализировать некоторый пример кода, который должен использовать эти правила, механизм синтаксического анализа выбирает неправильное правило.ANTLR4 проблемы с левой рекурсией
правила синтаксического анализа:
expr
: expr COR term
| expr CAND term
| term
;
код Я пытаюсь разобрать:
...
print("Testing Program p00csx\n");
...
Посетитель, используя информацию из разбора двигателя:
public override Int32 VisitExpr(CSXParser.ExprContext context)
{
if (context == null) return 0;
switch (context.altNum)
{
case 1: //expr COR term
VisitExpr(context.expr());
Console.Write(context.COR());
VisitTerm(context.term());
break;
case 2: //expr CAND term
VisitExpr(context.expr());
Console.Write(context.CAND());
VisitTerm(context.term());
break;
case 3: //term
VisitTerm(context.term());
break;
}
return 0;
}
В этом Например, строковый литерал внутри вызова print() должен быть разрешен к 'expr', который разрешает «термин» и т. д., et c, пока у нас не будет 'stringLit'. Это пример 3 в приведенном выше примере. Вместо этого, однако, парсер выбирает случай 1, даже считает, что в тексте программы нет COR ('||').
Сайт ANTLR говорит, что v4 может обрабатывать леворекурсивные выражения, такие как эти, что заставляет меня поверить, что я должен что-то делать неправильно. Я новичок в ANTLR, и, может быть, проблема в том, что я просто забыл. Любая помощь приветствуется; Я читаю документацию и запускаю отладчик в течение нескольких дней и пытаюсь понять это.
Спасибо!
Интересно, что вы подходите к нему с этого угла. Я на самом деле начал писать своего посетителя таким образом, но код становился довольно грязным со всеми «проверять это, а затем проверять эту» логику, когда я нашел «ParserRuleContext.altNum». Есть ли способ получить только число правил синтаксического анализа, не использующих 'ParserRuleContext.altNum'? –
Вот почему я дал вам два отдельных варианта решения проблемы. :) Второй вариант оставит вас с тремя отдельными методами 'VisitOrExpr',' VisitAndExpr' и 'VisitTermExpr'. 'VisitExpr' будет по-прежнему существовать в интерфейсе, но не будет вызван посетителем по умолчанию. –
Ха-ха, извините, не видел второго. Раньше я не использовал этикетки, но я сделаю это. Благодаря! –