//
// An experimental expression grammer by
// Ian Kaplan
//


options {
	language="Cpp";
}

class MyExprParser extends Parser;

options {
        k = 2;
        exportVocab=MyExpr;
	buildAST = true;
        // defaultErrorHandler = true;  // Don't generate parser error handlers
}


exprlist
  : ( assignment_statement )* EOF!
  ;

assignment_statement
  : assignment SEMICOLON!
  ;

assignment
  : (IDENT ASSIGN^ )? expr
  ;

primary_expr
  : IDENT 
  | constant 
  | (LPAREN! expr RPAREN! ) 
  ;

boolneg_expr
  : ( "not" )* primary_expr
  ;

sign_expr
  : (MINUS)? boolneg_expr
  ;

mul_expr
  : sign_expr (( TIMES^ | DIVIDE^ | MOD^ ) sign_expr)*
  ;

add_expr
  : mul_expr (( PLUS^ | MINUS^ ) mul_expr)*
  ;

shift_expr
  : add_expr ( shiftop add_expr )*
  ;

rel_expr
  : shift_expr (relop shift_expr)*
  ;

eq_expr
  : rel_expr (eqop rel_expr)*
  ;

lmul_expr
  : eq_expr ( "and" eq_expr )*
  ;

expr
  : lmul_expr ("or" lmul_expr)*
  ;


constant
  : (ICON | CHCON)
  ;



relop
  : ( LTHAN | GTHAN | GEQ | LEQ )
  ;

eqop
  : ( EQ | NEQ )
  ;

shiftop
  : ( SHIFT_LEFT | SHIFT_RIGHT )
  ;


class MyExprLexer extends Lexer;

options {
	k = 2;
        exportVocab=MyExpr;
}


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

IDENT
options {
	paraphrase = "identifier";
}
  :  ('a'..'z' | 'A'..'Z' | '_' ) ( ('a'..'z' | 'A'..'Z' | '_') | ('0'..'9' ))*
  ;

ICON
options {
	paraphrase = "integer constant";
}
  : '0'..'9' ('0'..'9')*
  ;

CHCON
options {
	paraphrase = "character constant";
}
  : "'" '\0'..'\255' "'"
  ;

COMMA
options {
	paraphrase = ",";
}
  : ','
  ;

SEMICOLON
options {
	paraphrase = ";";
}
  : ';'
  ;

LPAREN
options {
	paraphrase = "(";
}
  : '('
  ;

RPAREN
options {
	paraphrase = ")";
}
  : ')'
  ;

LCURL
options {
	paraphrase = "{";
}
  : '{'
  ;

RCURL
options {
	paraphrase = "}";
}
  : '}'
  ;

PLUS
options {
	paraphrase = "+";
}
  : '+'
  ;

MINUS
options {
	paraphrase = "-";
}
  : '-'
  ;

TIMES
options {
	paraphrase = "*";
}
  : '*'
  ;

DIVIDE
options {
	paraphrase = "/";
}
  : '/'
  ;

MOD
options {
	paraphrase = "%";
}
  : '%'
  ;

ASSIGN
options {
	paraphrase = "=";
}
  : '='
  ;

EQ
options {
	paraphrase = "==";
}
  : "=="
  ;

NEQ
options {
	paraphrase = "!=";
}
  : "!="
  ;

LTHAN
options {
	paraphrase = "<";
}
  :  '<'
  ;

GTHAN
options {
	paraphrase = ">";
}
  :  '>'
  ;

LEQ
options {
	paraphrase = "<=";
}
  :  "<="
  ;

GEQ
options {
	paraphrase = ">=";
}
  :  ">="
  ;

SHIFT_LEFT
options {
	paraphrase = "<<";
}
  : "<<"
  ;

SHIFT_RIGHT
options {
	paraphrase = ">>";
}
  : ">>"
  ;

back to ANTLR examples page