1
votes

Can rules/parser/lexer be set up so as to accept input that conforms to the expected structure, but the static (predefined) tokens are not written in full?

Example:

I have an ANTLR4 grammar (C# target) that I use to parse some input and use it to run specific methods of my application.

(made-up):

grammar:

setWage
    :    SETWAGE userId=STRING value=NUMBER
    ;
SETWAGE
    :    'setWage'
    ;

input:

setWage john.doe 2000

A listener that walks the parse tree in method for setWage rule (after getting text from labeled tokens) would call for example:

SalaryManager.SetWage(User.GetById("john.doe"), 2000);

My question: can Antlr (or the grammar) be set up so as to allow for example for such input:

setW john.doe 2000

assuming that there are no rules for e.g. "setWater" or "setWindow", or assuming that there are and I'm fine with Antlr choosing one of those by itself (albeit, consistently the same one).

Please note that this question is mostly academical and I'm not looking for a better way to achieve that input->action linking.

1

1 Answers

1
votes

You probably know this already, but you can elaborate the set of possible input matches

SETWAGE : 'setW' | 'setWa' | 'setWag' | 'setWage' ;

or

SETWAGE   : 'set' ('W' ('a' ('g' ('e')? )? )? ) ;

Not sure if the latter satisfies your requirement that "the static (predefined) tokens are not written in full".

Hard-coding the "synonyms" could be tedious, but how many do you need?

Here's an example I wrote to validate the approach. (Java target, but that shouldn't matter)

actions.g4

grammar actions ;
actions : action+;
action : setWage | deductSum ;

setWage   : SETWAGEOP userId=SYMBOL value=NUMBER ;
deductSum : DEDUCTSUMOP userId=SYMBOL value=NUMBER ;

//SETWAGEOP   : 'setW' | 'setWa' | 'setWag' | 'setWage' ;
SETWAGEOP   : 'set' ('W' ('a' ('g' ('e')? )? )? ) ;
DEDUCTSUMOP : 'deduct' ('S' ('u' ('m')? )? ) ;

WS      : [ \t\n\r]+ -> channel(HIDDEN) ;
SYMBOL  : [a-zA-Z][a-zA-Z0-9\.]* ;
NUMBER  : [0-9]+ ;

testinput

setW john.doe 2000
deductS john.doe 50
setWag joe.doe.III 2002
deductSu joe.doe 40
setWage jane.doe 2004
deductSum john.doe 50

Transcript:

$ antlr4 actions.g4 ; javac actions*.java ; grun actions actions -tree < testinput 
(actions (action (setWage setW john.doe 2000)) (action (deductSum deductS john.doe 50)) (action (setWage setWag joe.doe.III 2002)) (action (deductSum deductSu joe.doe 40)) (action (setWage setWage jane.doe 2004)) (action (deductSum deductSum john.doe 50)))