public inbox for frysk@sourceware.org
 help / color / mirror / Atom feed
* antlr v3 parser file
@ 2007-10-25 14:02 Stan Cox
  0 siblings, 0 replies; only message in thread
From: Stan Cox @ 2007-10-25 14:02 UTC (permalink / raw)
  To: Frysk List

[-- Attachment #1: Type: text/plain, Size: 286 bytes --]

One evening a while back I took a stab to see if antlr v3 would work.
These .g files made it through antlr.   They didn't compile and I
didn't/haven't done much subsequent investigating to discover why.
The .g conversions where mostly done with emacs editor macros and a
sledghammer.  

[-- Attachment #2: CExpr.g --]
[-- Type: text/x-csrc, Size: 20071 bytes --]

// This file is part of the program FRYSK.

// Copyright 2005, 2007 Red Hat Inc.

// FRYSK is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 2 of the License.

// FRYSK is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with FRYSK; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.

// In addition, as a special exception, Red Hat, Inc. gives You the
// additional right to link the code of FRYSK with code not covered
// under the GNU General Public License ("Non-GPL Code") and to
// distribute linked combinations including the two, subject to the
// limitations in this paragraph. Non-GPL Code permitted under this
// exception must only link to the code of FRYSK through those well
// defined interfaces identified in the file named EXCEPTION found in
// the source code files (the "Approved Interfaces"). The files of
// Non-GPL Code may instantiate templates or use macros or inline
// functions from the Approved Interfaces without causing the
// resulting work to be covered by the GNU General Public
// License. Only Red Hat, Inc. may make changes or additions to the
// list of Approved Interfaces. You must obey the GNU General Public
// License in all respects for all of the FRYSK code and other code
// used in conjunction with FRYSK except the Non-GPL Code covered by
// this exception. If you modify this file, you may extend this
// exception to your version of the file, but you are not obligated to
// do so. If you do not wish to provide this exception without
// modification, you must delete this exception statement from your
// version and license this file solely under the GPL without
// exception.

grammar CExpr;
options {
output = AST;
}

@header {
// This file is part of the program FRYSK.
//
// Copyright 2005, 2007 Red Hat Inc.
//
// FRYSK is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 2 of the License.
//
// FRYSK is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with FRYSK; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
// 
// In addition, as a special exception, Red Hat, Inc. gives You the
// additional right to link the code of FRYSK with code not covered
// under the GNU General Public License ("Non-GPL Code") and to
// distribute linked combinations including the two, subject to the
// limitations in this paragraph. Non-GPL Code permitted under this
// exception must only link to the code of FRYSK through those well
// defined interfaces identified in the file named EXCEPTION found in
// the source code files (the "Approved Interfaces"). The files of
// Non-GPL Code may instantiate templates or use macros or inline
// functions from the Approved Interfaces without causing the
// resulting work to be covered by the GNU General Public
// License. Only Red Hat, Inc. may make changes or additions to the
// list of Approved Interfaces. You must obey the GNU General Public
// License in all respects for all of the FRYSK code and other code
// used in conjunction with FRYSK except the Non-GPL Code covered by
// this exception. If you modify this file, you may extend this
// exception to your version of the file, but you are not obligated to
// do so. If you do not wish to provide this exception without
// modification, you must delete this exception statement from your
// version and license this file solely under the GPL without
// exception.
    package frysk.expr;

    import java.util.ArrayList;
    import frysk.value.ArithmeticType;
    import frysk.value.SignedType;
    import frysk.value.UnsignedType;
    import frysk.value.FloatingPointType;
    import frysk.value.Value;
    import javax.naming.NameNotFoundException;
    import frysk.value.InvalidOperatorException;
    import frysk.value.OperationNotDefinedException;
    import inua.eio.ByteOrder;
    import lib.dwfl.BaseTypes;
}

@members {
/** 
  *	A member variable to keep track of TAB completions requests.
  *	If this is true the normal course of action is to simply
  *	bail out by throwing an exception
  */
    private boolean bTabPressed;
    private int assign_stmt_RHS_found;
    //private String sInputExpression;

    protected CppParser(TokenStream lexer, String sInput)
    {
        this(lexer);
        bTabPressed = false;
        //sInputExpression = sInput;
    }
}

// The start rule simply expects an expression list following by
// the end of text symbol (ETX \3).
//
// The TabException propagates all the way up, to the start rule,
// which then propagates it up to the calling program.

start throws TabException
    :   expressionList ETX
    ;

/**
  *  This rule looks for comma separated expressions.
  */
expressionList throws TabException
    :   expression (COMMA! expression)*
    ->  ^(EXPR_LIST expression)
        ;

expression! throws TabException
    :  assignment_expression
//        assign_expr1=assignment_expression 
//         {
//             // ## = #assign_expr1;
// 		    ^($assign_expr1.tree);
//         }
    ;

/**
  *  Assignment expressions of the form "expr1 = expr2 = expr3".
  *  Notice that the operator can be any assignment operator.
  */
assignment_operator
    :  ASSIGNEQUAL
    |  PLUSEQUAL
    |  MINUSEQUAL
    |  TIMESEQUAL
    |  DIVIDEEQUAL
    |  MODEQUAL
    |  SHIFTRIGHTEQUAL
    |  SHIFTLEFTEQUAL
    |  BITWISEANDEQUAL
    |  BITWISEXOREQUAL
    |  BITWISEOREQUAL
    ;

assignment_expression throws TabException 
    :  conditional_expression
       (
        (
          assignment_operator
        )
       assignment_expression
       )?
       {
        if ($a.tree != null)
            ^($o.tree $c.tree $a.tree);
        else
            ^($c.tree);
        }
    ;

/**
  *  Conditional expressions of the form
  *  (logical_expr)?expr:expr
  */
conditional_expression! throws TabException 
    :   log_or_expr=logical_or_expression
        (ques=QUESTIONMARK expr=assignment_expression colon=COLON 
            cond_expr=conditional_expression)?
        {
            if (ques != null)
                //## = ^([COND_EXPR, "ConditionalExpression"], #log_or_expr, #expr, #cond_expr);
                ^(COND_EXPR $log_or_expr.tree $expr.tree $cond_expr.tree;
            else
                //## = #log_or_expr;
                ^($log_or_expr.tree);
        }
    ;

logical_or_expression throws TabException 
    :	logical_and_expression (OR^ logical_and_expression)* 
    ;

logical_and_expression throws TabException 
    :	inclusive_or_expression (AND^ inclusive_or_expression)* 
    ;

inclusive_or_expression throws TabException 
    :	exclusive_or_expression (BITWISEOR^ exclusive_or_expression)*
    ;

exclusive_or_expression throws TabException 
    :   and_expression (BITWISEXOR^ and_expression)*
    ;

and_expression throws TabException 
    :   equality_expression (AMPERSAND^  equality_expression)*
    ;

equality_expression throws TabException 
    :   relational_expression ((NOTEQUAL^ | EQUAL^) relational_expression)*
    ;

relational_expression throws TabException 
    :   shift_expression
        (
	    (	LESSTHAN^
            |	GREATERTHAN^
            |	LESSTHANOREQUALTO^
            |	GREATERTHANOREQUALTO^
            )
            shift_expression
        )*
    ;

shift_expression throws TabException 
    :   additive_expression ((SHIFTLEFT^ | SHIFTRIGHT^) additive_expression)*
    ;

additive_expression throws TabException 
    :   multiplicative_expression
        (
            (PLUS^ | MINUS^) multiplicative_expression
        )*
    ;

multiplicative_expression throws TabException 
    :	unary_expression
        (
            (STAR^ | DIVIDE^ | MOD^) unary_expression
        )*
    ;
 
unary_expression throws TabException 
    :   PLUS^ unary_expression
    |   MINUS^ unary_expression
    |   PLUSPLUS^ postfix_expression
    |   MINUSMINUS^ postfix_expression
    |   TILDE^ unary_expression
    |   NOT^ unary_expression
    |   unary_expression_simple
    ;

unary_expression_simple throws TabException 
    :   AMPERSAND prim_expr=id_expression
        {
            //## = ^([ADDRESS_OF, "Address Of"], #prim_expr); 
            ^(ADDRESS_OF $prim_expr.tree);
        }
    |   STAR mem_expr=id_expression
        {
            //## = ^([MEMORY, "Memory"], #mem_expr); 
            ^(MEMORY $mem_expr.tree);
        }
    |   cast_expression
    | postfix_expression
    ;

primitiveType
    :   'boolean'
    |   'char'
    |   'byte'
    |   'short'
    |   'int'
    |   'long'
    |   'float'
    |   'double'
    ;

cast_expression! throws TabException 
    :  LPAREN type=primitiveType RPAREN expr=unary_expression
//       | LPAREN (expression) RPAREN unary_expression_simple
//       |  LPAREN (expression | primitiveType) RPAREN unary_expression_simple
        {
            //## = ^([CAST, "Cast"], #type, #expr);
            ^(CAST $type.tree $expr.tree);
        }
	;

postfix_expression throws TabException 
@init {String sTabText;}
    :	post_expr1=primary_expression 
        {
          if (bTabPressed)
            {
	      // ??? Use antlr expressions instead of tree surgery.
              if (#post_expr1.getFirstChild() != null)
		if (#post_expr1.getFirstChild().getNextSibling() != null)
                  sTabText = #post_expr1.getFirstChild().getNextSibling().getText();
		else
		  sTabText = #post_expr1.getFirstChild().getText();
              else 
                sTabText = #post_expr1.getText();

	      if (#post_expr1.getText().startsWith("Class Reference"))
		sTabText += ".";

              throw new TabException(#post_expr1, sTabText);
            }
        }
    ;

/**
  *	The TAB over here is not part of the C++ grammar.
  *	This enables auto-completion by allowing the user
  *	to press TAB whenever auto-completion is required
  */
primary_expression throws TabException 
    :   (TAB {bTabPressed = true;}
	    | primary_identifier)
    |   constant
    |   'this'
    |   LPAREN! expression RPAREN!
    ;

/**
  *  TabException is raised everytime the TAB is pressed.
  *  The parser thus bails out immediately and returns the
  *  parse tree constructed so far.
  */
/* ??? add (id_expression | (TAB {bTabPressed = true;})) */

primary_identifier! throws TabException 
@init {
    AST astPostExpr = null, astDotExpr = null;
} 
    :   (   prim_expr= id_expression
            {
                //astPostExpr = #prim_expr;
                ^($prim_expr.tree);
            }

            (

            : LPAREN (expr2=expressionList)? RPAREN
             { 
                 //astPostExpr = ^([FUNC_CALL, "FuncCall"], #astPostExpr, #expr2); 
                 ^(FUNC_CALL $astPostExpr.tree $expr2.tree);
            }
	        | LSQUARE arrExpr1=expression (COLON arrExpr2=expression)? RSQUARE
                // a[b][c] => (Array Reference a (Subscript b-lbound)
                //            (Subscript b-hbound) (Subscript c-lbound)...)
                {AST sub = null;
		 		 if (astPostExpr.getFirstChild() != null) {
                    // #sub = ^(#[SUBSCRIPT,"Subscript"], #arrExpr1);
                    ^(SUBSCRIPT $arrExpr1.tree);
                    astPostExpr.addChild(#sub);
                    // arr[n] is treated as arr[n:n]
                    if (#arrExpr2 != null)
		      	       #sub = ^(#[SUBSCRIPT,"Subscript"], #arrExpr2);
                    else
                       #sub =  ^(#[SUBSCRIPT,"Subscript"], #arrExpr1);
                    astPostExpr.addChild(#sub);
                    }
                 else {
		      	    #sub = ^(#[SUBSCRIPT,"Subscript"], #arrExpr1);
                    #astPostExpr = ^(#[REFERENCE,"Array Reference"], #astPostExpr, #sub);
                    if (#arrExpr2 != null)
		      	       #sub = ^(#[SUBSCRIPT,"Subscript"], #arrExpr2);
                    else
                       #sub =  ^(#[SUBSCRIPT,"Subscript"], #arrExpr1);
                    astPostExpr.addChild(#sub);
                 }
                }

// 	        | AT at_expr=expression
//                 // a@N => (Array Reference a (Subscript N) (Subscript N))
//                 {AST sub = null;
// 		      	 #sub = ^(#[SUBSCRIPT,"Subscript"], #[DECIMALINT,"0"]);
//                  #astPostExpr = ^(#[REFERENCE,"Array Reference"], #astPostExpr, #sub);
//                  // allow for 0 origin lower bound
//                  #at_expr.setText(new String(Integer.toString(Integer.parseInt(#at_expr.getText()) - 1)));
// 		      	 #sub = ^(#[SUBSCRIPT,"Subscript"], #at_expr);
//                  astPostExpr.addChild(#sub);
//                 }

            |   DOT!
                (   tb=TAB
                    {
                        bTabPressed = true;
                        astDotExpr = #tb; 
                    }
                |   id_expr1=id_expression
                    { astDotExpr = #id_expr1;}
                )
                // a.b.c => (Class Reference a b c))
                {if (astPostExpr.getFirstChild() != null) {
		            if (#astDotExpr.getText().endsWith("\t") == false)
                       astPostExpr.addChild(#astDotExpr); 
		            }
                    else {
		     	       if (#astDotExpr.getText().endsWith("\t") == false)
                           //#astPostExpr = ^(#[REFERENCE,"Class Reference"], #astPostExpr, #astDotExpr);
                           ^(REFERENCE $astPostExpr.tree $astDotExpr.tree);
                       else
                           //#astPostExpr = ^(#[REFERENCE,"Class Reference"], #astPostExpr);
                           ^(REFERENCE $astPostExpr.tree);
		   			}
                }
            |   POINTERTO id_expr2=id_expression
                { 
                    //astPostExpr = ^(POINTERTO, #astPostExpr, #id_expr2); 
                    ^(POINTERTO $astPostExpr.tree $id_expr2.tree)
                }
            |   PLUSPLUS
                {
                    //astPostExpr = ^(PLUSPLUS, #astPostExpr); 
                    ^(CPLUSPLUS $astPostExpr.tree)
                }
            |   MINUSMINUS
                {
                    //astPostExpr = ^(MINUSMINUS, #astPostExpr); 
                    ^(MINUSMINUS $astPostExpr.tree)
                }
            )*
        )
        { 
            //## = #astPostExpr; 
            ^($astPostExpr.tree)
        }
    ;

constant
    :   OCTALINT
    |   DECIMALINT
    |   HEXADECIMALINT
    |   CharLiteral
    |   (StringLiteral)+
    |   FLOAT
    |   DOUBLE
    |   'true'
    |   'false'
    ;

id_expression
    :   IDENT
    ;

tid_expression
    :   TAB_IDENT 
    ;

/*----------------------------------------------------------------------------
   * The Lexer
   *----------------------------------------------------------------------------*/
// @lexer::members {
//     OPERATOR = 'operator';
// }

/* Operators: */

ASSIGNEQUAL     : '=' ;
COLON           : ':' ;
COMMA           : ',' ;
QUESTIONMARK    : '?' ;
SEMICOLON       : ';' ;
POINTERTO       : '->';


ETX	    : '\3'  ;
LPAREN    : '('   ;
RPAREN    : ')'   ;

LSQUARE   : '[' ;
RSQUARE   : ']' ;

LCURLY    : '{' ;
RCURLY    : '}' ;

AT : '@' ;

EQUAL			: '==' ;
NOTEQUAL		: '!=' ;
LESSTHANOREQUALTO     : '<=' ;
LESSTHAN              : '<' ;
GREATERTHANOREQUALTO  : '>=' ;
GREATERTHAN           : '>' ;

DIVIDE          : '/' ;
DIVIDEEQUAL     : '/=' ;
PLUS            : '+' ;
PLUSEQUAL       : '+=' ;
PLUSPLUS        : '++' ;
MINUS           : '-' ;
MINUSEQUAL      : '-=' ;
MINUSMINUS      : '--' ;
STAR            : '*' ;
TIMESEQUAL      : '*=' ;
MOD             : '%' ;
MODEQUAL        : '%=' ;
SHIFTRIGHT      : '>>' ;
SHIFTRIGHTEQUAL : '>>=' ;
SHIFTLEFT       : '<<' ;
SHIFTLEFTEQUAL  : '<<=' ;

AND		  : '&&' ;
NOT		  : '!' ;
OR		  : '||' ;

AMPERSAND       : '&' ;
BITWISEANDEQUAL : '&=' ;
TILDE           : '~' ;
BITWISEOR       : '|'	  ;
BITWISEOREQUAL  : '|='  ;
BITWISEXOR      : '^'	  ;
BITWISEXOREQUAL : '^='  ;

fragment
ELLIPSIS  : '...' ;

fragment
DOT       : '.' ;

SCOPE           : '::'  ;

fragment
IDENT
    :   ('$')*('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
    
;
/**
  *  A <TAB> token is returned not only on regular tabs
  *  but also when a TAB is hit after an incomplete variable
  */
fragment
TAB
    :   (IDENT)?'\t'
    ;

TAB_IDENT 
    :   ((IDENT)'\t')=>TAB {$type = TAB;}
    |   ('\t')=>TAB {$type = TAB;}
    |   IDENT {$type = IDENT;}
    ;

fragment
NL
    :   '\r' ('\n')?  // DOS/Windows
    |   '\n'    // Unix
        { /* newline(); */ }
    ;

WS
    :	(   ' '
        |   '\f'
        |   NL    
        |   '\\'
            (   '\r' ('\n')?
            |   '\n'
            )
        )
        { $channel=HIDDEN; }
    ; 

CharLiteral
    :	'\'' (Escape | ~( '\'' )) '\''
    ;

StringLiteral
    :	'\"'
        (   Escape
        |	(	'\\\r\n'   // MS 
            |	'\\\r'     // MAC
            |	'\\\n'     // Unix
            )
        |	~('\"' | '\r' | '\n' | '\\')
        )*
        '\"'
    ;

fragment
Escape  
    :	'\\'
        (
            'a'
        |   'b'
        |   'f'
        |   'n'
        |   'r'
        |   't'
        |   'v'
        |   '\"'
        |   '\''
        |   '\\'
        |   '?'
        |   ('0'..'3') 
            (
            : Digit (Digit)? )?
        |   ('4'..'7') (Digit)?
        |   'x' (Digit | 'a'..'f' | 'A'..'F')+
        )
    ;

/* Numeric Constants: */

fragment
Digit
    :	'0'..'9'
    ;

fragment
Decimal
    :	('0'..'9')+
    ;

fragment
LongSuffix
    :	'l'
    |   'L'
    ;

fragment
UnsignedSuffix
    :	'u'
    |	'U'
    ;

fragment
FloatSuffix
    :	'f'
    |	'F'
    ;

fragment
Exponent
    :   ('e' | 'E') ('+' | '-')? (Digit)+
    ;

// fragment
// Vocabulary
//     :	'\3'..'\377'
//     ;

// a numeric literal
NUM
	@init {Token t=null;}
	:	'.' {$type = DOT;}
		(	'.' '.' {$type = ELLIPSIS;}
		|	(	('0'..'9')+ (EXPONENT)? (f1=FLOAT_SUFFIX {t=f1;})?
				{
				if (t != null && t.getText().toUpperCase().indexOf('F')>=0) {
					$type = FLOAT;
				}
				else {
					$type = DOUBLE; // assume double
				}
				}
			)?
		)

	|	(	'0' {$type = DECIMALINT;} // special case for just '0'
			(	('x'|'X')
				(											// hex
					// the 'e'|'E' and float suffix stuff look
					// like hex digits, hence the (...)+ doesn't
					// know when to stop: ambig.  ANTLR resolves
					// it correctly by matching immediately.  It
					// is therefor ok to hush warning.
				:	HEX_DIGIT
				)+					{$type = HEXADECIMALINT;}

			|	//float or double with leading zero
				(('0'..'9')+ ('.'|EXPONENT|FLOAT_SUFFIX)) => ('0'..'9')+

			|	('0'..'7')+			{$type = OCTALINT;}
			)?
		|	('1'..'9') ('0'..'9')*  {$type = DECIMALINT;}
		)
		(	('l'|'L') { $type = DECIMALINT; }

		// only check to see if it's a float if looks like decimal so far
		|	{$type == DECIMALINT}?
			(	'.' ('0'..'9')* (EXPONENT)? (f2=FLOAT_SUFFIX {t=f2;})?
			|	EXPONENT (f3=FLOAT_SUFFIX {t=f3;})?
			|	f4=FLOAT_SUFFIX {t=f4;}
			)
			{
			if (t != null && t.getText().toUpperCase() .indexOf('F') >= 0) {
				$type = FLOAT;
			}
			else {
				$type = DOUBLE; // assume double
			}
			}
		)?
	;

fragment FLOAT : ;
fragment DOUBLE : ;
fragment OCTALINT : ;
fragment DECIMALINT : ;
fragment HEXADECIMALINT : ;

// Fragment methods to assist in matching floating point numbers
fragment
HEX_DIGIT
	:	('0'..'9'|'A'..'F'|'a'..'f')
	;
fragment
EXPONENT
	:	('e'|'E') ('+'|'-')? ('0'..'9')+
	;


fragment
FLOAT_SUFFIX
	:	'f'|'F'|'d'|'D'
	;

[-- Attachment #3: CExprEvaluator.g --]
[-- Type: text/x-csrc, Size: 9704 bytes --]

// This file is part of the program FRYSK.

// Copyright 2005, 2007 Red Hat Inc.

// FRYSK is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 2 of the License.

// FRYSK is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with FRYSK; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.

// In addition, as a special exception, Red Hat, Inc. gives You the
// additional right to link the code of FRYSK with code not covered
// under the GNU General Public License ("Non-GPL Code") and to
// distribute linked combinations including the two, subject to the
// limitations in this paragraph. Non-GPL Code permitted under this
// exception must only link to the code of FRYSK through those well
// defined interfaces identified in the file named EXCEPTION found in
// the source code files (the "Approved Interfaces"). The files of
// Non-GPL Code may instantiate templates or use macros or inline
// functions from the Approved Interfaces without causing the
// resulting work to be covered by the GNU General Public
// License. Only Red Hat, Inc. may make changes or additions to the
// list of Approved Interfaces. You must obey the GNU General Public
// License in all respects for all of the FRYSK code and other code
// used in conjunction with FRYSK except the Non-GPL Code covered by
// this exception. If you modify this file, you may extend this
// exception to your version of the file, but you are not obligated to
// do so. If you do not wish to provide this exception without
// modification, you must delete this exception statement from your
// version and license this file solely under the GPL without
// exception.

tree grammar CExprEvaluator;


options {
    tokenVocab=CExpr;
    ASTLabelType=CommonTree;
}

primitiveType
    :   'boolean'
    |   'char'
    |   'byte'
    |   'short'
    |   'int'
    |   'long'
    |   'float'
    |   'double'
    ;

identifier returns [String idSpelling=null]
    :   ident=IDENT  {idSpelling=ident.getText();} ;

references returns [ArrayList el = null;]
	throws  InvalidOperatorException, 
		OperationNotDefinedException,
		NameNotFoundException
    @init {   refList = new ArrayList();}
    :   (subscript_or_member)* {el=refList;};

subscript_or_member returns [String id=null;] 
	throws  InvalidOperatorException, 
		OperationNotDefinedException,
		NameNotFoundException
    @init {   Value s; }
    :   ^(SUBSCRIPT s=expr) {refList.add(new Integer((int)s.asLong()).toString());}
    |    ident=identifier {refList.add(ident);};

expr returns [Value returnVar=null] 
	throws  InvalidOperatorException, 
		OperationNotDefinedException,
		NameNotFoundException
@init { Value v1, v2, log_expr, zero=intType.createValue(0); String s1; ArrayList el;}
    :   ( ^(PLUS expr expr) ) => ^(PLUS v1=expr v2=expr)
        { returnVar = v1.getType().add(v1, v2);  }
    |   ( ^(MINUS expr expr) )=> ^(MINUS v1=expr v2=expr) 
        { returnVar = v1.getType().subtract(v1, v2);  }
    |   ( ^(MINUS expr ) )=> ^(MINUS '0' expr)
    |   ( ^(STAR expr expr) )=> ^(STAR  v1=expr v2=expr)  
	{ returnVar = v1.getType().multiply(v1, v2); }
    |   ^(MEMORY s1=identifier )
	{ returnVar = longType.createValue(0);
          returnVar = (Value)cppSymTabRef.getMemory(s1); }
    |   ^(DIVIDE  v1=expr v2=expr)  { returnVar = v1.getType().divide(v1, v2); }
    |   ^(MOD  v1=expr v2=expr)  {	returnVar = v1.getType().mod(v1, v2);  }
    |   ^(SHIFTLEFT  v1=expr v2=expr)  {	
            returnVar = v1.getType().shiftLeft(v1, v2);  }
    |   ^(SHIFTRIGHT  v1=expr v2=expr)  {	
            returnVar = v1.getType().shiftRight(v1, v2);  }
    |   ^(LESSTHAN  v1=expr v2=expr)  { returnVar = v1.getType().lessThan(v1, v2);  }

    |   ^(GREATERTHAN  v1=expr v2=expr)  { returnVar = v1.getType().greaterThan(v1, v2);  }

    |   ^(LESSTHANOREQUALTO  v1=expr v2=expr)  { returnVar = v1.getType().lessThanOrEqualTo(v1, v2);  }

    |   ^(GREATERTHANOREQUALTO  v1=expr v2=expr)  { returnVar = v1.getType().greaterThanOrEqualTo(v1, v2);  }

    |   ^(NOTEQUAL  v1=expr v2=expr)  { returnVar = v1.getType().notEqual(v1, v2);  }

    |   ^(EQUAL  v1=expr v2=expr)  { returnVar = v1.getType().equal(v1, v2);  }
    |   ( ^(AMPERSAND expr expr) )=>^(AMPERSAND  v1=expr v2=expr)  
	{ returnVar = v1.getType().bitWiseAnd(v1, v2);  }
    |   ^(ADDRESS_OF s1=identifier )
	{ returnVar = longType.createValue(0);
          returnVar = (Value)cppSymTabRef.getAddress(s1); }
    |   ^(BITWISEXOR  v1=expr v2=expr)  { returnVar = v1.getType().bitWiseXor(v1, v2);  }
    |   ^(BITWISEOR  v1=expr v2=expr)  { returnVar = v1.getType().bitWiseOr(v1, v2);  }
    |   ^(AND  v1=expr v2=expr)  { returnVar = v1.getType().logicalAnd(v1, v2);  }
    |   ^(OR  v1=expr v2=expr)  { returnVar = v1.getType().logicalOr(v1, v2);  }
    |   ^(NOT  v1=expr)  { returnVar = v1.getType().logicalNegation(v1);  }
    |   ^(TILDE v1=expr)  { returnVar = v1.getType().bitWiseComplement(v1);  }
    |   ^(COND_EXPR  log_expr=expr v1=expr v2=expr)  { 
            returnVar = ((log_expr.getType().getLogicalValue(log_expr)) ? v1 : v2);  
        }
    |   o=OCTALINT  {
    	    char c = o.getText().charAt(o.getText().length() - 1);
    	    int l = o.getText().length();
    	    if (c == 'u' || c == 'U' || c == 'l' || c == 'L')
    	       l -= 1;
            returnVar =
                longType.createValue(Long.parseLong(o.getText().substring(1, l), 8));
        }
    |   i=DECIMALINT  {
    	    char c = i.getText().charAt(i.getText().length() - 1);
    	    int l = i.getText().length();
    	    if (c == 'u' || c == 'U' || c == 'l' || c == 'L')
    	       l -= 1;
            returnVar =
                longType.createValue(Long.parseLong(i.getText().substring(0, l)));
        }
    |   h=HEXADECIMALINT  {
    	    char c = h.getText().charAt(h.getText().length() - 1);
    	    int l = h.getText().length();
    	    if (c == 'u' || c == 'U' || c == 'l' || c == 'L')
    	       l -= 1;
            returnVar =
                longType.createValue(Long.parseLong(h.getText().substring(2, l), 16));
        }
    |   f=FLOAT  {
    	    char c = f.getText().charAt(f.getText().length() - 1);
    	    int l = f.getText().length();
    	    if (c == 'f' || c == 'F' || c == 'l' || c == 'L')
    	       l -= 1;
            returnVar =
                floatType.createValue(Float.parseFloat(f.getText().substring(0, l)));
        }
    |   d=DOUBLE  {
    	    char c = d.getText().charAt(d.getText().length() - 1);
    	    int l = d.getText().length();
    	    if (c == 'f' || c == 'F' || c == 'l' || c == 'L')
    	       l -= 1;
            returnVar =
                doubleType.createValue(Double.parseDouble(d.getText().substring(0, l)));
        }
    |   ^(ASSIGNEQUAL v1=expr v2=expr)  {
            v1.assign(v2);
            returnVar = v1;
        }
    |   ^(TIMESEQUAL v1=expr v2=expr)  {
            v1.getType().timesEqual(v1, v2);
            returnVar = v1;
        }
    |   ^(DIVIDEEQUAL v1=expr v2=expr)  {
            v1.getType().divideEqual(v1, v2);
            returnVar = v1;
        }
    |   ^(MINUSEQUAL v1=expr v2=expr)  {
            v1.getType().minusEqual(v1, v2);
            returnVar = v1;
        }
    |   ^(PLUSEQUAL v1=expr v2=expr)  {
            v1.getType().plusEqual(v1, v2);
            returnVar = v1;
        }
    |   ^(MODEQUAL v1=expr v2=expr)  {
            v1.getType().modEqual(v1, v2);
            returnVar = v1;
        }
    |   ^(SHIFTLEFTEQUAL v1=expr v2=expr)  {
            v1.getType().shiftLeftEqual(v1, v2);
            returnVar = v1;
        }
    |   ^(SHIFTRIGHTEQUAL v1=expr v2=expr)  {
            v1.getType().shiftRightEqual(v1, v2);
            returnVar = v1;
        }
    |   ^(BITWISEANDEQUAL v1=expr v2=expr)  {
            v1.getType().bitWiseAndEqual(v1, v2);
            returnVar = v1;
        }
    |   ^(BITWISEXOREQUAL v1=expr v2=expr)  {
            v1.getType().bitWiseXorEqual(v1, v2);
            returnVar = v1;
        }
    |   ^(BITWISEOREQUAL v1=expr v2=expr)  {
            v1.getType().bitWiseOrEqual(v1, v2);
            returnVar = v1;
        }
    |   ^(CAST pt=primitiveType v2=expr) { 
	    if(pt.getText().compareTo("long") == 0) {
	      returnVar = longType.createValue(0);
              returnVar.assign(v2);
	      }
	    else if(pt.getText().compareTo("int") == 0) {
	      returnVar = intType.createValue(0);
              returnVar.assign(v2);
	      }
	    else if(pt.getText().compareTo("short") == 0) {
	      returnVar = shortType.createValue(0);
              returnVar.assign(v2);
	      }
	    else if(pt.getText().compareTo("double") == 0) {
	      returnVar = doubleType.createValue(0.0);
              returnVar.assign(v2);
	      }
	    else if(pt.getText().compareTo("float") == 0) {
	      returnVar = floatType.createValue(0.0);
              returnVar.assign(v2);
	      }
	    else returnVar = v2;
        }
    |   ^(EXPR_LIST v1=expr)  { returnVar = v1; }
    |   ^(FUNC_CALL v1=expr v2=expr)  { returnVar = v1; }
    |   ^(REFERENCE el=references) {
          returnVar = (Value)cppSymTabRef.get(el);
          }
    |   ident=IDENT  {
            returnVar = ((Value)cppSymTabRef.get(ident.getText()));
        }
    |   tident=TAB_IDENT  {
            returnVar = ((Value)cppSymTabRef.get(tident.getText()));
        }
    ;

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2007-10-25 14:02 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-10-25 14:02 antlr v3 parser file Stan Cox

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).