1 lexer grammar t020fuzzy; 2 options { 3 language=JavaScript; 4 filter=true; 5 } 6 7 @members { 8 this.outbuf = []; 9 this.output = function(msg) { 10 this.outbuf.push(msg); 11 }; 12 } 13 14 IMPORT 15 : 'import' WS name=QIDStar WS? ';' 16 ; 17 18 /** Avoids having "return foo;" match as a field */ 19 RETURN 20 : 'return' (options {greedy=false;}:.)* ';' 21 ; 22 23 CLASS 24 : 'class' WS name=ID WS? ('extends' WS QID WS?)? 25 ('implements' WS QID WS? (',' WS? QID WS?)*)? '{' 26 {this.output("found class "+$name.text+"\n");} 27 ; 28 29 METHOD 30 : TYPE WS name=ID WS? '(' ( ARG WS? (',' WS? ARG WS?)* )? ')' WS? 31 ('throws' WS QID WS? (',' WS? QID WS?)*)? '{' 32 {this.output("found method "+$name.text+"\n");} 33 ; 34 35 FIELD 36 : TYPE WS name=ID '[]'? WS? (';'|'=') 37 {this.output("found var "+$name.text+"\n");} 38 ; 39 40 STAT: ('if'|'while'|'switch'|'for') WS? '(' ; 41 42 CALL 43 : name=QID WS? '(' 44 {this.output("found call "+$name.text+"\n");} 45 ; 46 47 COMMENT 48 : '/*' (options {greedy=false;} : . )* '*/' 49 {this.output("found comment "+this.getText()+"\n");} 50 ; 51 52 SL_COMMENT 53 : '//' (options {greedy=false;} : . )* '\n' 54 {this.output("found // comment "+this.getText()+"\n");} 55 ; 56 57 STRING 58 : '"' (options {greedy=false;}: ESC | .)* '"' 59 ; 60 61 CHAR 62 : '\'' (options {greedy=false;}: ESC | .)* '\'' 63 ; 64 65 WS : (' '|'\t'|'\n')+ 66 ; 67 68 fragment 69 QID : ID ('.' ID)* 70 ; 71 72 /** QID cannot see beyond end of token so using QID '.*'? somewhere won't 73 * ever match since k=1 lookahead in the QID loop of '.' will make it loop. 74 * I made this rule to compensate. 75 */ 76 fragment 77 QIDStar 78 : ID ('.' ID)* '.*'? 79 ; 80 81 fragment 82 TYPE: QID '[]'? 83 ; 84 85 fragment 86 ARG : TYPE WS ID 87 ; 88 89 fragment 90 ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')* 91 ; 92 93 fragment 94 ESC : '\\' ('"'|'\''|'\\') 95 ; 96