Skip to content

Instantly share code, notes, and snippets.

@shopetan
Created December 23, 2017 04:55
Show Gist options
  • Save shopetan/b0370444782501a25f9cd8641f527825 to your computer and use it in GitHub Desktop.
Save shopetan/b0370444782501a25f9cd8641f527825 to your computer and use it in GitHub Desktop.
class Parser
@lexime = "";
def initialize(l)
@lexer = l
end
def parse
@lexer.lex{|t, l|
@lexime = l
@token = t
}
program
end
def program
fdecls
main
end
def main
checktoken("main", :main)
body
end
def fdecls
while @token == :ident do
checktoken("fdecls", :ident)
checktoken("fdecls", :lpar)
params
checktoken("fdecls", :rpar)
body
end
end
def params
case @token
when :ident
checktoken("params", :ident)
while @token == :comma do
checktoken("params", :comma)
checktoken("params", :ident)
end
end
end
def body
checktoken("body", :lbra)
vardecls
stmts
checktoken("body", :rbra)
end
def vardecls
case @token
when :var
while @token == :var do
checktoken("vardecls", :var)
identList
checktoken("vardecls", :semi)
end
end
end
def identList
checktoken("identList", :ident)
while @token == :comma do
checktoken("identList", :comma)
checktoken("identList", :ident)
end
end
def stmts
case @token
when :write, :writeln, :read, :ident, :if, :while, :lbra, :return
while @token == :write ||
@token == :writeln ||
@token == :read ||
@token == :ident ||
@token == :if ||
@token == :while ||
@token == :return ||
@token == :lbra do
stmt
end
else
errormsg("stmts", @token, :write, :writeln,
:read, :ident, :if, :while, :lbra, :return)
end
end
def stmt
case @token
when :write
checktoken("stmt", :write)
expression
checktoken("stmt", :semi)
when :writeln
checktoken("stmt", :writeln)
checktoken("stmt", :semi)
when :read
checktoken("stmt", :read)
checktoken("stmt", :ident)
checktoken("stmt", :semi)
when :ident
checktoken("stmt", :ident)
checktoken("stmt", :coleq)
expression
checktoken("stmt", :semi)
when :if
ifstmt
when :while
whilestmt
when :lbra
body
when :return
checktoken("stmt", :return)
expression
checktoken("stmt", :semi)
else
errormsg("stmts", @token, :write, :writeln,
:read, :ident, :if, :while, :lbra)
end
end
def ifstmt
checktoken("ifstmt", :if)
condition
checktoken("ifstmt", :then)
stmt
case @token
when :endif
checktoken("ifstmt", :endif)
checktoken("ifstmt", :semi)
when :else
checktoken("ifstmt", :else)
stmt
checktoken("ifstmt", :endif)
else
errormsg("ifstmts", @token, :endif, :else)
end
checktoken("ifstmt", :semi)
end
def whilestmt
checktoken("whilestmt", :while)
condition
checktoken("whilestmt", :do)
stmt
end
def condition
cexp
end
def cexp
expression
if @token == :eq ||
@token == :neq ||
@token == :lt ||
@token == :gt ||
@token == :leq ||
@token == :geq then
checktoken("cexp", @token)
else
errormsg("cexp", @token, :eq, :neq, :lt, :gt, :leq, :geq)
end
expression
end
def expression
term
while @token == :plus || @token == :minus do
if @token == :plus then
checktoken("expression", :plus)
elsif @token == :minus then
checktoken("expression", :minus)
else
end
term
end
end
def term
factor
while @token == :mult || @token == :div do
if @token == :mult
checktoken("term", :mult)
else
checktoken("term", :div)
end
factor
end
end
def factor
case @token
when :number
checktoken("factor", :number)
when :lpar
checktoken("factor", :lpar)
expression
checktoken("factor", :rpar)
when :ident
checktoken("factor", :ident)
if @token == :lpar
checktoken("factor", :lpar)
if @token == :rpar
else
aparams
end
checktoken("factor", :rpar)
end
end
end
def aparams
case @token
when :lpar, :ident, :number
expression
while @token == :comma do
checktoken("aparams", :comma)
expression
end
else
end
end
def checktoken(f, expected)
if @token == expected
@lexer.lex(){|t,l|
@token=t
}
else
errormsg(f, @token, expected)
end
end
def errormsg(f, et, *tokens)
tks = tokens.join(" or ")
puts "syntax error (#{f}(#{et})) : #{tks} is expected."
exit(1)
end
end
lexer = Lexer.new($stdin)
parser=Parser.new(lexer)
parser.parse
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment