Java – ANTLR independent input

I have a syntax file, boardfile G4 (only relevant parts):

grammar Board;

//Tokens
GADGET : 'squareBumper' | 'circleBumper' | 'triangleBumper' | 'leftFlipper' | 'rightFlipper' | 'absorber' | 'portal' ;
NAME : [A-Za-z_][A-Za-z_0-9]* ;
INT : [0-9]+ ;
FLOAT : '-'?[0-9]+('.'[0-9]+)? ;
COMMENT : '#' ~( '\r' | '\n' )*;
WHITESPACE : [ \t\r\n]+ -> skip ;
KEY : [a-z] | [0-9] | 'shift' | 'ctrl' | 'alt' | 'Meta' | 'space' | 'left' | 'right' | 'up' | 'down' | 'minus' | 'equals' | 'backspace' | 'openbracket' | 'closebracket' | 'backslash' | 'semicolon' | 'quote' | 'enter' | 'comma' | 'period' | 'slash' ;
KEYPRESS : 'keyup' | 'keydown' ;

//Rules
file : define+ EOF ;
define : board | ball | gadget | fire | COMMENT | key ;
board : 'board' 'name' '=' name ('gravity' '=' gravity)? ('friction1' '=' friction1)? ('friction2' '=' friction2)? ;
ball : 'ball' 'name' '=' name 'x' '=' xfloat 'y' '=' yfloat 'xVeLocity' '=' xvel 'yVeLocity' '=' yvel ;
gadget : gadgettype 'name' '=' name 'x' '=' xint 'y' '=' yint ('width' '=' width 'height' '=' height)? ('orientation' '=' orientation)? ('otherBoard' '=' name 'otherPortal' '=' name)? ;
fire : 'fire' 'trigger' '=' trigger 'action' '=' action ;
key : keytype 'key' '=' KEY 'action' '=' name ;

name : NAME ;
gadgettype : GADGET ;
keytype : KEYPRESS ;
gravity : FLOAT ;
friction1 : FLOAT ;
friction2 : FLOAT ;
trigger : NAME ;
action : NAME ;
yfloat : FLOAT ;
xfloat : FLOAT ;
yint : INT ;
xint : INT ;
xvel : FLOAT ;
yvel : FLOAT ;
orientation : INT ;
width : INT ;
height : INT ;

This generates a lexical analyzer and parser However, when I use it for the following file, it will give the following error:

line 12:0 extraneous input 'keyup' expecting {<EOF>,KEYPRESS}

File to parse:

board name = keysBoard gravity = 5.0 friction1 = 0.0 friction2 = 0.0

# define a ball
ball name=Ball x=0.5 y=0.5 xVeLocity=2.5 yVeLocity=2.5

# add some flippers
leftFlipper name=FlipL1 x=16 y=2 orientation=0
leftFlipper name=FlipL2 x=16 y=9 orientation=0

# add keys. lots of keys.
keyup key=space action=apple
keydown key=a action=ball
keyup key=backslash action=cat
keydown key=period action=dog

I experienced other problems with this error in so, but no one helped me I can't figure out what's wrong Why did I receive this error?

Solution

The string "Keyup" is marked as the name tag: that's the problem

You must realize that the lexical analyzer runs independently of the parser If the parser tries to match the keypress token, the lexical analyzer will not "listen" to it, but just construct a token according to the rules:

>Match rules that consume the most characters > if more rules match the same number of characters, select the rule defined first

Consider these rules and their order:

NAME : [A-Za-z_][A-Za-z_0-9]* ;

INT : [0-9]+ ;

KEY : [a-z] | [0-9] | 'shift' | 'ctrl' | 'alt' | 'Meta' | 'space' | 'left' | 'right' | 'up' | 'down' | 'minus' | 'equals' | 'backspace' | 'openbracket' | 'closebracket' | 'backslash' | 'semicolon' | 'quote' | 'enter' | 'comma' | 'period' | 'slash' ;

KEYPRESS : 'keyup' | 'keydown' ;

The name token will be created before most key alternatives, and all keypress alternatives will be created

And since int matches one or more numbers and is defined before key and has a single number substitution, it is obvious that the lexical analyzer will never generate a key or keypress token

If you move the name and int rules under the key and keypress rules, most tokens will be built as you expect, which is my guess

edit

Possible solutions are as follows:

KEY : [a-z] | 'shift' | 'ctrl' | 'alt' | 'Meta' | 'space' | 'left' | 'right' | 'up' | 'down' | 'minus' | 'equals' | 'backspace' | 'openbracket' | 'closebracket' | 'backslash' | 'semicolon' | 'quote' | 'enter' | 'comma' | 'period' | 'slash' ;

KEYPRESS : 'keyup' | 'keydown' ;

NAME : [A-Za-z_][A-Za-z_0-9]* ;

SINGLE_DIGIT : [0-9] ;

INT : [0-9]+ ;

That is, I deleted the [0-9] substitution from the key and introduced a single_ Digit rule (before int rule!)

Now create some additional parser rules:

integer : INT | SINGLE_DIGIT ;

key : KEY | SINGLE_DIGIT ;

And change all ints appearing in the parser rules to integers (do not call your rule int: it is a reserved word) and change all keys to key

And you may also want to do something similar to the [A-Z] alternative in name and key (that is, a single lowercase character will never be marked as name now, but always as key)

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>