Skip to content

Instantly share code, notes, and snippets.

@dhilst
Created November 4, 2022 01:51
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 dhilst/4d1a32f6bf0665407e87a09c08738ffa to your computer and use it in GitHub Desktop.
Save dhilst/4d1a32f6bf0665407e87a09c08738ffa to your computer and use it in GitHub Desktop.
Getting started with racc (ruby LALR(1) parser lib)
class Calcparser
prechigh
left '*' '/'
left '+' '-'
preclow
options no_result_var
rule
target: expr
expr: expr "+" expr { [:+, val[0], val[2]] }
| expr "*" expr { [:*, val[0], val[2]] }
| NUMBER
end
---- inner
def make_tokens str
require 'strscan'
result = []
scanner = StringScanner.new str
until scanner.empty?
case
when scanner.scan(/\s+/)
#ignore whitespace
when match = scanner.scan(/\+/)
result << ["+", "+"]
when match = scanner.scan(/\*/)
result << ["*", "*"]
when match = scanner.scan(/\d+/)
result << [:NUMBER, match[0].to_i]
else
raise "can't recognize <#{scanner.peek(5)}>"
end
end
result << [false, false]
return result
end
attr_accessor :result
def parse(str)
@result = []
@tokens = make_tokens str
do_parse
end
def next_token
@tokens.shift
end
require './grammar.tab'
parser = Calcparser.new
x = parser.parse "1 + 2 * 1"
p x
racc grammar.y.rb; echo; ruby main.rb
# output : [:+, 1, [:*, 2, 1]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment