Reputation: 363
I am relatively new to ANTLR so please bear with me.
I'm trying to parse a valid PDDL file and it seems the given grammar has some kind of error I cannot seem to find.
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}
A minimal input that reproduces the error:
(define (domain foo)
(:types car place)
(:functions (at ?x - car) - place)
(:action move
:parameters (?a - place ?c - car)
:precondition ()
:effect (assign (at ?c) ?a)))
If it is of any use, the "official" BNF can be found here: https://helios.hud.ac.uk/scommv/IPC-14/repository/kovacs-pddl-3.1-2011.pdf
I'm using the latest stable antlr4 (4.7.2). I have tried generating Java and Python code, but it outputs the same error.
Upvotes: 1
Views: 154
Reputation: 170178
One of the problems is that (:functions (at ?x - car) - place)
cannot be parsed as a functionsDef
. Have a look at this rule and the rules it's made up of:
functionsDef
: '(' ':functions' functionList ')'
;
functionList
: ( atomicFunctionSkeleton+ ( '-' functionType )? )*
;
atomicFunctionSkeleton
: '(' functionSymbol typedVariableList ')'
;
functionSymbol
: NAME
;
As you can see, a functionSymbol
can only be a name, yet the input at
is being tokenised as a keyword, not as a NAME
. If at
is a valid functionSymbol
, it must be added to it as an alternative:
functionSymbol
: NAME
| 'at'
;
Or, if more keywords are valid names, introduce a name
rule that matches them:
functionSymbol
: name
;
name
: NAME
| 'at'
| 'start'
| 'end'
| ...
;
And is seems - place
should be matched by the rule functionType
:
functionType
: 'number'
;
but that can apparently only be the keyword number
. If you add 'place'
as an alternative:
functionType
: 'number'
| 'place'
;
it would be parsed correctly.
Assuming the input (:functions (at ?x - car) - place)
is valid, then there are already 2 errors in that grammar for a functionsDef
alone. I would be hesitant to use it.
For all the literal keywords inside parser rules (like 'at'
, 'begin'
, 'end'
, ...) ANTLR will create tokens for behind the scenes. So it will be the same as something like this:
AT : 'at';
BEGIN : 'begin';
END : 'end';
...
NAME : LETTER ANY_CHAR*;
So the input at
will always be tokenised as an AT
token, never as a NAME
token. If you want at
to be sometimes recognised as an AT
and other times as a NAME
, do as I previously recommended: introduce a parser rule called name
and let it match NAME
and all keyword-tokens and use name
in your parser rules instead of NAME
.
Upvotes: 2