📄 eval.g
字号:
tree grammar Eval;options{ tokenVocab = CMinus; ASTLabelType = CommonTree;}@header{ import java.util.HashMap; import java.util.Vector; import java.util.Map; import java.io.*;}@members{ CommonTreeNodeStream stream = (CommonTreeNodeStream)input; public int read_line(){ BufferedReader mstdin = new BufferedReader(new InputStreamReader(System.in)); try{ System.out.print("input> "); String s=mstdin.readLine(); return Integer.parseInt(s); }catch (IOException e){ Main.print_err("IO Exception: "+e.getMessage()); return -1; } }}program : ^(PROGRAM ^(VARIABLES varDecl*) ^(FUNCTIONS .*) call) EOF ; varDecl : ^(VARDEF TYPE name=ID) {Main.symbols.declare_variable($name.text,$TYPE.text);} | ^(ARRDEF TYPE name=ID size=INT) {Main.symbols.declare_array($name.text,$TYPE.text,Integer.parseInt($size.text));} ; block@init{ Main.symbols.enter_block();}@after { Main.symbols.exit_block();} : ^(BLOCK ^(VARIABLES varDecl*) ^(STMTS stmt*)) ; stmt @init{ try{ if((! $call::can_run) || $whileStmt::breaked){ matchAny(input); return; } }catch(java.util.EmptyStackException ignore){}} : expr | ^(RETURN expr) {$call::return_val=$expr.value; $call::can_run=false;} | ^(READ name=ID) {Main.symbols.set_value($name.text,read_line());} | ^(WRITE expr) {System.out.print($expr.value);} | WRITELN {System.out.println("");} | BREAK {$whileStmt::breaked=true;} | ifStmt | whileStmt | block | NOP ; whileStmtscope{ Boolean breaked;}@after{ CommonTree stmtNode=(CommonTree)$whileStmt.start.getChild(1); CommonTree exprNode=(CommonTree)$whileStmt.start.getChild(0); int test; $whileStmt::breaked=false; while($whileStmt::breaked==false){ stream.push(stream.getNodeIndex(exprNode)); test=expr().value; stream.pop(); if (test==0) break; stream.push(stream.getNodeIndex(stmtNode)); stmt(); stream.pop(); } } : ^(WHILE . .) ;ifStmt@after{ CommonTree stmtNode; if ($v.value!=0){ stmtNode = (CommonTree)$ifStmt.start.getChild(1); }else{ stmtNode = (CommonTree)$ifStmt.start.getChild(2); } stream.push(stream.getNodeIndex(stmtNode)); stmt(); stream.pop();} : ^(IF ^(EXPR v=expr) . .) ; expr returns [int value, String id_name] : orStmt {$value = $orStmt.value;} | andStmt {$value = $andStmt.value;} | ^('==' a=expr b=expr) {$value = (a.value == b.value)? 1 : 0;} | ^('!=' a=expr b=expr) {$value = (a.value != b.value)? 1 : 0;} | ^('>' a=expr b=expr) {$value = (a.value > b.value)? 1 : 0;} | ^('<' a=expr b=expr) {$value = (a.value < b.value)? 1 : 0;} | ^('>=' a=expr b=expr) {$value = (a.value >= b.value)? 1 : 0;} | ^('<=' a=expr b=expr) {$value = (a.value <= b.value)? 1 : 0;} | ^('<>' a=expr b=expr) {$value = (a.value != b.value)? 1 : 0;} | ^('+' a=expr b=expr) {$value = a.value+b.value;} | ^('-' a=expr b=expr) {$value = a.value-b.value;} | ^('*' a=expr b=expr) {$value = a.value*b.value;} | ^('/' a=expr b=expr) {$value = a.value/b.value;} | ^(PREFIX ^(VAR ID) ^(NUM INT)) {$value = Main.symbols.get_value($ID.text)+Integer.parseInt($INT.text); Main.symbols.set_value($ID.text,$value); } | ^(POSTFIX ^(VAR ID) ^(NUM INT)) {$value = Main.symbols.get_value($ID.text); Main.symbols.set_value($ID.text,$value+Integer.parseInt($INT.text)); } | ^(NEGATE a=expr) {$value = -a.value;} | ^(NOT a=expr) {$value = (a.value!=0)? 0 : 1;} | ^(NUM INT) {$value = Integer.parseInt($INT.text);} | ^(VAR ID) {$value = Main.symbols.get_value($ID.text); $id_name=$ID.text;} | ^(INDEX ID i=expr) {$value = Main.symbols.get_value($ID.text,i.value);} | call {$value = $call.value;} | ^(ASSIGN ID a=expr) {Main.symbols.set_value($ID.text,a.value); $value=$a.value;} | ^(ASSIGN ^(INDEX ID i=expr) a=expr) {Main.symbols.set_value($ID.text,a.value,i.value); ; $value=$a.value;} ;//short circuiting or statementorStmt returns [int value]@after{ if ($a.value!=0){ $value=1; }else{ stream.push(stream.getNodeIndex((CommonTree)$orStmt.start.getChild(1))); $value=expr().value; stream.pop(); }} : ^(('or'|'||') a=expr .) ; //short circuiting and statementandStmt returns [int value]@after{ if ($a.value==0){ $value=0; }else{ stream.push(stream.getNodeIndex((CommonTree)$andStmt.start.getChild(1))); $value=expr().value; stream.pop(); }} : ^(('and'|'&&') a=expr .) ;call returns [int value]scope{ int return_val; Boolean can_run; Boolean in_paramater_defs;}@init { int p_i=0; Function fcn; Vector params=new Vector(); $call::can_run=true;} : ^(CALL ID {fcn=Main.symbols.get_function($ID.text);} ^(EXPRLIST (expr { if(((FunctionParam)fcn.params.get(p_i)).mode=="array"){ params.add(Main.symbols.get_variable($expr.id_name)); }else{ params.add($expr.value); } p_i++; } )*)) { Main.symbols.enter_frame(fcn,params); stream.push(stream.getNodeIndex(fcn.tree)); block(); stream.pop(); $value = $call::return_val; Main.symbols.exit_frame(); } ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -