kschiess / parslet

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

Parslet Alternatives Not parsing whole string #175

Closed darshan-patel closed 7 years ago

darshan-patel commented 7 years ago

@kschiess

require 'parslet'
require 'parslet/convenience'

class Lines < Parslet::Parser
    rule(:open_tag) {str('[')}
    rule(:close_tag) {str(']')}
    rule(:data) {str('name') | str('name_id') }
    rule(:text) { open_tag >> data >> close_tag }
    root :text
end

begin
    p Lines.new.parse("[name_id]")    <---- It throws error
rescue Parslet::ParseFailed => failure
    Lines.new.parse_with_debug("[name_id]")
end

Is there any alternative for this problem?

rathrio commented 7 years ago

@darshan-patel does it work when you try to match the longer string first? e.g.

rule(:data) { str('name_id') | str('name') }
kschiess commented 7 years ago
require 'parslet'
require 'parslet/convenience'

class Lines < Parslet::Parser
    rule(:open_tag) {str('[')}
    rule(:close_tag) {str(']')}
    rule(:data) { str('name_id') | str('name') }
    rule(:text) { open_tag >> data >> close_tag }
    root :text
end

begin
    p Lines.new.parse("[name_id]")   # <---- It throws error
rescue Parslet::ParseFailed => failure
    Lines.new.parse_with_debug("[name_id]")
end

When using top-down parsers (and parslet can be thought of as one, in simplification) you will always have to match the longer alternative first, failing that you'll match the shorter one. The problem is the common substring of your 'data' token.