[antlr-interest] need help designing a simple calculator

fedot fedot at stockworm.com
Mon Mar 10 13:21:43 PST 2003


Having read through just about all ANTLR documentation I could lay 
my hands on, I am sorry to say that I am more frustrated than 
enlightened at this point. I would be greatly thankful if anyone 
experienced enough with ANTLR could lend me a hand with the 
following task:

I need to design a parser capable of evaluating one-liner boolean 
equations, such as:

    "F1(A, 5) AND F2(B)"
    "A <= 0.4 AND F1(B, 1) OR F2(C, 2)"
    "NOT (A <> 10 AND B < 0.5)"

Or more specifically, being able to perform the following operations 
(in order of precedence):

OR
AND
= <>
< <= > >=
+ -
* /
NOT

Variables are given as a map of name/value pairs, and list of 
functions is fixed and known ahead of time.

Attached is my first shot at lexer/parser to do the job. I am still 
not sure what direction I should take next, as I am not at all 
comfortable yet with ANTLR and not familiar with all of its 
capabilities. Specifically, I have the following questions to answer:

1) do I need to build an AST and use a TreeParser to actually 
evaluate my expressions? or do I just do it all within the parser?

2) i know why I am getting ambiguity warnings about conflicts 
between "AND/OR/NOT" operators and ID identifiers, but what should I 
do about eliminating that ambuguity?

3) i don't think i did the right thing with unary_expression being a 
NUMBER constant, a parenthesized "expression", an ID (variable), or 
a function call. or did i? it seems that ID and function should be 
two separate rules instead of one with optional function arguments.

Like I said, you would be doing me a GREAT favor if you could point 
me in the right direction.

Thank you!

---------------------------

// Parser
class SignalParser extends Parser;

options {
    buildAST = true;
}

expression:
    logical_or_expression
;

logical_or_expression:
    logical_and_expression (OR^ logical_and_expression)*
;

logical_and_expression:
    equality_expression (AND^ equality_expression)*
;

equality_expression:
    relational_expression ((EQ^ | NE^) relational_expression)*
;

relational_expression:
    additive_expression ((LT^ | LE^ | GT^ | GE^) additive_expression)
*
;

additive_expression:
    multiplicative_expression ((ADD^ | SUBTRACT^) 
multiplicative_expression)*
;

multiplicative_expression:
    unary_expression ((MULTIPLY^ | DIVIDE^) unary_expression)*
;

unary_expression:
    NUMBER
    |
    LPAREN! expression RPAREN!
    |
    ID (LPAREN! (expression (COMMA! expression)*)? RPAREN!)?
;

// Lexer
class SignalLexer extends Lexer;

options {
    k = 2;
}

WHITESPACE:
    (' ' | '\t' | '\n' { newline(); } | '\r') { $setType
(Token.SKIP); }
;

NUMBER:
    (DIGIT)+  ('.' (DIGIT)*)? (EXPONENT)? | '.' (DIGIT)+ (EXPONENT)?
;

ID:
    ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' 
| '0'..'9')*
;

protected
DIGIT:
    '0'..'9'
;

protected
EXPONENT:
    ('e' | 'E') ('+' | '-')? (DIGIT)+
;

LPAREN: "(" ;
RPAREN: ")" ;
COMMA: "," ;

OR: "OR" ;
AND: "AND" ;

EQ: "=" ;
NE: "<>" ;

LT: "<" ;
LE: "<=" ;
GT: ">" ;
GE: ">=" ;

ADD: "+" ;
SUBTRACT: "-" ;

MULTIPLY: "*" ;
DIVIDE: "/" ;

NOT: "NOT" ;



 

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



More information about the antlr-interest mailing list