summaryrefslogtreecommitdiff
path: root/tool/lrama/lib/lrama/output.rb
diff options
context:
space:
mode:
Diffstat (limited to 'tool/lrama/lib/lrama/output.rb')
-rw-r--r--tool/lrama/lib/lrama/output.rb160
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