0

Good morning everyone,

I'm currently trying to describe some basic Ruby grammar but I'm now stuck with parse space? I can handle x = 1 + 1,
but can't parser x=1+1,
how can I parser space?
I have tried add enough space after every terminal. but it can't parse,give a nil..... How can I fix it? Thank you very much, have a nice day.


grammar Test
  rule main
     s assign
  end

  rule assign
     name:[a-z]+ s '=' s expression s
     {
      def to_ast
        Assign.new(name.text_value.to_sym, expression.to_ast)
      end
    }
  end


  rule expression
     add
  end


  rule add
     left:brackets s '+' s right:add s
     {
      def to_ast
        Add.new(left.to_ast, right.to_ast)
      end
    }
    /
    minus
  end

  rule minus
     left:brackets s '-' s right:minus s
     {
      def to_ast
        Minus.new(left.to_ast, right.to_ast)
      end
    }
    /
    brackets
  end

  rule brackets
      '(' s expression ')' s
      {
       def to_ast
          expression.to_ast
       end
     }
      /
    term
  end

  rule term
    number / variable
  end

  rule number
     [0-9]+ s
     {
      def to_ast
        Number.new(text_value.to_i)
      end
    }
  end

  rule variable
     [a-z]+ s
     {
      def to_ast
        Variable.new(text_value.to_sym)
      end
     }
  end

  rule newline
     s "\n"+ s
  end

  rule s
    [ \t]*
  end
end

this code works problem Solved!!!!

4

1 回答 1

2

It's not enough to define the space rule, you have to use it anywhere there might be space. Because this occurs often, I usually use a shorter rule name S for mandatory space, and the lowercase version s for optional space.

Then, as a principle, I skip optional space first in my top rule, and again after every terminal that can be followed by space. Terminals here are strings, character sets, etc. So at the start of assign, and before the {} block on variable, boolean, number, and also after your '=', '-' and '+' literals, add a call to the rule s to skip any spaces.

This policy works well for me. It's a good idea to have a test case which has minimum space, and another case that has maximum space (in all possible places).

于 2017-10-06T23:58:38.890 回答