Skip to content

Instantly share code, notes, and snippets.

@crguezl
Created March 29, 2012 06:31
Show Gist options
  • Save crguezl/2234155 to your computer and use it in GitHub Desktop.
Save crguezl/2234155 to your computer and use it in GitHub Desktop.
Recursive Predictive parser for a simple grammar: s -> A s B | c ; c -> C c | C
# svn+ssh://orion/var/svn/casiano/LPP/rubytesting/simplerecdescent
# s -> A s B
# | c
# c -> C c
# | C
class Lexer
attr_accessor :input, :tokens, :pos
def initialize(input)
@input = input
@tokens = @input.scan(/\S/)
@pos = -1
end
def next
@pos += 1
if @pos < @tokens.length
@tokens[@pos]
else
nil
end
end
end
def lexer
@lookahead = @lex.next
end
def match(t)
if @lookahead == t
lexer
else
raise SyntaxError, "Error. Expecting '#{t}', found #{@lookahead}"
end
end
def s
if @lookahead == 'A' then
lexer
s
match('B')
puts "s -> A s B"
elsif @lookahead == 'C' then
c
puts "s -> c"
else
raise SyntaxError, "Error. Expecting 'A' or 'C'"
end
end
def c
if @lookahead == 'C' then
lexer
end
if @lookahead == 'C' then
c
puts "c -> C c"
elsif ['B', nil].include? @lookahead then
puts "c -> C"
return
else
raise SyntaxError, "Error. Expecting 'C' or 'B' or end of input but found '#@lookahead'"
end
end
@lex = Lexer.new(ARGV.shift || 'ACCB')
puts @lex.input
lexer
s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment