[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