options { LOOKAHEAD=1; } PARSER_BEGIN(Q1) class KeyWord { public String tok; public int line; public int nest; public KeyWord(String t, int l, int n) { tok=t; line=l; nest=n; } } public class Q1 { /*** The counters ***/ static int maxNesting = 0; static int currNesting = 0; static int numGotos = 0; /*** Storing keyword information ***/ static java.util.Vector kwInfo = new java.util.Vector(); static void printKwInfo() { System.out.println("Information on keywords:"); System.out.println("\tWord\tLine\tNesting"); for(int i=0; i | <"/*" (~["*"])* "*" ("*" | ~["*","/"] (~["*"])* "*")* "/"> } TOKEN : { < LCURL : "{" > | < RCURL : "}" > | < WHILE : "while" > | < IF : "if" > | < FOR : "for" > | < GOTO : "goto" > } SPECIAL_TOKEN : /* COMMENTS */ { | } SPECIAL_TOKEN : /* Make it ignore identifiers that might contain keywords, for example * "my_while", which otherwise would get returned as a */ { < IDENT : ( | ["0"-"9"])+ > | < #LETTER : ["A"-"Z", "a"-"z", "_"] > | < OTHER : ~[] > } /*************************/ /***** GRAMMAR RULES *****/ /*************************/ void c_prog() : {} { ( tok() )+ ( ) } void tok() : {} { { currNesting++; if (currNesting>maxNesting) maxNesting = currNesting; } | { currNesting--; } | ( | | ) { kwInfo.addElement(new KeyWord(token.image, token.beginLine, currNesting)); } | { numGotos++; } }