| lexer grammar t020fuzzy; |
| options { |
| language=JavaScript; |
| filter=true; |
| } |
| |
| @members { |
| this.outbuf = []; |
| this.output = function(msg) { |
| this.outbuf.push(msg); |
| }; |
| } |
| |
| IMPORT |
| : 'import' WS name=QIDStar WS? ';' |
| ; |
| |
| /** Avoids having "return foo;" match as a field */ |
| RETURN |
| : 'return' (options {greedy=false;}:.)* ';' |
| ; |
| |
| CLASS |
| : 'class' WS name=ID WS? ('extends' WS QID WS?)? |
| ('implements' WS QID WS? (',' WS? QID WS?)*)? '{' |
| {this.output("found class "+$name.text+"\n");} |
| ; |
| |
| METHOD |
| : TYPE WS name=ID WS? '(' ( ARG WS? (',' WS? ARG WS?)* )? ')' WS? |
| ('throws' WS QID WS? (',' WS? QID WS?)*)? '{' |
| {this.output("found method "+$name.text+"\n");} |
| ; |
| |
| FIELD |
| : TYPE WS name=ID '[]'? WS? (';'|'=') |
| {this.output("found var "+$name.text+"\n");} |
| ; |
| |
| STAT: ('if'|'while'|'switch'|'for') WS? '(' ; |
| |
| CALL |
| : name=QID WS? '(' |
| {this.output("found call "+$name.text+"\n");} |
| ; |
| |
| COMMENT |
| : '/*' (options {greedy=false;} : . )* '*/' |
| {this.output("found comment "+this.getText()+"\n");} |
| ; |
| |
| SL_COMMENT |
| : '//' (options {greedy=false;} : . )* '\n' |
| {this.output("found // comment "+this.getText()+"\n");} |
| ; |
| |
| STRING |
| : '"' (options {greedy=false;}: ESC | .)* '"' |
| ; |
| |
| CHAR |
| : '\'' (options {greedy=false;}: ESC | .)* '\'' |
| ; |
| |
| WS : (' '|'\t'|'\n')+ |
| ; |
| |
| fragment |
| QID : ID ('.' ID)* |
| ; |
| |
| /** QID cannot see beyond end of token so using QID '.*'? somewhere won't |
| * ever match since k=1 lookahead in the QID loop of '.' will make it loop. |
| * I made this rule to compensate. |
| */ |
| fragment |
| QIDStar |
| : ID ('.' ID)* '.*'? |
| ; |
| |
| fragment |
| TYPE: QID '[]'? |
| ; |
| |
| fragment |
| ARG : TYPE WS ID |
| ; |
| |
| fragment |
| ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')* |
| ; |
| |
| fragment |
| ESC : '\\' ('"'|'\''|'\\') |
| ; |