Skip to content

Instantly share code, notes, and snippets.

@kschiess
Created May 29, 2012 05:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kschiess/2822799 to your computer and use it in GitHub Desktop.
Save kschiess/2822799 to your computer and use it in GitHub Desktop.
Parses a tokenized stream of elements.
require 'parslet'
include Parslet
input = %w(a aa b)
class El < Parslet::Atoms::Base
def initialize(pattern)
@pattern = pattern
super()
end
def to_s_inner(prec)
"'#{@pattern}'"
end
def try(source, context)
return succ(source.consume(1)) if source.matches?(@pattern)
# Failures:
error_pos = source.pos
return context.err_at(
self, source,
"Failed to match #@pattern", error_pos)
end
end
def el(*args)
El.new(*args)
end
parser1 = el('a') >> el('aa') >> el('b')
parser2 = el('aa') >> el('a') >> el('b')
class ArySource
def initialize(ary)
@ary = ary
@pos = 0
end
def line_and_column(pos=nil)
[1, (pos || @pos)+1]
end
attr_accessor :pos
def matches?(pattern)
@ary[@pos] == pattern
end
def consume(n)
@ary.slice(@pos, n).join(',').tap {
@pos += n
}
end
def eof?
@pos >= @ary.size
end
def chars_left
@ary.size-@pos.size
end
end
s = ArySource.new(input)
require 'parslet/convenience'
puts "parser1: "
p parser1.parse_with_debug(s)
s.pos = 0
puts "parser2: "
p parser2.parse_with_debug(s)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment