Hi Anton,

Many thanks for your advice.  I  have enclosed my grammar rules:

  rule(:epsilon)     { any.absnt? }

  rule(:lparen)      { str('(') >> space? }
  rule(:rparen)     { str(')') >> space? }

  rule(:space)       { match('\s').repeat(1) }
  rule(:space?)     { space.maybe }

  rule(:plus_op)     { str('+') >> space? }
  rule(:mult_op)    { str('*') >> space? }
  rule(:min_op)     { str('-') >> space? }
  rule(:div_op)      { str('/') >> space? }

  rule(:integer)    { (space? >> (str('+') | str('-')).maybe >> space? >>
match("[0-9]").repeat(1)).as(:integer) >> space?}

  rule(:exp)            {  term >> exp_acc }

  rule(:exp_acc)    { space? >>  mult_op >>  exp |
                                space? >>  div_op >> exp |
                               epsilon  }

  rule(:term)         { factor >>  space? >>  term_acc }

  rule(:term_acc)   {  (space? >>  plus_op >>  term) |
                                   space? >>  min_op >> term |
                                  epsilon}

rule(:factor) { identifier |float | integer | var | (lparen >> exp >> rparen) | epsilon }

  rule(:stm)            { exp }

  root  :stm

Actually, this should be a simple grammar for parsing arithmetic expressions.

But I am still struggling:-)

Thiel


Op 2-5-2011 16:36, Ant Skelton schreef:
On Mon, May 2, 2011 at 3:20 PM, Thiel Chang <[email protected] <mailto:[email protected]>> wrote:

    Hi guys,

    Due to a problem with code generation I changed my grammar rules.

    After running this code: parser.parse_with_debug( '1  +  2' )

    I got this result:

    {:stm=>{:ident=>"2"@4}}
    Duplicate subtrees while merging result of
      stm:EXP
    only the values of the latter will be kept. (keys: [:ident])

    Can anyone tell me what's  wrong?


Hard to say without seeing the grammar, but I'm guessing you have a rule that has duplicate ".as(:stm)" expressions?

    And I also have another question: when do you have to use "space" in a
    grammar rule?


When you want to consume whitespace characters. generally these are optional, so you use the "space?" idiom.
Thus
     rule(:foo) { str('1') >> space? str('+') >> space? >> str('2) }

matches your above example, and also '1+2', '1     +     2' etc.


cheers

ant

Reply via email to