All pastes #1649406 Raw Edit

Unnamed

public java v1 · immutable
#1649406 ·published 2009-10-30 16:34 UTC
rendered paste body
/* * This is based on: * Example grammar written 11/1/96 by Chuck McManisoptions {	MULTI=true;	VISITOR=true;	NODE_DEFAULT_VOID=true;}/* MULTI=true; *//* #LOOKAHEAD=1; */PARSER_BEGIN(PRM)public class PRM {	public static void main(String args[]) {		PRM parser = new PRM(System.in);		ASTProgram n = null;		try {			n = parser.program();			n.dump("");			System.out.println("Successfully parsed!\n");		} catch (Exception e) {			System.out.println("Error.");			System.out.println(e.getMessage());			e.printStackTrace();		}		/* Check variable declarations */		System.out.println("\nChecking variable declarations");		PRMDeclarationCheckVisitor dcv = 					   new	                                    PRMDeclarationCheckVisitor();		dcv.visit(n, null);	}}PARSER_END(PRM)SKIP : /* WHITESPACE */{ 	" "  |	"\t"  |	"\r"  |	"\n"  |     < "//" (~["\n","\r"])* ("\n" | "\r" | "\r\n") > }/* The next few TOKEN definitions are the binary operators of our 	language in decreasing order of precedence */TOKEN : /* The end of line token (a semicolon) */{	< EOL: ";" >}TOKEN : /* Block begin and block end markers */{	< BB: "{" >  |	< BE: "}" >}TOKEN : /* The left subscript and right subscript operators */{	< LSUB: "[" >  |	< RSUB: "]" >}TOKEN : /* Left and right parentheses */{	< LPAREN: "(" >  |	< RPAREN: ")" >}TOKEN : /* The list separator */{	< LISTSEP: "," >}TOKEN : /* Exponentiation operator */{	< EXP: "^" >}TOKEN : /* Multiplication and division */{	< MULTIPLY: "*" >  |	< DIVIDE: "/">  |	< MOD: "%" >}TOKEN : /* Addition and subtraction */{	< PLUS: "+" >  |	< MINUS: "-">}TOKEN : /* Comparison operators */{	< EQ: "=" >  |	< GT: ">" >  |	< GE: ">=" >  |	< LT: "<" >  |	< LE: "<=" >  |	< NE: "<>" | "!=" >}TOKEN : /* Logical operators (AND/OR) */{	< AND: "&" >  |	< OR: "|" >}TOKEN : /* The assignment operator */{	< GETS: ":=" >}TOKEN : /* Keywords */{	< DO: "do" >  |	< WHILE: "while" >  |	< IF: "if" >  | 	< ELSIF: "elsif" >  |	< ELSE: "else" >  |     < NUMBER_TYPE: "number" >  |	< STRING_TYPE: "string" >  |	< BOOLEAN_TYPE: "boolean" >  |     < RETURN: "return" >}TOKEN : /* Numeric Constants */{	< NUMBER: <FLOAT>		| <INTEGER> "r" <SPECINTEGER>	    | <FLOAT> ( ["e","E"] ([ "-","+"])? <INTEGER> )?	    	     	>  | 	< #FLOAT: <INTEGER> 	    | <INTEGER> ( "." <INTEGER> )?	    | "." <INTEGER>    	>  | 	< #INTEGER: ( <DIGIT> )+ >  | 	< #SPECINTEGER: (["a"-"t", "A"-"T", "0"-"9"])+  | 	< #DIGIT: ["0" - "9"] >}TOKEN : /* String constants */{	< STRING: "\"" ( <CHAR> )* "\"" >  |	< #CHAR: ["!", "#"-"~", " ", "\t"] >}TOKEN : /* Boolean constants */{	< BOOLEAN: "true" | "false" >}TOKEN : /* Identifiers (variables and function calls) */{	< ID: ( <LETTER> )+ ( <DIGIT> | <LETTER> )* >  | 	< #LETTER: ["a"-"z", "A"-"Z", "_"] > } /* That's it for TOKEN definitions, now we start with the grammar */ASTProgram program() #Program :{ }{	(( functionDefinition() )* <EOF> ) 	{ 	  return jjtThis;	}}void functionDefinition() :{ }{	(		type() identifier() <LPAREN> parameterList() <RPAREN> block()	) #Function}void parameterList() :{ }{	( 		( parameter() ( <LISTSEP>  parameter() )* )? 	) #ParameterList}void parameter() :{ }{	(		type() identifier()	) #Parameter}void block() :{ }{	(		<BB> expressionList() <BE>	) #Block}void expressionList() :{ }{	( statement() )* }void statement() :{ }{	declaration()  |     returnStatement()  |	whileLoop()  |	doLoop()  |	ifStatement()  |	simpleStatement()}void declaration() :{ }{	(		type() identifier() (<LISTSEP> identifier())* <EOL>	) #Declaration}void type() #MyType : {   Token t;}{	( <NUMBER_TYPE> | <STRING_TYPE> | <BOOLEAN_TYPE> )	{ 	  t = getToken(0);	  jjtThis.setName(t.image);	} }void identifier() #MyIdentifier :{	Token t;}{	t=<ID>	{		jjtThis.setName(t.image);	}}void returnStatement() :{ }{	(		<RETURN> logical() <EOL>	) #Return}void whileLoop() :{ }{	(		<WHILE> condition() block()	) #WhileLoop}void doLoop() :{ }{	(		<DO> block() <WHILE> condition()	) #DoLoop}void ifStatement() :{ }{	(		<IF> condition() block()			( <ELSIF> condition() block() )*			( <ELSE> block() )? 	) #IfStatement}void condition() :{ }{	(		<LPAREN> assignment() <RPAREN>	) #Condition}void simpleStatement() :{ }{	(		assignment() <EOL>	) #SimpleStatement}void assignment() :{ }{	// The first solution requires a lookahead, but spots invalid	// assignments during parsing.  The second solution doesn't require	// lookahead, but allows invalid assignments during parsing	// LOOKAHEAD( <ID> <GETS> ) <ID> <GETS> logical() | logical()   	(		logical() ( <GETS> logical() )*	) #Assign(>1)}void logical() :{ }{	(		comparison() (logicalOp() comparison())*	) #OperatorList(>1)}void logicalOp() #MyOperator :{   Token t;}{	( <AND> | <OR> )	{		t = getToken(0);		jjtThis.setName(t.image);	}}void comparison() :{ }{	(		sum() (comparisonOp() sum())*	) #OperatorList(>1)}void comparisonOp() #MyOperator :{   Token t;}{	( <GT> | <GE> | <LT> | <LE> | <EQ> | <NE> )	{		t = getToken(0);		jjtThis.setName(t.image);	}}void sum() :{ }{	(		term() (sumOp() term())*	) #OperatorList(>1)}void sumOp() #MyOperator :{   Token t;}{	( <PLUS> | <MINUS> )	{		t = getToken(0);		jjtThis.setName(t.image);	}}void term() :{ }{	(		exp() (termOp() exp())*	) #OperatorList(>1)}void termOp() #MyOperator :{   Token t;}{	( <MULTIPLY> | <DIVIDE> | <MOD> )	{		t = getToken(0);		jjtThis.setName(t.image);	}}void exp() :{ }{	// Notice: x^x^x^x = x^(x^(x^(x))) 	(		unary() ( expOp() exp() )?	) #OperatorList(>1)}void expOp() #MyOperator :{   Token t;}{	t=<EXP>	{		jjtThis.setName(t.image);	}}void unary() :{ }{	negation()  | 	element()}void negation() #MyUnaryOp :{   Token t;}{	t=<MINUS> element()	{		jjtThis.setName(t.image);	}}void element() :{ }{   constant()   |	idOrFunctionCall()   |	<LPAREN> assignment() <RPAREN>}void idOrFunctionCall() :{ }{	(		identifier() (argumentList())?	) #IDOrFunctionCall}void constant() : { }{	(		stringConstant() | booleanConstant() | numberConstant()	)}void stringConstant() #MyStringConstant :{   Token t;}{	t=<STRING>	{		jjtThis.setValue(t.image.substring(1,t.image.length()-1));	}}void booleanConstant() #MyBooleanConstant :{   Token t;}{	t=<BOOLEAN>	{		jjtThis.setValue(t.image.compareTo("true")==0);	}		}void numberConstant() #MyNumberConstant :{   Token t;}{	t=<NUMBER>	{  		String parsed[];		if ((t.image.indexOf("r") == 1)||(t.image.indexOf("r") == 2))		{		  	parsed = t.image.split("r");		    jjtThis.setValue(new Double(Integer.valueOf(parsed[1], (new Integer(parsed[0])).intValue())).doubleValue());		}		else		{			jjtThis.setValue(new Double(t.image).doubleValue());		}	}	}void variableOrFunctionCall() #MyIdentifier :{   Token t; }{		t=<ID> ( argumentList() )?	{		jjtThis.setName(t.image);	}}void argumentList() :{ }{	(		<LPAREN> assignment() ( <LISTSEP> assignment() )* <RPAREN>	) #ArgumentList}