kschiess / parslet

A small PEG based parser library. See the Hacking page in the Wiki as well.
kschiess.github.com/parslet
MIT License
805 stars 95 forks source link

Concatinated .maybe statements match "" as "" instead of nil #155

Closed postmodern closed 7 years ago

postmodern commented 8 years ago

Example

class Parser < Parslet::Parser
  root :foo
  rule(:foo) { (str('foo=').maybe >> str('bar').maybe).as(:match) }
end
Parser.new.foo.parse("")

Actual Output

# => {:match=>""}

Expected Output

# => {:match=>nil}
postmodern commented 8 years ago

Rewriting the expression as below seems to work:

rule(:foo) {
  (
    (str('foo=') >> str('bar').maybe) |
    (str('foo=').maybe >> str('bar'))
  ).maybe.as(:value)
}
kschiess commented 8 years ago

Should we act on this? What could be done?

Our merging algo is a bit finnicky - in theory, we would have to complicate things to cover all cases. But in practice, the heuristics work nicely apart from a few edge cases like this one. SOO ... it's a tradeoff...

postmodern commented 7 years ago

Can we add a note about this unexpected behavior somewhere? Kind of surprised me when I stumbled across this.