Skip to content

Instantly share code, notes, and snippets.

@katsuyoshi
Created December 17, 2023 09:19
Show Gist options
  • Save katsuyoshi/beb21e5ee2babeaaca1e1aff59b288f8 to your computer and use it in GitHub Desktop.
Save katsuyoshi/beb21e5ee2babeaaca1e1aff59b288f8 to your computer and use it in GitHub Desktop.
Learning racc
% racc parser.y -o parser.rb
% ruby parser.rb
1+2-3*4/5
class Parser
rule
expression:
term
| expression '+' term { puts '+'; result = val[0] + val[2] }
| expression '-' term { puts '-'; result = val[0] - val[2] }
term :
primary_expression
| term '*' primary_expression { puts '*'; result = val[0] * val[2] }
| term '/' primary_expression { puts '-'; result = val[0] / val[2] }
primary_expression:
INTEGER
| DOUBLE
end
---- inner
def parse(text)
@scanner = StringScanner.new text
do_parse
end
def next_token
if @scanner.eos?
[false, nil]
elsif t = @scanner.scan(/\d+\.\d*/)
[:DOUBLE, t.to_f]
elsif t = @scanner.scan(/\d+/)
[:INTEGER, t.to_i]
elsif @scanner.scan(/\s+/)
next_token
elsif t = @scanner.scan(/[\+\-\*\/]/)
[t, nil]
end
end
---- footer
if $0 == __FILE__
require 'strscan'
$stdin.each_line do |line|
puts Parser.new.parse(line)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment