Одна из проблем заключается в том, что (:functions (at ?x - car) - place)
не может быть проанализирован как functionsDef
. Посмотрите на это правило и правила, из которых оно состоит:
functionsDef
: '(' ':functions' functionList ')'
;
functionList
: ( atomicFunctionSkeleton+ ( '-' functionType )? )*
;
atomicFunctionSkeleton
: '(' functionSymbol typedVariableList ')'
;
functionSymbol
: NAME
;
Как видите, functionSymbol
может быть только именем, однако вход at
маркируется как ключевое слово, а не как NAME
. Если at
является действительным functionSymbol
, его необходимо добавить в качестве альтернативы:
functionSymbol
: NAME
| 'at'
;
Или, если больше ключевых слов являются допустимыми именами, введите правило name
, которое соответствует им:
functionSymbol
: name
;
name
: NAME
| 'at'
| 'start'
| 'end'
| ...
;
И, похоже, - place
должно соответствовать правилу functionType
:
functionType
: 'number'
;
но это может быть только ключевое слово number
. Если вы добавите 'place'
в качестве альтернативы:
functionType
: 'number'
| 'place'
;
это будет правильно проанализировано.
Если ввод (:functions (at ?x - car) - place)
действителен, то в этой грамматике уже есть 2 ошибки только для functionsDef
. Я не хотел бы использовать его.
EDIT
Для всех буквальных ключевых слов в правилах синтаксического анализатора (например, 'at'
, 'begin'
, 'end'
, ...) ANTLR создаст токены для закулисной работы. Так будет примерно так:
AT : 'at';
BEGIN : 'begin';
END : 'end';
...
NAME : LETTER ANY_CHAR*;
Таким образом, ввод at
всегда будет токенизироваться как AT
токен, а не как NAME
токен. Если вы хотите, чтобы at
иногда распознавался как AT
, а иногда как NAME
, сделайте, как я ранее рекомендовал: введите правило синтаксического анализатора под названием name
и дайте ему совпадать с NAME
и всеми ключевыми словами-токенами и используйте name
в правилах вашего парсера вместо NAME
.