⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compiler.g

📁 c--词法分析
💻 G
字号:
tree grammar Compiler;options{	tokenVocab = CMinus;	ASTLabelType = CommonTree;	output = template;}@header{	import java.util.HashMap;	import java.util.Vector;	import java.util.Map;    	import java.util.List;	import java.io.*;	import org.antlr.stringtemplate.*;	import org.antlr.stringtemplate.language.*;}@members{	CommonTreeNodeStream stream = (CommonTreeNodeStream)input;	Boolean global=true;		int next_power_of_two(int v){		//FIXME Currently arrays are set to 2^16, and this function isn't used		double t=(double)v;		double nv=Math.log(t)/Math.log(2);		int res=(int)Math.ceil(nv);		return (int)Math.pow(2,res);	}	StringTemplateGroup mtemplates;}program	@init{	Main.symbols.reset_globals();}:	 ^(PROGRAM ^(VARIABLES (vars+=varDecl)*) ^(FUNCTIONS (funs+=funDecl)*) .) EOF -> wrapper(globals={$vars}, functions={$funs})	;funDecl@init{	global=false;	Main.symbols.enter_frame();}@after{	global=true;	Main.symbols.exit_frame();}: ^(FUNCTION TYPE name=ID ^(PARAMATERS (params+=paramDecl)*) b+=block) -> function(name={$name}, params={$params}, content={$b});paramDecl :	^(VARPAR TYPE ID) {Main.symbols.declare_variable($ID.text,$TYPE.text, true);} 	-> param(name={Main.symbols.get_variable($ID.text).num})	        | ^(ARRPAR TYPE name=ID) 	{Main.symbols.declare_array($name.text,$TYPE.text,65536);}		        										-> array_param(name={Main.symbols.get_variable($ID.text).num});varDecl	:	^(VARDEF TYPE name=ID) {Main.symbols.declare_variable($name.text,$TYPE.text,false);}	-> {global}? declare_global(r={Main.symbols.get_variable($ID.text).num})													-> declare(r={Main.symbols.get_variable($ID.text).num})	    |	^(ARRDEF TYPE name=ID size=INT) {Main.symbols.declare_array($name.text,$TYPE.text,65536);} //next_power_of_two(Integer.parseInt($size.text))	    												-> {global}? declare_global_array(ref={Main.symbols.get_variable($name.text).num}, size={Main.symbols.get_variable($name.text).length})													-> declare_array(ref={Main.symbols.get_variable($name.text).num}, size={Main.symbols.get_variable($name.text).length})	;	block@init{	Main.symbols.enter_block();}@after {	Main.symbols.exit_block();}	:	^(BLOCK ^(VARIABLES (vars+=varDecl)*) ^(STMTS (stmts+=stmt)*)) -> block(vars={$vars}, stmts={$stmts})	;	stmt	:	a=expr			-> item(st={$a.st},s={"Start Expression"},e={"End Expression"})		| ^(RETURN expr)	-> return(expr={$expr.st}, ref = {$expr.ref})		| ^(READ ID)		-> read(ret={Main.symbols.get_variable($ID.text).num}, tmp1 = {Main.symbols.next_var()}, tmp2 = {Main.symbols.next_var()}, tmp3 = {Main.symbols.next_var()}, tmp4 = {Main.symbols.next_var()}, tmp5 = {Main.symbols.next_var()})		| ^(WRITE expr)		-> write(expr= {$expr.st}, ref = {$expr.ref}, v1 = {Main.symbols.next_var()}, v2 = {Main.symbols.next_var()})		| WRITELN		-> writeln(v = {Main.symbols.next_var()})		| BREAK			-> break(lab={$whileStmt::breaked})		| ifStmt		-> item(st={$ifStmt.st},s={"Start If Statement"},e={"End If Statement"})		| whileStmt		-> item(st={$whileStmt.st},s={"Start While Statement"},e={"End While Statement"})		| block			-> item(st={$block.st},s={"Start Block"},e={"End Block"})		| NOP			->	;	whileStmtscope{	int breaked;}@init{	$whileStmt::breaked=Main.symbols.next_label();} : ^(WHILE expr stmt)		-> while(expr={$expr.st}, ref={$expr.ref}, stmt={$stmt.st}, tmp1={Main.symbols.next_var()},start={Main.symbols.next_label()},block_begin={Main.symbols.next_label()},end={$whileStmt::breaked})	;ifStmt  :	 ^(IF ^(EXPR expr) t=stmt f=stmt)	-> if(expr={$expr.st},ref={$expr.ref},true={$t.st},false={$f.st},tmp1={Main.symbols.next_var()},lab1={Main.symbols.next_label()},lab2={Main.symbols.next_label()},lab3={Main.symbols.next_label()})	;		expr returns [int ref]@init {	$ref=Main.symbols.next_var();}	:		^(('or'|'||') a=expr b=expr)		-> or(ret={$ref},expr1={$a.st},expr2={$b.st},ref1={$a.ref},ref2={$b.ref},tmp1={Main.symbols.next_var()},tmp2={Main.symbols.next_var()},lab1={Main.symbols.next_label()},lab2={Main.symbols.next_label()},lab3={Main.symbols.next_label()},lab4={Main.symbols.next_label()})		| ^(('and'|'&&') a=expr b=expr)		-> and(ret={$ref},expr1={$a.st},expr2={$b.st},ref1={$a.ref},ref2={$b.ref},tmp1={Main.symbols.next_var()},tmp2={Main.symbols.next_var()},lab1={Main.symbols.next_label()},lab2={Main.symbols.next_label()},lab3={Main.symbols.next_label()},lab4={Main.symbols.next_label()})		| ^('==' a=expr b=expr)			-> comparison(type={"eq"}, expr1={$a.st}, expr2={$b.st},ret={$ref}, ref1={$a.ref}, ref2={$b.ref})		| ^(('!='|'<>') a=expr b=expr)		-> comparison(type={"ne"}, expr1={$a.st}, expr2={$b.st},ret={$ref}, ref1={$a.ref}, ref2={$b.ref})		| ^('>' a=expr b=expr)			-> comparison(type={"gt"}, expr1={$a.st}, expr2={$b.st},ret={$ref}, ref1={$a.ref}, ref2={$b.ref})		| ^('<' a=expr b=expr)			-> comparison(type={"lt"}, expr1={$a.st}, expr2={$b.st},ret={$ref}, ref1={$a.ref}, ref2={$b.ref})		| ^('>=' a=expr b=expr)			-> comparison(type={"ge"}, expr1={$a.st}, expr2={$b.st},ret={$ref}, ref1={$a.ref}, ref2={$b.ref})		| ^('<=' a=expr b=expr)			-> comparison(type={"le"}, expr1={$a.st}, expr2={$b.st},ret={$ref}, ref1={$a.ref}, ref2={$b.ref})		| ^('+' a=expr b=expr) 			-> add(ea={$a.st},eb={$b.st},r={$ref}, v1={$a.ref}, v2={$b.ref})		| ^('-' a=expr b=expr) 			-> subtract(ea={$a.st},eb={$b.st},r={$ref}, v1={$a.ref}, v2={$b.ref})		| ^('*' a=expr b=expr) 			-> multiply(ea={$a.st},eb={$b.st},r={$ref}, v1={$a.ref}, v2={$b.ref})		| ^('/' a=expr b=expr) 			-> divide(ea={$a.st},eb={$b.st},r={$ref}, v1={$a.ref}, v2={$b.ref})		| ^(NEGATE a=expr)			-> negate(expr={$a.st}, r={$ref}, val={$a.ref})		| ^(NOT a=expr)				-> not(expr={$a.st}, ret={$ref}, ref={$a.ref})		| ^(NUM INT)				-> create(r={$ref}, val={$INT})		| ^(VAR ID)				{if(Main.symbols.get_variable($ID.text).read_only || Main.symbols.get_variable($ID.text).mode=="array") $ref=Main.symbols.get_variable($ID.text).num;} -> {(! Main.symbols.get_variable($ID.text).read_only) && Main.symbols.get_variable($ID.text).mode=="scalar"}? access(target={$ref},source={Main.symbols.get_variable($ID.text).num})							->		//| ^(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)); }		| ^(INDEX name=ID i=expr)		-> access_array(ret={$ref},name={Main.symbols.get_variable($name.text).num}, index_expr={$i.st}, index_ref={i.ref},tmp1={Main.symbols.next_var()},size={Main.symbols.get_variable($name.text).length})		| call[$ref]				->{$call.st}		| ^(ASSIGN name=ID a=expr)		-> var_assign(ret={$ref}, expr={$a.st}, var={Main.symbols.get_variable($name.text).num}, ref={$a.ref})		| ^(ASSIGN ^(INDEX name=ID i=expr) a=expr)	-> array_assign(ret={$ref}, val_expr={$a.st},val_ref={$a.ref}, index_expr={$i.st}, index_ref={i.ref}, var={Main.symbols.get_variable($name.text).num}, size={Main.symbols.get_variable($name.text).values.length},tmp1={Main.symbols.next_var()});call[int ref] @init {	int p_i=0;	Function fcn;	ArrayList prefs=new ArrayList();	ArrayList exprs=new ArrayList();} 	:		^(CALL ID {fcn=Main.symbols.get_function($ID.text);} ^(EXPRLIST (p=expr 	{			StringTemplate code;		if(((FunctionParam)fcn.params.get(p_i)).mode=="array"){			code=mtemplates.getInstanceOf("array_var");		}else{			code=mtemplates.getInstanceOf("int_var");		}            	code.setAttribute("num", $p.ref);		prefs.add(code);		exprs.add($p.st);		p_i++;	})*))	-> call(ret={$ref}, name={$ID.text}, param_expr={exprs}, params={prefs})	;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -