Skip to content

Commit

Permalink
Install lrama v0.2.1 and use it for parser generation
Browse files Browse the repository at this point in the history
  • Loading branch information
yui-knk committed May 10, 2023
1 parent 8866e08 commit 67c049e
Show file tree
Hide file tree
Showing 20 changed files with 5,711 additions and 2 deletions.
2 changes: 1 addition & 1 deletion common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -1208,7 +1208,7 @@ $(srcdir)/ext/ripper/ripper.c: $(srcdir)/ext/ripper/tools/preproc.rb $(srcdir)/p
$(Q) $(CHDIR) $(@D) && \
$(CAT_DEPEND) depend | \
$(exec) $(MAKE) -f - $(mflags) \
Q=$(Q) ECHO=$(ECHO) RM="$(RM1)" BISON="$(YACC)" top_srcdir=../.. srcdir=. VPATH=../.. \
Q=$(Q) ECHO=$(ECHO) RM="$(RM1)" top_srcdir=../.. srcdir=. VPATH=../.. \
RUBY="$(BASERUBY)" PATH_SEPARATOR="$(PATH_SEPARATOR)" LANG=C

$(srcdir)/ext/json/parser/parser.c: $(srcdir)/ext/json/parser/parser.rl $(srcdir)/ext/json/parser/prereq.mk
Expand Down
1 change: 1 addition & 0 deletions ext/ripper/depend
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
GEN = $(srcdir)/tools/generate.rb
SRC1 = $(top_srcdir)/parse.y
SRC2 = $(srcdir)/eventids2.c
BISON = $(top_srcdir)/tool/lrama/exe/lrama

.SUFFIXES: .y

Expand Down
2 changes: 1 addition & 1 deletion template/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ CPP = @CPP@
LD = @LD@
RUSTC = @RUSTC@
CARGO = @CARGO@
YACC = bison
YACC = $(tooldir)/lrama/exe/lrama
PURIFY =
AUTOCONF = autoconf
CONFIGURE = @CONFIGURE@
Expand Down
7 changes: 7 additions & 0 deletions tool/lrama/exe/lrama
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env ruby


$LOAD_PATH << File.join(__dir__, "../lib")
require "lrama"

Lrama::Command.new.run(ARGV.dup)
13 changes: 13 additions & 0 deletions tool/lrama/lib/lrama.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require "lrama/bitmap"
require "lrama/command"
require "lrama/context"
require "lrama/digraph"
require "lrama/grammar"
require "lrama/lexer"
require "lrama/output"
require "lrama/parser"
require "lrama/report"
require "lrama/states"
require "lrama/states_reporter"
require "lrama/version"
require "lrama/warning"
29 changes: 29 additions & 0 deletions tool/lrama/lib/lrama/bitmap.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module Lrama
module Bitmap
def self.from_array(ary)
bit = 0

ary.each do |int|
bit |= (1 << int)
end

bit
end

def self.to_array(int)
a = []
i = 0

while int > 0 do
if int & 1 == 1
a << i
end

i += 1
int >>= 1
end

a
end
end
end
144 changes: 144 additions & 0 deletions tool/lrama/lib/lrama/command.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
require 'optparse'

module Lrama
class Command
def run(argv)
opt = OptionParser.new

# opt.on('-h') {|v| p v }
opt.on('-V', '--version') {|v| puts Lrama::VERSION ; exit 0 }

# Tuning the Parser
skeleton = "bison/yacc.c"

opt.on('-S', '--skeleton=FILE') {|v| skeleton = v }
opt.on('-t') { } # Do nothing

# Output Files:
header = false
header_file = nil
report = []
report_file = nil
outfile = "y.tab.c"

opt.on('-h', '--header=[FILE]') {|v| header = true; header_file = v }
opt.on('-d') { header = true }
opt.on('-r', '--report=THINGS') {|v| report = v.split(',') }
opt.on('--report-file=FILE') {|v| report_file = v }
opt.on('-v') { } # Do nothing
opt.on('-o', '--output=FILE') {|v| outfile = v }

# Hidden
trace = []
opt.on('--trace=THINGS') {|v| trace = v.split(',') }

# Error Recovery
error_recovery = false
opt.on('-e') {|v| error_recovery = true }

opt.parse!(argv)

trace_opts = validate_trace(trace)
report_opts = validate_report(report)

grammar_file = argv.shift

if !report.empty? && report_file.nil? && grammar_file
report_file = File.dirname(grammar_file) + "/" + File.basename(grammar_file, ".*") + ".output"
end

if !header_file && header
case
when outfile
header_file = File.dirname(outfile) + "/" + File.basename(outfile, ".*") + ".h"
when grammar_file
header_file = File.dirname(grammar_file) + "/" + File.basename(grammar_file, ".*") + ".h"
end
end

if !grammar_file
puts "File should be specified\n"
exit 1
end

Report::Duration.enable if trace_opts[:time]

warning = Lrama::Warning.new
y = File.read(grammar_file)
grammar = Lrama::Parser.new(y).parse
states = Lrama::States.new(grammar, warning, trace_state: (trace_opts[:automaton] || trace_opts[:closure]))
states.compute
context = Lrama::Context.new(states)

if report_file
reporter = Lrama::StatesReporter.new(states)
File.open(report_file, "w+") do |f|
reporter.report(f, **report_opts)
end
end

File.open(outfile, "w+") do |f|
Lrama::Output.new(
out: f,
output_file_path: outfile,
template_name: skeleton,
grammar_file_path: grammar_file,
header_file_path: header_file,
context: context,
grammar: grammar,
).render
end

if warning.has_error?
exit 1
end
end

private

def validate_report(report)
bison_list = %w[states itemsets lookaheads solved counterexamples cex all none]
others = %w[verbose]
list = bison_list + others
not_supported = %w[counterexamples cex none]
h = { grammar: true }

report.each do |r|
if list.include?(r) && !not_supported.include?(r)
h[r.to_sym] = true
else
raise "Invalid report option \"#{r}\"."
end
end

if h[:all]
(bison_list - not_supported).each do |r|
h[r.to_sym] = true
end

h.delete(:all)
end

return h
end

def validate_trace(trace)
list = %w[
none locations scan parse automaton bitsets
closure grammar resource sets muscles tools
m4-early m4 skeleton time ielr cex all
]
h = {}

trace.each do |t|
if list.include?(t)
h[t.to_sym] = true
else
raise "Invalid trace option \"#{t}\"."
end
end

return h
end
end
end
Loading

0 comments on commit 67c049e

Please sign in to comment.