[antlr-interest] Dont know how to allow Unary MINUS

Kjell Nilsson kjell at oops.se
Sat Oct 13 02:50:22 PDT 2001


Hi

I a complete newbee to parsers and I have played around
with antlr for 2 days now. Im trying to create a simple java
calculator as a start. I have looked through all the examples
and made some progress. But now Im trying to implement
unary minus and Im completly lost. In the doc Terence mentioned
that this could be handled by a syntactic predicate and I
have tried this in my TreeParser but had no luck.

Can someone give me a clue?

Here is my grammar.

Love to hear from somebody.

--kjell

{
import java.io.*;
}

class CalcParser extends Parser;
options {
	codeGenMakeSwitchThreshold = 3;
	codeGenBitsetTestThreshold = 4;
	buildAST=true;
	ASTLabelType = "antlr.CommonAST"; // change default of "AST"
}

calculate: assignExpr SEMI! ;
assignExpr: addExpr ;

// Doing the arithmetic
addExpr: multExpr (
     pm: (PLUS^ | MINUS^)?
     me: multExpr
     exception catch [ RecognitionException ex ]
     {
                     System.out.println("Caught error in addExpr");
                     reportError(ex.toString());
     } )* ;

multExpr: postfixExpr ( ( MULT^ | DIV^ | MOD^) postfixExpr )* ;

postfixExpr: absFunc | acosFunc | asinFunc | atanFunc | cosFunc | expFunc
              | invFunc | logFunc | sinFunc | sqrtFunc | tanFunc | powFunc
              | sqrFunc | cubeFunc | atom;
absFunc: ABS^ LPAREN! assignExpr RPAREN! ;
acosFunc: ACOS^ LPAREN! assignExpr RPAREN! ;
asinFunc: ASIN^ LPAREN! assignExpr RPAREN! ;
atanFunc: ATAN^ LPAREN! assignExpr RPAREN! ;
cosFunc: COS^ LPAREN! assignExpr RPAREN! ;
expFunc: EXP^ LPAREN! assignExpr RPAREN! ;
invFunc: INV^ LPAREN! assignExpr RPAREN! ;
logFunc: LOG^ LPAREN! assignExpr RPAREN! ;
sinFunc: SIN^ LPAREN! assignExpr RPAREN! ;
sqrtFunc: SQRT^ LPAREN! assignExpr RPAREN! ;
tanFunc: TAN^ LPAREN! assignExpr RPAREN! ;
sqrFunc: SQR^ LPAREN! assignExpr RPAREN! ;
cubeFunc: CUBE^ LPAREN! assignExpr RPAREN! ;
powFunc: POW^ LPAREN! assignExpr COMMA! assignExpr RPAREN! ;
maxFunc: MAX^ LPAREN! assignExpr COMMA! assignExpr RPAREN! ;
minFunc: MIN^ LPAREN! assignExpr COMMA! assignExpr RPAREN! ;

atom: unsignedNumber | ID | EEE | PII | LPAREN! assignExpr RPAREN! ;

unsignedNumber: unsignedInteger | unsignedReal ;

unsignedInteger: NUM_INT ;

unsignedReal: NUM_REAL ;

dummy: DOT  ;

//////////////////////////////////////////////////////////////////////////
/

class CalcLexer extends Lexer;

options {
   k=4;
   caseSensitive = true;
   caseSensitiveLiterals = true;
}

tokens {
     ABS = "abs" ;
     ACOS = "acos" ;
     ASIN = "asin" ;
     ATAN = "atan" ;
     COS = "cos" ;
     EXP = "exp" ;
     INV = "inv" ;
     LOG = "log" ;
     SIN = "sin" ;
     SQRT = "sqrt" ;
     TAN = "tan" ;
     SQR = "sqr" ;
     CUBE = "cube" ;
     POW = "pow";
     MAX = "max";
     MIN = "min";
     EEE = "e" ;
     PII = "pi" ;
}

WS: (' ' |'\t' | '\n' | '\r') { _ttype = Token.SKIP; } ;

LPAREN:	'(' ;
RPAREN:	')' ;
MINUS: 	'-' ;
PLUS:	'+' ;
MULT: 	'*' ;
DIV:	'/' ;
MOD:	'%' ;
COMMA: 	',' ;
SEMI:	';' ;

ID	options { testLiterals = true; }
	: ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')* ;

NUM_INT
	{boolean isDecimal=false;}
	:	"." {_ttype = DOT;}

		(('0'..'9')+ (EXPONENT)? { _ttype = NUM_REAL; })?
	|	(	'0' {isDecimal = true;} // special case for just '0'
		|	('1'..'9') ('0'..'9')*  {isDecimal=true;}		// non-zero decimal
		)
		// only check to see if it's a float if looks like decimal so far
		(	{ LA(2)!='.' && LA(3)!='.' && isDecimal}?
			(	'.' ('0'..'9')* (EXPONENT)?
			|	EXPONENT
			)
			{ _ttype = NUM_REAL; }
		)?
	;


// a couple protected methods to assist in matching floating point 
numbers
protected
EXPONENT
	:	('e') ('+'|'-')? ('0'..'9')+
	;

//////////////////////////////////////////////////////////////////////////
/

class CalcTreeWalker extends TreeParser;

expr returns [double r]
{
	double a,b;
	r=0;
}
	: 	#(PLUS a=expr b=expr)	{r = a+b;}

// Here comes my try to implement unary minus
         	|	( #(MINUS a=expr b=expr) )=> #( MINUS a=expr b=expr ) {r = 
a-b;} | #( MINUS a=expr ) {r = -a;}
//	
	|	#(MULT a=expr b=expr)	{r = a*b;}
	|	#(DIV a=expr b=expr)	{r = a/b;}
	|	#(MOD a=expr b=expr)	{r = a%b;}
	|	#(ABS a=expr)		{r = Math.abs(a);}
	|	#(ACOS a=expr)		{r = Math.acos(a);}
	|	#(ASIN a=expr)		{r = Math.asin(a);}
	|	#(ATAN a=expr)		{r = Math.atan(a);}
	|	#(COS a=expr)		{r = Math.cos(a);}
	|	#(EXP a=expr)		{r = Math.exp(a);}
	|	#(INV a=expr)		{r = 1/a;}
	|	#(LOG a=expr)		{r = Math.log(a);}
	|	#(SIN a=expr)		{r = Math.sin(a);}
	|	#(SQRT a=expr)		{r = Math.sqrt(a);}
	|	#(TAN a=expr)		{r = Math.tan(a);}
	|	#(SQR a=expr)		{r = a*a;}
	|	#(CUBE a=expr)		{r = a*a*a;}
	|	#(POW a=expr b=expr)	{r = Math.pow(a,b);}
	|	#(MAX a=expr b=expr)	{r = Math.max(a,b);}
	|	#(MIN a=expr b=expr)	{r = Math.min(a,b);}
	|	EEE			{r = Math.E;}
	|	PII			{r = Math.PI;}
	|	ni: NUM_INT		{r = (double)Double.parseDouble(ni.getText());}
	|	nr: NUM_REAL		{r = (double)Double.parseDouble(nr.getText());}
	;

 

Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/ 



More information about the antlr-interest mailing list