ANTLR4: какому шаблону проектирования следовать?

#antlr4

#antlr4

Вопрос:

У меня есть «выражение» правила ANTR4, которое может быть либо «математикой», либо «сравнением», но «сравнение» может содержать «математику». Вот конкретный код:

 expression
    : ID
    | maths
    | comparison
    ;

maths
    : maths_atom ((PLUS | MINUS) maths_atom) ? // "?" because in fact there is first multiplication then pow and I don't want to force a multiplication to make an addition
    ;

maths_atom
    : NUMBER
    | ID
    | OPEN_PAR expression CLOSE_PAR
    ;

comparison
    : comp_atom ((EQUALS | NOT_EQUALS) comp_atom) ?
    ;

comp_atom
    : ID
    | maths // here is the expression of interest
    | OPEN_PAR expression CLOSE_PAR
    ;
    
  

Если я предоставляю, например, 6 в качестве входных данных, это нормально для дерева синтаксического анализа, потому что оно обнаруживает maths . Но в плагине ANTLR4 для Intellij Idea мое expression правило помечено красным цветом — неоднозначность. Должен ли я попрощаться с коротким деревом синтаксического анализа и разрешить только maths прогиб comparison в expression , чтобы это больше не было таким двусмысленным?

Ответ №1:

Проблема в том, что когда синтаксический анализатор видит 6 , что является NUMBER , у него есть два пути достижения его через вашу грамматику:

  expression - maths - maths_atom - NUMBER
  

или

  expression - comparison - comp_atom - NUMBER
  

Эта двусмысленность вызывает ошибку, которую вы видите.

Вы можете исправить это, сгладив грамматику вашего синтаксического анализатора, как показано в этом руководстве:

 start
    : expr | <EOF>
    ;
    
expr
    : expr (PLUS | MINUS) expr         # ADDGRP
    | expr (EQUALS | NOT_EQUALS) expr  # COMPGRP
    | OPEN_PAR expression CLOSE_PAR    # PARENGRP
    | NUMBER                           # NUM
    | ID                               # IDENT
    ;
  

Комментарии:

1. Извините, это была ошибка, в сравнении нет «ЧИСЛА». Я отредактировал вопрос.

2. Кстати, моя грамматика слишком сложна, чтобы ее можно было сгладить подобным образом. Прочитайте мою первую команду в коде

3. @bananasmoothii Тогда ID в этом проблема: вы можете получить доступ к нему напрямую или через последовательность правил. В любом случае, сглаженная грамматика может распознавать ваш исходный синтаксис, то есть она позволит вам самостоятельно вводить ID .

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

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