View previous topic :: View next topic 
Author 
Message 
davidl
Joined: 17 Aug 2006 Posts: 27

Posted: Tue Nov 21, 2006 9:35 am Post subject: how can i make the grammar call from left to right 


.import("enki.BaseParser");
.import("std.conv");
.import("calc");
.define("String","digit","true","Digit");
Expr = float num
::= AddExpression:num;
AddExpression = float add(num1,num2,opr)
::=
(MulExpression:num1AddExpression:num1)[ ("+":opr  "":opr) AddExpression:num2]
;
MulExpression = float mul(num1,num2,opr)
::= number:num1 [("*":opr  "/":opr) MulExpression:num2]
;
number = float toFloat(num1)
::= {digit}:num1;
the grammar would call from right to left
like parse
2+3+4+5
it would call 4+5 then 9+3 then 12+2
it would be alright when plus
consider
2+345
it would call 45 =1 then 3(1) = 4 2+4=6 which is incorrect
and also
2/3*4
it would 3*4 =12 2/12 = 0.1833 but it shouldn't 

Back to top 


pragma
Joined: 28 May 2004 Posts: 607 Location: Washington, DC

Posted: Tue Nov 21, 2006 12:32 pm Post subject: Re: how can i make the grammar call from left to right 


David, you might want to try a grammar that looks a little more like this:
Code: 
Expr ::= Add;
Add ::= Mul [('+'  '') Add)];
Mul ::= Atom [('*'  '/') Mul];
Atom ::= number  '(' Expr ')';

_________________  !Eric.t.Anderton at gmail 

Back to top 


davidl
Joined: 17 Aug 2006 Posts: 27

Posted: Tue Nov 21, 2006 7:29 pm Post subject: 


i guess u didn't get my point.
the grammar actually recognize the following sequence
345 to
3  Addexpr
and Addexpr= 45
and i call add(4,5,'') which return 1
then call add(3,1,'') which return 4
the grammar eval the expr from right to left, if i introduce a stack it's painful
in all it actually add () to the rightest expr, so 345 actually executed as
(3(45)) , and (3/4/5) would be recognized as (3/(4/5)) 

Back to top 


pragma
Joined: 28 May 2004 Posts: 607 Location: Washington, DC

Posted: Wed Nov 22, 2006 10:29 am Post subject: 


My apologies. You're right about having to add a stack: for something like this, it should be a piece of cake.
I see what I did wrong in my suggestion. Take a look at the calculator grammar here: http://www.nongnu.org/bnf/
Code:  input ::= ws expr ws eoi;
expr ::= ws powterm [{ws '^' ws powterm}];
powterm ::= ws factor [{ws ('*''/') ws factor}];
factor ::= ws term [{ws ('+''') ws term}];
term ::= '(' ws expr ws ')'  '' ws expr  number;
number ::= {dgt} ['.' {dgt}] [('e''E') [''] {dgt}];
dgt ::= '0''1''2''3''4''5''6''7''8''9';
ws ::= [{' ''\t''\n''\r'}]; 
This should do the trick. From here you can try expanding the grammar into a tree, or just use arrays to store the terms for evaluation:
Code:  expr = float expr(float[] terms)
::= ws powterm:~terms {ws '^' ws powterm:~terms}; 
_________________  !Eric.t.Anderton at gmail 

Back to top 


