diff --git a/README.md b/README.md index f42b95e6..87f81d08 100644 --- a/README.md +++ b/README.md @@ -36,13 +36,8 @@ $ lrama -d sample/parse.y ``` ```shell -# "y.tab.c" and "y.tab.h" are generated and added `#include "y.tab.h"` -$ lrama -d sample/parse.y --auto-include -``` - -```shell -# "calc", "calc.c", and "calc.h" are generated and added `#include "calc.h"` -$ lrama -d sample/calc.y -o calc.c --auto-include && gcc -Wall calc.c -o calc && ./calc +# "calc", "calc.c", and "calc.h" are generated +$ lrama -d sample/calc.y -o calc.c && gcc -Wall calc.c -o calc && ./calc Enter the formula: 1 => 1 diff --git a/lib/lrama/command.rb b/lib/lrama/command.rb index 301b3e67..213b7acb 100644 --- a/lib/lrama/command.rb +++ b/lib/lrama/command.rb @@ -8,7 +8,7 @@ def run(argv) warning = Lrama::Warning.new text = options.y.read options.y.close if options.y != STDIN - grammar = Lrama::NewParser.new(text, options.include_header).parse + grammar = Lrama::NewParser.new(text).parse states = Lrama::States.new(grammar, warning, trace_state: (options.trace_opts[:automaton] || options.trace_opts[:closure])) states.compute context = Lrama::Context.new(states) diff --git a/lib/lrama/new_parser.rb b/lib/lrama/new_parser.rb index ea819939..a33fdfdc 100644 --- a/lib/lrama/new_parser.rb +++ b/lib/lrama/new_parser.rb @@ -670,9 +670,8 @@ class NewParser < Racc::Parser module_eval(<<'...end parser.y/module_eval...', 'parser.y', 378) -def initialize(text, include_header) +def initialize(text) @text = text - @include_header = include_header end def parse @@ -690,14 +689,6 @@ def parse def next_token @lexer.next_token end - -def prologue(s_value) - if @include_header && !s_value.match?(/^\s*#include\s+"#{@include_header}"/) - "\n#include \"#{@include_header}\"\n" + s_value - else - s_value - end -end ...end parser.y/module_eval... ##### State transition tables begin ### @@ -1127,7 +1118,7 @@ def _reduce_5(val, _values, result) module_eval(<<'.,.,', 'parser.y', 20) def _reduce_6(val, _values, result) - @grammar.prologue = prologue(val[2].s_value) + @grammar.prologue = val[2].s_value result end diff --git a/lib/lrama/option_parser.rb b/lib/lrama/option_parser.rb index c33c0aa7..35725fc6 100644 --- a/lib/lrama/option_parser.rb +++ b/lib/lrama/option_parser.rb @@ -39,10 +39,6 @@ def parse(argv) end end - if @options.auto_include - @options.include_header = @options.header_file.sub("./", "") - end - @options end @@ -66,7 +62,6 @@ def parse_by_option_parser(argv) 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('--auto-include', 'also include header files automatically') {|v| @options.auto_include = 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 } diff --git a/lib/lrama/options.rb b/lib/lrama/options.rb index 0fed96e5..01b3e701 100644 --- a/lib/lrama/options.rb +++ b/lib/lrama/options.rb @@ -1,8 +1,8 @@ module Lrama # Command line options. class Options - attr_accessor :skeleton, :header, :header_file, :auto_include, - :include_header, :report_file, :outfile, + attr_accessor :skeleton, :header, :header_file, + :report_file, :outfile, :error_recovery, :grammar_file, :report_file, :trace_opts, :report_opts, :y @@ -10,8 +10,6 @@ def initialize @skeleton = "bison/yacc.c" @header = false @header_file = nil - @auto_include = false - @include_header = nil @report_file = nil @outfile = "y.tab.c" @error_recovery = false diff --git a/lib/lrama/output.rb b/lib/lrama/output.rb index 1a9a84d6..5bc4d1ab 100644 --- a/lib/lrama/output.rb +++ b/lib/lrama/output.rb @@ -7,7 +7,7 @@ class Output extend Forwardable include Report::Duration - attr_reader :grammar_file_path, :context, :grammar, :error_recovery + attr_reader :grammar_file_path, :context, :grammar, :error_recovery, :include_header def_delegators "@context", :yyfinal, :yylast, :yyntokens, :yynnts, :yynrules, :yynstates, :yymaxutok, :yypact_ninf, :yytable_ninf @@ -28,6 +28,7 @@ def initialize( @context = context @grammar = grammar @error_recovery = error_recovery + @include_header = header_file_path ? header_file_path.sub("./", "") : nil end if ERB.instance_method(:initialize).parameters.last.first == :key diff --git a/parser.y b/parser.y index 390248dd..5301eabd 100644 --- a/parser.y +++ b/parser.y @@ -18,7 +18,7 @@ rule } "%}" { - @grammar.prologue = prologue(val[2].s_value) + @grammar.prologue = val[2].s_value } | "%require" STRING @@ -376,9 +376,8 @@ end ---- inner -def initialize(text, include_header) +def initialize(text) @text = text - @include_header = include_header end def parse @@ -397,10 +396,3 @@ def next_token @lexer.next_token end -def prologue(s_value) - if @include_header && !s_value.match?(/^\s*#include\s+"#{@include_header}"/) - "\n#include \"#{@include_header}\"\n" + s_value - else - s_value - end -end diff --git a/spec/lrama/context_spec.rb b/spec/lrama/context_spec.rb index 44150088..d81d5964 100644 --- a/spec/lrama/context_spec.rb +++ b/spec/lrama/context_spec.rb @@ -5,7 +5,7 @@ describe "basic" do it do y = File.read(fixture_path("context/basic.y")) - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse states = Lrama::States.new(grammar, warning) states.compute context = Lrama::Context.new(states) @@ -181,7 +181,7 @@ %% INPUT - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse states = Lrama::States.new(grammar, warning) states.compute context = Lrama::Context.new(states) @@ -230,7 +230,7 @@ %% INPUT - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse states = Lrama::States.new(grammar, warning) states.compute context = Lrama::Context.new(states) diff --git a/spec/lrama/new_parser_spec.rb b/spec/lrama/new_parser_spec.rb index b9c69b0b..c5ecda4b 100644 --- a/spec/lrama/new_parser_spec.rb +++ b/spec/lrama/new_parser_spec.rb @@ -41,7 +41,7 @@ describe '#parse' do it "basic" do y = File.read(fixture_path("common/basic.y")) - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse expect(grammar.union.code.s_value).to eq(<<-CODE.chomp) @@ -408,7 +408,7 @@ it "nullable" do y = File.read(fixture_path("common/nullable.y")) - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse expect(grammar.nterms.sort_by(&:number)).to eq([ Sym.new(id: T.new(type: T::Ident, s_value: "$accept"), alias_name: nil, number: 6, tag: nil, term: false, token_id: 0, nullable: false), @@ -562,7 +562,7 @@ class : keyword_class tSTRING keyword_end { code 1 } %% INPUT - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse expect(grammar._rules).to eq([ [ @@ -605,7 +605,7 @@ class : keyword_class tSTRING keyword_end { code 1 } %% INPUT - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse expect(grammar.terms.sort_by(&:number)).to eq([ Sym.new(id: T.new(type: T::Ident, s_value: "EOI"), alias_name: "\"EOI\"", number: 0, tag: nil, term: true, token_id: 0, nullable: false, precedence: nil), @@ -661,7 +661,7 @@ class : keyword_class { code 1 } tSTRING { code 2 } keyword_end { code 3 } %% INPUT - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse expect(grammar.nterms.sort_by(&:number)).to eq([ Sym.new(id: T.new(type: T::Ident, s_value: "$accept"), alias_name: nil, number: 11, tag: nil, term: false, token_id: 0, nullable: false), @@ -756,7 +756,7 @@ class : keyword_class tSTRING %prec tPLUS keyword_end { code 1 } %% INPUT - parser = Lrama::NewParser.new(y, nil) + parser = Lrama::NewParser.new(y) expect { parser.parse }.to raise_error("Ident after %prec") end @@ -773,7 +773,7 @@ class : keyword_class { code 2 } tSTRING %prec "=" '!' keyword_end { code 3 } %% INPUT - parser = Lrama::NewParser.new(y, nil) + parser = Lrama::NewParser.new(y) expect { parser.parse }.to raise_error("Char after %prec") end @@ -790,7 +790,7 @@ class : keyword_class { code 4 } tSTRING '?' keyword_end %prec tEQ { code 5 } { %% INPUT - parser = Lrama::NewParser.new(y, nil) + parser = Lrama::NewParser.new(y) expect { parser.parse }.to raise_error("Multiple User_code after %prec") end @@ -811,7 +811,7 @@ class : keyword_class %% INPUT - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse codes = grammar.rules.map(&:code).compact expect(codes.count).to eq(1) @@ -838,7 +838,7 @@ class : keyword_class %% INPUT - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse codes = grammar.rules.map(&:code).compact expect(codes.count).to eq(1) @@ -883,7 +883,7 @@ class : keyword_class tSTRING keyword_end { code 1 } %% INPUT - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse expect(grammar.terms.sort_by(&:number)).to eq([ Sym.new(id: T.new(type: T::Ident, s_value: "EOI"), alias_name: "\"EOI\"", number: 0, tag: nil, term: true, token_id: 0, nullable: false), @@ -932,7 +932,7 @@ class : keyword_class tSTRING keyword_end { code 1 } %% INPUT - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse expect(grammar.terms.sort_by(&:number)).to eq([ Sym.new(id: T.new(type: T::Ident, s_value: "EOI"), alias_name: "\"EOI\"", number: 0, tag: nil, term: true, token_id: 0, nullable: false, precedence: nil), @@ -978,7 +978,7 @@ class : keyword_class tSTRING keyword_end { code 1 } ; %% INPUT - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse expect(grammar.rules).to eq([ Rule.new( @@ -1086,7 +1086,7 @@ class : keyword_class tSTRING keyword_end { code 1 } ; %% INPUT - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse expect(grammar.rules).to eq([ Rule.new( @@ -1177,7 +1177,7 @@ class : keyword_class tSTRING keyword_end { code 1 } { $$ = $1 - $2; } ; INPUT - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse expect(grammar.rules).to eq([ Rule.new( @@ -1311,7 +1311,7 @@ class : keyword_class tSTRING keyword_end { code 1 } ; INPUT - expect { Lrama::NewParser.new(y, nil).parse }.to raise_error("'results' is invalid name.") + expect { Lrama::NewParser.new(y).parse }.to raise_error("'results' is invalid name.") end end end @@ -1348,7 +1348,7 @@ class : keyword_class tSTRING keyword_end ; %% INPUT - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse terms = grammar.terms.sort_by(&:number).map do |term| [term.id.s_value, term.token_id] end @@ -1397,7 +1397,7 @@ class : keyword_class tSTRING keyword_end %% INPUT - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse codes = grammar.rules.map(&:code) expect(codes.count).to eq(3) @@ -1444,7 +1444,7 @@ class : keyword_class tSTRING keyword_end %% INPUT - expect { Lrama::NewParser.new(y, nil).parse }.to raise_error(RuntimeError) do |e| + expect { Lrama::NewParser.new(y).parse }.to raise_error(RuntimeError) do |e| expect(e.message).to eq(<<~MSG.chomp) $$ of 'stmt' has no declared type $1 of 'stmt' has no declared type diff --git a/spec/lrama/states_spec.rb b/spec/lrama/states_spec.rb index 43f910ad..4ac84c38 100644 --- a/spec/lrama/states_spec.rb +++ b/spec/lrama/states_spec.rb @@ -5,7 +5,7 @@ describe '#compute' do it "basic" do y = File.read(fixture_path("common/basic.y")) - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse states = Lrama::States.new(grammar, warning) states.compute @@ -298,7 +298,7 @@ class go to state 5 it '#State#accessing_symbol' do y = File.read(fixture_path("common/basic.y")) - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse states = Lrama::States.new(grammar, warning) states.compute @@ -338,7 +338,7 @@ class go to state 5 describe '#reads_relation' do it do y = File.read(fixture_path("states/reads_relation.y")) - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse states = Lrama::States.new(grammar, warning) states.compute @@ -605,7 +605,7 @@ class go to state 5 describe '#includes_relation' do it do y = File.read(fixture_path("states/includes_relation.y")) - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse states = Lrama::States.new(grammar, warning) states.compute @@ -904,7 +904,7 @@ class go to state 5 %% INPUT - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse states = Lrama::States.new(grammar, warning) states.compute @@ -973,7 +973,7 @@ class go to state 5 %% INPUT - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse states = Lrama::States.new(grammar, warning) states.compute @@ -1063,7 +1063,7 @@ class go to state 5 %% INPUT - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse states = Lrama::States.new(grammar, warning) states.compute @@ -1180,7 +1180,7 @@ class go to state 5 %% INPUT - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse states = Lrama::States.new(grammar, warning) states.compute @@ -1426,7 +1426,7 @@ class go to state 5 %% INPUT - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse states = Lrama::States.new(grammar, warning) states.compute @@ -1598,7 +1598,7 @@ class go to state 5 %% INPUT - grammar = Lrama::NewParser.new(y, nil).parse + grammar = Lrama::NewParser.new(y).parse states = Lrama::States.new(grammar, warning) states.compute @@ -1816,7 +1816,7 @@ class : keyword_class tSTRING keyword_end %prec tPLUS end it "has errors for r/r conflicts" do - grammar = Lrama::NewParser.new(header + y, nil).parse + grammar = Lrama::NewParser.new(header + y).parse states = Lrama::States.new(grammar, warning) states.compute @@ -1840,7 +1840,7 @@ class : keyword_class tSTRING keyword_end %prec tPLUS end it "has errors for s/r conflicts and r/r conflicts" do - grammar = Lrama::NewParser.new(header + y, nil).parse + grammar = Lrama::NewParser.new(header + y).parse states = Lrama::States.new(grammar, warning) states.compute @@ -1864,7 +1864,7 @@ class : keyword_class tSTRING keyword_end %prec tPLUS end it "has warns for s/r conflicts and r/r conflicts" do - grammar = Lrama::NewParser.new(header + y, nil).parse + grammar = Lrama::NewParser.new(header + y).parse states = Lrama::States.new(grammar, warning) states.compute diff --git a/template/bison/yacc.c b/template/bison/yacc.c index 8f57984e..06a13ac1 100644 --- a/template/bison/yacc.c +++ b/template/bison/yacc.c @@ -101,8 +101,12 @@ # endif <%# b4_header_include_if -%> +<%- if output.include_header -%> +#include "<%= output.include_header %>" +<%- else -%> /* Use api.header.include to #include this header instead of duplicating it here. */ +<%- end -%> <%# b4_shared_declarations -%> <%-# b4_cpp_guard_open([b4_spec_mapped_header_file]) -%> <%- if output.spec_mapped_header_file -%>