diff options
Diffstat (limited to 'tool/lrama/lib/lrama/output.rb')
-rw-r--r-- | tool/lrama/lib/lrama/output.rb | 160 |
1 files changed, 141 insertions, 19 deletions
diff --git a/tool/lrama/lib/lrama/output.rb b/tool/lrama/lib/lrama/output.rb index 696aa79feb..642c8b4708 100644 --- a/tool/lrama/lib/lrama/output.rb +++ b/tool/lrama/lib/lrama/output.rb @@ -1,20 +1,23 @@ require "erb" require "forwardable" -require "lrama/report" +require "lrama/report/duration" module Lrama class Output extend Forwardable include Report::Duration - attr_reader :grammar_file_path, :context, :grammar + 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 def_delegators "@grammar", :eof_symbol, :error_symbol, :undef_symbol, :accept_symbol - def initialize(out:, output_file_path:, template_name:, grammar_file_path:, header_out: nil, header_file_path: nil, context:, grammar:) + def initialize( + out:, output_file_path:, template_name:, grammar_file_path:, + context:, grammar:, header_out: nil, header_file_path: nil, error_recovery: false + ) @out = out @output_file_path = output_file_path @template_name = template_name @@ -23,6 +26,8 @@ module Lrama @header_file_path = header_file_path @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 @@ -35,11 +40,8 @@ module Lrama end end - def eval_template(file, path) - erb = self.class.erb(File.read(file)) - erb.filename = file - tmp = erb.result_with_hash(context: @context, output: self) - replace_special_variables(tmp, path) + def render_partial(file) + render_template(partial_file(file)) end def render @@ -98,6 +100,10 @@ module Lrama int_array_to_string(@context.yytranslate) end + def yytranslate_inverted + int_array_to_string(@context.yytranslate_inverted) + end + def yyrline int_array_to_string(@context.yyrline) end @@ -134,7 +140,26 @@ module Lrama str << <<-STR case #{sym.enum_name}: /* #{sym.comment} */ #line #{sym.printer.lineno} "#{@grammar_file_path}" - #{sym.printer.translated_code(sym.tag)} + {#{sym.printer.translated_code(sym.tag)}} +#line [@oline@] [@ofile@] + break; + + STR + end + + str + end + + def symbol_actions_for_destructor + str = "" + + @grammar.symbols.each do |sym| + next unless sym.destructor + + str << <<-STR + case #{sym.enum_name}: /* #{sym.comment} */ +#line #{sym.destructor.lineno} "#{@grammar_file_path}" + {#{sym.destructor.translated_code(sym.tag)}} #line [@oline@] [@ofile@] break; @@ -151,25 +176,98 @@ module Lrama <<-STR #{comment} #line #{@grammar.initial_action.line} "#{@grammar_file_path}" - #{@grammar.initial_action.translated_code} + {#{@grammar.initial_action.translated_code}} + STR + end + + def after_shift_function(comment = "") + return "" unless @grammar.after_shift + + <<-STR + #{comment} +#line #{@grammar.after_shift.line} "#{@grammar_file_path}" + {#{@grammar.after_shift.s_value}(#{parse_param_name});} +#line [@oline@] [@ofile@] + STR + end + + def before_reduce_function(comment = "") + return "" unless @grammar.before_reduce + + <<-STR + #{comment} +#line #{@grammar.before_reduce.line} "#{@grammar_file_path}" + {#{@grammar.before_reduce.s_value}(yylen#{user_args});} +#line [@oline@] [@ofile@] + STR + end + + def after_reduce_function(comment = "") + return "" unless @grammar.after_reduce + + <<-STR + #{comment} +#line #{@grammar.after_reduce.line} "#{@grammar_file_path}" + {#{@grammar.after_reduce.s_value}(yylen#{user_args});} +#line [@oline@] [@ofile@] STR end + def after_shift_error_token_function(comment = "") + return "" unless @grammar.after_shift_error_token + + <<-STR + #{comment} +#line #{@grammar.after_shift_error_token.line} "#{@grammar_file_path}" + {#{@grammar.after_shift_error_token.s_value}(#{parse_param_name});} +#line [@oline@] [@ofile@] + STR + end + + def after_pop_stack_function(len, comment = "") + return "" unless @grammar.after_pop_stack + + <<-STR + #{comment} +#line #{@grammar.after_pop_stack.line} "#{@grammar_file_path}" + {#{@grammar.after_pop_stack.s_value}(#{len}#{user_args});} +#line [@oline@] [@ofile@] + STR + end + + def symbol_actions_for_error_token + str = "" + + @grammar.symbols.each do |sym| + next unless sym.error_token + + str << <<-STR + case #{sym.enum_name}: /* #{sym.comment} */ +#line #{sym.error_token.lineno} "#{@grammar_file_path}" + {#{sym.error_token.translated_code(sym.tag)}} +#line [@oline@] [@ofile@] + break; + + STR + end + + str + end + # b4_user_actions def user_actions str = "" @context.states.rules.each do |rule| - next unless rule.code + next unless rule.token_code - rule = rule - code = rule.code + code = rule.token_code spaces = " " * (code.column - 1) str << <<-STR case #{rule.id + 1}: /* #{rule.as_comment} */ #line #{code.line} "#{@grammar_file_path}" -#{spaces}#{rule.translated_code} +#{spaces}{#{rule.translated_code}} #line [@oline@] [@ofile@] break; @@ -184,14 +282,14 @@ module Lrama str end - def omit_braces_and_blanks(param) - param[1..-2].strip + def omit_blanks(param) + param.strip end # b4_parse_param def parse_param if @grammar.parse_param - omit_braces_and_blanks(@grammar.parse_param) + omit_blanks(@grammar.parse_param) else "" end @@ -199,7 +297,7 @@ module Lrama def lex_param if @grammar.lex_param - omit_braces_and_blanks(@grammar.lex_param) + omit_blanks(@grammar.lex_param) else "" end @@ -224,7 +322,7 @@ module Lrama end def extract_param_name(param) - /\A(.)+([a-zA-Z0-9_]+)\z/.match(param)[2] + param[/\b([a-zA-Z0-9_]+)(?=\s*\z)/] end def parse_param_name @@ -324,8 +422,28 @@ module Lrama end end + # b4_percent_code_get + def percent_code(name) + @grammar.percent_codes.select do |percent_code| + percent_code.name == name + end.map do |percent_code| + percent_code.code + end.join + end + private + def eval_template(file, path) + tmp = render_template(file) + replace_special_variables(tmp, path) + end + + def render_template(file) + erb = self.class.erb(File.read(file)) + erb.filename = file + erb.result_with_hash(context: @context, output: self) + end + def template_file File.join(template_dir, @template_name) end @@ -334,6 +452,10 @@ module Lrama File.join(template_dir, "bison/yacc.h") end + def partial_file(file) + File.join(template_dir, file) + end + def template_dir File.expand_path("../../../template", __FILE__) end |