Ошибка синтаксического анализа с грамматикой ANTLR4 по умолчанию для языка PDDL - PullRequest
0 голосов
/ 12 января 2019

Я относительно новичок в ANTLR, поэтому, пожалуйста, потерпите меня.

Я пытаюсь проанализировать действительный файл PDDL, и кажется в данной грамматике есть какая-то ошибка, которую я не могу найти.

line 3:13 mismatched input 'at' expecting NAME
line 8:18 mismatched input 'at' expecting NAME
line 8:25 mismatched input '?a' expecting {'(', NAME, NUMBER}

Минимальный ввод, который воспроизводит ошибку:

(define (domain foo)
(:types car place)
(:functions (at ?x - car) - place)

(:action move 
 :parameters (?a - place ?c - car)
 :precondition ()
 :effect (assign (at ?c) ?a)))

Если это имеет какое-либо значение, «официальный» BNF можно найти здесь: https://helios.hud.ac.uk/scommv/IPC-14/repository/kovacs-pddl-3.1-2011.pdf

Я использую последнюю стабильную версию antlr4 (4.7.2). Я попытался сгенерировать код Java и Python, но он выдает ту же ошибку.

1 Ответ

0 голосов
/ 13 января 2019

Одна из проблем заключается в том, что (: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.

...