Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
188 additions
and
141 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,162 +1,40 @@ | ||
require 'optparse' | ||
|
||
module Lrama | ||
class Command | ||
def initialize(argv) | ||
@argv = argv | ||
|
||
@skeleton = "bison/yacc.c" | ||
@header = false | ||
@header_file = nil | ||
@report = [] | ||
@report_file = nil | ||
@outfile = "y.tab.c" | ||
@trace = [] | ||
@error_recovery = false | ||
@grammar_file = nil | ||
@report_file = nil | ||
@trace_opts = nil | ||
@report_opts = nil | ||
end | ||
def run(argv) | ||
options = OptionParser.new.parse(argv) | ||
|
||
def run | ||
parse_option | ||
|
||
Report::Duration.enable if @trace_opts[:time] | ||
Report::Duration.enable if options.trace_opts[:time] | ||
|
||
warning = Lrama::Warning.new | ||
grammar = Lrama::Parser.new(@y.read).parse | ||
@y.close if @y != STDIN | ||
states = Lrama::States.new(grammar, warning, trace_state: (@trace_opts[:automaton] || @trace_opts[:closure])) | ||
grammar = Lrama::Parser.new(options.y.read).parse | ||
options.y.close if options.y != STDIN | ||
states = Lrama::States.new(grammar, warning, trace_state: (options.trace_opts[:automaton] || options.trace_opts[:closure])) | ||
states.compute | ||
context = Lrama::Context.new(states) | ||
|
||
if @report_file | ||
if options.report_file | ||
reporter = Lrama::StatesReporter.new(states) | ||
File.open(@report_file, "w+") do |f| | ||
reporter.report(f, **@report_opts) | ||
File.open(options.report_file, "w+") do |f| | ||
reporter.report(f, **options.report_opts) | ||
end | ||
end | ||
|
||
File.open(@outfile, "w+") do |f| | ||
File.open(options.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, | ||
output_file_path: options.outfile, | ||
template_name: options.skeleton, | ||
grammar_file_path: options.grammar_file, | ||
header_file_path: options.header_file, | ||
context: context, | ||
grammar: grammar, | ||
error_recovery: @error_recovery, | ||
error_recovery: options.error_recovery, | ||
).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[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 | ||
|
||
def parse_option | ||
opt = OptionParser.new | ||
|
||
# opt.on('-h') {|v| p v } | ||
opt.on('-V', '--version') {|v| puts "lrama #{Lrama::VERSION}"; exit 0 } | ||
|
||
# Tuning the Parser | ||
opt.on('-S', '--skeleton=FILE') {|v| @skeleton = v } | ||
opt.on('-t') { } # Do nothing | ||
|
||
# Output Files: | ||
opt.on('-h', '--header=[FILE]') {|v| @header = true; @header_file = v } | ||
opt.on('-d') { @header = true } | ||
opt.on('-r', '--report=THINGS', Array) {|v| @report = v } | ||
opt.on('--report-file=FILE') {|v| @report_file = v } | ||
opt.on('-v') { } # Do nothing | ||
opt.on('-o', '--output=FILE') {|v| @outfile = v } | ||
|
||
# Hidden | ||
opt.on('--trace=THINGS', Array) {|v| @trace = v } | ||
|
||
# Error Recovery | ||
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 !@grammar_file | ||
abort "File should be specified\n" | ||
end | ||
|
||
if @grammar_file == '-' | ||
@grammar_file = @argv.shift or abort "File name for STDIN should be specified\n" | ||
@y = STDIN | ||
else | ||
@y = File.open(@grammar_file, 'r') | ||
end | ||
|
||
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 | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
require 'optparse' | ||
|
||
module Lrama | ||
# Handle option parsing for the command line interface. | ||
class OptionParser | ||
def initialize | ||
@options = Options.new | ||
@trace = [] | ||
@report = [] | ||
end | ||
|
||
def parse(argv) | ||
parse_by_option_parser(argv) | ||
|
||
@options.trace_opts = validate_trace(@trace) | ||
@options.report_opts = validate_report(@report) | ||
@options.grammar_file = argv.shift | ||
|
||
if !@options.grammar_file | ||
abort "File should be specified\n" | ||
end | ||
|
||
if @options.grammar_file == '-' | ||
@options.grammar_file = argv.shift or abort "File name for STDIN should be specified\n" | ||
else | ||
@options.y = File.open(@options.grammar_file, 'r') | ||
end | ||
|
||
if !@report.empty? && @options.report_file.nil? && @options.grammar_file | ||
@options.report_file = File.dirname(@options.grammar_file) + "/" + File.basename(@options.grammar_file, ".*") + ".output" | ||
end | ||
|
||
if !@options.header_file && @options.header | ||
case | ||
when @options.outfile | ||
@options.header_file = File.dirname(@options.outfile) + "/" + File.basename(@options.outfile, ".*") + ".h" | ||
when @options.grammar_file | ||
@options.header_file = File.dirname(@options.grammar_file) + "/" + File.basename(@options.grammar_file, ".*") + ".h" | ||
end | ||
end | ||
|
||
@options | ||
end | ||
|
||
private | ||
|
||
def parse_by_option_parser(argv) | ||
::OptionParser.new do |o| | ||
o.banner = <<~BANNER | ||
Lrama is LALR (1) parser generator written by Ruby. | ||
Usage: lrama [options] FILE | ||
BANNER | ||
o.separator '' | ||
o.separator 'Tuning the Parser:' | ||
o.on('-S', '--skeleton=FILE', 'specify the skeleton to use') {|v| @options.skeleton = v } | ||
o.on('-t', 'reserved, do nothing') { } | ||
o.separator '' | ||
o.separator 'Output:' | ||
o.on('-h', '--header=[FILE]', 'also produce a header file named FILE') {|v| @options.header = true; @options.header_file = v } | ||
o.on('-d', 'also produce a header file') { @options.header = true } | ||
o.on('-r', '--report=THINGS', Array, 'also produce details on the automaton') {|v| @report = v } | ||
o.on('--report-file=FILE', 'also produce details on the automaton output to a file named FILE') {|v| @options.report_file = v } | ||
o.on('-o', '--output=FILE', 'leave output to FILE') {|v| @options.outfile = v } | ||
o.on('--trace=THINGS', Array, 'also output trace logs at runtime') {|v| @trace = v } | ||
o.on('-v', 'reserved, do nothing') { } | ||
o.separator '' | ||
o.separator 'Error Recovery:' | ||
o.on('-e', 'enable error recovery') {|v| @options.error_recovery = true } | ||
o.separator '' | ||
o.separator 'Other options:' | ||
o.on('-V', '--version', "output version information and exit") {|v| puts "lrama #{Lrama::VERSION}"; exit 0 } | ||
o.on('--help', "display this help and exit") {|v| puts o; exit 0 } | ||
o.separator '' | ||
o.parse!(argv) | ||
end | ||
end | ||
|
||
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[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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
module Lrama | ||
# Command line options. | ||
class Options | ||
attr_accessor :skeleton, :header, :header_file, | ||
:report_file, :outfile, | ||
:error_recovery, :grammar_file, | ||
:report_file, :trace_opts, :report_opts, :y | ||
|
||
def initialize | ||
@skeleton = "bison/yacc.c" | ||
@header = false | ||
@header_file = nil | ||
@report_file = nil | ||
@outfile = "y.tab.c" | ||
@error_recovery = false | ||
@grammar_file = nil | ||
@report_file = nil | ||
@trace_opts = nil | ||
@report_opts = nil | ||
@y = STDIN | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
module Lrama | ||
VERSION = "0.5.5".freeze | ||
VERSION = "0.5.6".freeze | ||
end |