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:num1|AddExpression: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+3-4-5 it would call 4-5 =-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   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    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 3-4-5 to 3 - Addexpr and Addexpr= 4-5 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 3-4-5 actually executed as (3-(4-5)) , and (3/4/5) would be recognized as (3/(4/5))   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    Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First
 All times are GMT - 6 Hours Page 1 of 1