📄 cminus.g
字号:
grammar CMinus;options{ output = AST; ASTLabelType = CommonTree;}tokens{ POS; NEG; POSTFIX; PREFIX; NOP; PROGRAM; FUNCTION; VARDEF; ARRDEF; VARPAR; ARRPAR; BLOCK; ASSIGN; EXPR; EXPRLIST; CALL; INDEX; NOT; NEGATE; FUNCTIONS; VARIABLES; PARAMATERS; STMTS; NUM; VAR; }@header { import java.util.HashMap; import java.io.*; import java.util.Properties;}@members { Stack paraphrases = new Stack(); public String getErrorMessage(RecognitionException e, String[] tokenNames){ String msg = super.getErrorMessage(e, tokenNames); if (paraphrases.size()>0){ msg=msg+" "+paraphrases.peek(); } return msg; } public static String unquote(String a) { Properties prop = new Properties(); try { prop.load(new ByteArrayInputStream(("x=" + a).getBytes())); } catch (IOException ignore) {} return prop.getProperty("x"); } public void emitErrorMessage(String s){ Main.print_err(s); }}program : varDeclList funDeclList -> ^(PROGRAM ^(VARIABLES varDeclList) ^(FUNCTIONS funDeclList) ^(CALL {adaptor.create(ID,"main")} ^(EXPRLIST)) ) EOF;varDeclList@init{ paraphrases.push("in variable declaration");}@after { paraphrases.pop();} : varDecl*;varDecl : TYPE name=ID ';' -> ^(VARDEF TYPE ID) | TYPE name=ID '[' INT ']' ';' -> ^(ARRDEF TYPE ID INT);funDeclList : funDecl*;funDecl@init{ paraphrases.push("in function declaration");}@after { paraphrases.pop();} : TYPE name=ID '(' paramDeclList ')' act=block -> ^(FUNCTION TYPE $name ^(PARAMATERS paramDeclList) $act);paramDeclList@init{ paraphrases.push("in parmater declaration");}@after { paraphrases.pop();} : (paramDecl (',' paramDecl)*)? -> paramDecl*;paramDecl : TYPE ID -> ^(VARPAR TYPE ID) | TYPE ID '[' ']' -> ^(ARRPAR TYPE ID);block @init{ paraphrases.push("in block");}@after { paraphrases.pop();} : '{' vars=varDeclList stmts=stmtList '}' -> ^(BLOCK ^(VARIABLES $vars) ^(STMTS $stmts));stmtList: stmt*;stmt@init{ paraphrases.push("in statement");}@after{ paraphrases.pop();} : ';' -> NOP | expr ';' -> expr | RETURN expr ';' -> ^(RETURN expr) | READ ID ';' -> ^(READ ID) | WRITE expr ';' -> ^(WRITE expr) | WRITELN ';' -> WRITELN | BREAK ';' -> BREAK | ifStmt | WHILE '(' expr ')' stmt -> ^(WHILE expr stmt) | 'do' stmt WHILE '(' expr ')' ';' -> stmt ^(WHILE expr stmt) | 'for' '(' ini=expr ';' tes=expr ';' inc=expr ')' stmt -> $ini ^(WHILE $tes ^(BLOCK ^(VARIABLES) ^(STMTS stmt $inc))) | block;ifStmt options{ backtrack=true; }: IF '(' expr ')' c1=stmt 'else' c2=stmt -> ^(IF ^(EXPR expr) $c1 $c2) | 'unless' '(' expr ')' c1=stmt 'else' c2=stmt -> ^(IF ^(EXPR expr) $c2 $c1) | IF '(' expr ')' c1=stmt -> ^(IF ^(EXPR expr) $c1 NOP) | 'unless' '(' expr ')' c1=stmt -> ^(IF ^(EXPR expr) NOP $c1) ; exproptions{ backtrack=true;}@init{ paraphrases.push("in expression");}@after { paraphrases.pop();} : (ID|arrayIndex) a='=' expr -> {$ID != null}? ^(ASSIGN[$a,"ASSIGN"] ID expr) -> ^(ASSIGN[$a,"ASSIGN"] arrayIndex expr) | orExpr;orExpr : andExpr (('or'|'||')^ andExpr)*;andExpr : equalityExpr (('and'|'&&')^ equalityExpr)*; equalityExpr : comparisonExpr (('=='|'!='|'<>')^ comparisonExpr)*;comparisonExpr : additiveExpr (('>'|'<'|'<='|'>=')^ additiveExpr)*;additiveExpr : multiplicativeExpr (('+'|'-')^ multiplicativeExpr)*;multiplicativeExpr : notExpr (('*'|'/')^ notExpr)*;notExpr : (op='!'|'not')? negationExpr -> {$op != null}? ^(NOT[$op,"NOT"] negationExpr) -> negationExpr;negationExpr : (op='-')? primary -> {$op != null}? ^(NEGATE[$op,"NEGATE"] primary) -> primary;primary : atom |'(' expr ')' -> expr;atom : SCHAR-> ^( NUM { adaptor.create(INT,String.valueOf((int) unquote($SCHAR.text).charAt(1) )) } ) | ID '++' -> ^(POSTFIX ^(VAR ID) ^(NUM {adaptor.create(INT,"1")}) ) | ID '--' -> ^(POSTFIX ^(VAR ID) ^(NUM {adaptor.create(INT,"-1")})) | '++' ID -> ^(PREFIX ^(VAR ID) ^(NUM {adaptor.create(INT,"1")})) | '--' ID -> ^(PREFIX ^(VAR ID) ^(NUM {adaptor.create(INT,"-1")})) | s=ID -> ^(VAR[$s,"ID"] ID) | s=INT -> ^(NUM[$s,"NUM"] INT) | arrayIndex | s=ID '(' exprList ')' -> ^(CALL[$s,"CALL"] ID exprList);exprList: (expr (',' expr)*)? -> ^(EXPRLIST expr*);arrayIndex : s=ID '[' expr ']' -> ^(INDEX[$s,"INDEX"] ID expr);//Begin LexerIF : 'if' ;WHILE : 'while' ;RETURN : 'return' ;BREAK : 'break' ;READ : 'read' ;WRITE : 'write' ;WRITELN : 'writeln' ;SCHAR : SQUOTE (.|'\\'('\\'|'n'|'t'|'\''|'\r')) SQUOTE;SQUOTE : '\'';TYPE : 'char'|'int';ID : CHAR(LCHAR|DIGIT)* ;fragment LCHAR : CHAR|'_';fragment CHAR : LC|UC;fragment LC : 'a'..'z' ;fragment UC : 'A'..'Z' ;INT : '0'|('1'..'9' DIGIT*);fragment DIGIT : '0'..'9';WS : ('\t'|' '|NEWLINE)+ {$channel=HIDDEN;};fragment NEWLINE : '\r'|'\n';COMMENT : '/*' (options {greedy=false;}:.)* '*/' {$channel=HIDDEN;}; LINECOMMENT : '//' ~('\r'|'\n')* NEWLINE {$channel=HIDDEN;};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -