From 885cf350de4c80a918a33da109d0462711ac5e49 Mon Sep 17 00:00:00 2001 From: ydah Date: Wed, 11 Sep 2024 18:32:50 +0900 Subject: [PATCH] Lrama v0.6.10 --- tool/lrama/NEWS.md | 220 +++ tool/lrama/exe/lrama | 1 + tool/lrama/lib/lrama.rb | 39 +- tool/lrama/lib/lrama/bitmap.rb | 2 + tool/lrama/lib/lrama/command.rb | 22 +- tool/lrama/lib/lrama/context.rb | 14 +- tool/lrama/lib/lrama/counterexamples.rb | 32 +- .../lib/lrama/counterexamples/derivation.rb | 2 + .../lib/lrama/counterexamples/example.rb | 2 + tool/lrama/lib/lrama/counterexamples/path.rb | 2 + .../lrama/counterexamples/production_path.rb | 2 + .../lib/lrama/counterexamples/start_path.rb | 2 + .../lib/lrama/counterexamples/state_item.rb | 2 + .../lrama/counterexamples/transition_path.rb | 2 + .../lrama/lib/lrama/counterexamples/triple.rb | 2 + tool/lrama/lib/lrama/diagnostics.rb | 36 + tool/lrama/lib/lrama/digraph.rb | 2 + tool/lrama/lib/lrama/grammar.rb | 81 +- tool/lrama/lib/lrama/grammar/auxiliary.rb | 2 + tool/lrama/lib/lrama/grammar/binding.rb | 13 +- tool/lrama/lib/lrama/grammar/code.rb | 12 +- .../lib/lrama/grammar/code/destructor_code.rb | 2 + .../lrama/grammar/code/initial_action_code.rb | 2 + .../lrama/grammar/code/no_reference_code.rb | 2 + .../lib/lrama/grammar/code/printer_code.rb | 2 + .../lib/lrama/grammar/code/rule_action.rb | 10 +- tool/lrama/lib/lrama/grammar/counter.rb | 2 + tool/lrama/lib/lrama/grammar/destructor.rb | 2 + tool/lrama/lib/lrama/grammar/error_token.rb | 2 + .../lib/lrama/grammar/parameterizing_rule.rb | 2 + .../grammar/parameterizing_rule/resolver.rb | 8 +- .../lrama/grammar/parameterizing_rule/rhs.rb | 7 +- .../lrama/grammar/parameterizing_rule/rule.rb | 6 + tool/lrama/lib/lrama/grammar/percent_code.rb | 2 + tool/lrama/lib/lrama/grammar/precedence.rb | 2 + tool/lrama/lib/lrama/grammar/printer.rb | 2 + tool/lrama/lib/lrama/grammar/reference.rb | 2 + tool/lrama/lib/lrama/grammar/rule.rb | 13 +- tool/lrama/lib/lrama/grammar/rule_builder.rb | 129 +- tool/lrama/lib/lrama/grammar/symbol.rb | 2 + tool/lrama/lib/lrama/grammar/symbols.rb | 2 + .../lib/lrama/grammar/symbols/resolver.rb | 6 +- tool/lrama/lib/lrama/grammar/type.rb | 2 + tool/lrama/lib/lrama/grammar/union.rb | 2 + tool/lrama/lib/lrama/grammar_validator.rb | 37 + tool/lrama/lib/lrama/lexer.rb | 19 +- tool/lrama/lib/lrama/lexer/grammar_file.rb | 2 + tool/lrama/lib/lrama/lexer/location.rb | 2 + tool/lrama/lib/lrama/lexer/token.rb | 12 +- tool/lrama/lib/lrama/lexer/token/char.rb | 2 + tool/lrama/lib/lrama/lexer/token/ident.rb | 2 + .../lib/lrama/lexer/token/instantiate_rule.rb | 2 + tool/lrama/lib/lrama/lexer/token/tag.rb | 2 + tool/lrama/lib/lrama/lexer/token/user_code.rb | 4 +- tool/lrama/lib/lrama/logger.rb | 17 + tool/lrama/lib/lrama/option_parser.rb | 91 +- tool/lrama/lib/lrama/options.rb | 7 +- tool/lrama/lib/lrama/output.rb | 107 +- tool/lrama/lib/lrama/parser.rb | 1539 ++++++++--------- tool/lrama/lib/lrama/report.rb | 6 +- tool/lrama/lib/lrama/report/duration.rb | 2 + tool/lrama/lib/lrama/report/profile.rb | 2 + tool/lrama/lib/lrama/state.rb | 12 +- tool/lrama/lib/lrama/state/reduce.rb | 3 + .../lib/lrama/state/reduce_reduce_conflict.rb | 2 + .../lib/lrama/state/resolved_conflict.rb | 4 +- tool/lrama/lib/lrama/state/shift.rb | 2 + .../lib/lrama/state/shift_reduce_conflict.rb | 2 + tool/lrama/lib/lrama/states.rb | 68 +- tool/lrama/lib/lrama/states/item.rb | 8 +- tool/lrama/lib/lrama/states_reporter.rb | 79 +- tool/lrama/lib/lrama/trace_reporter.rb | 30 + tool/lrama/lib/lrama/version.rb | 4 +- tool/lrama/template/bison/yacc.c | 43 +- 74 files changed, 1602 insertions(+), 1213 deletions(-) create mode 100644 tool/lrama/lib/lrama/diagnostics.rb create mode 100644 tool/lrama/lib/lrama/grammar_validator.rb create mode 100644 tool/lrama/lib/lrama/logger.rb create mode 100644 tool/lrama/lib/lrama/trace_reporter.rb diff --git a/tool/lrama/NEWS.md b/tool/lrama/NEWS.md index 96aaaf94f5..0e682b4676 100644 --- a/tool/lrama/NEWS.md +++ b/tool/lrama/NEWS.md @@ -1,5 +1,225 @@ # NEWS for Lrama +## Lrama 0.6.10 (2024-09-11) + +### Aliased Named References for actions of RHS in parameterizing rules + +Allow to use aliased named references for actions of RHS in parameterizing rules. + +``` +%rule sum(X, Y): X[summand] '+' Y[addend] { $$ = $summand + $addend } + ; +``` + +https://github.com/ruby/lrama/pull/410 + + +### Named References for actions of RHS in parameterizing rules caller side + +Allow to use named references for actions of RHS in parameterizing rules caller side. + +``` +opt_nl: '\n'?[nl] { $$ = $nl; } + ; +``` + +https://github.com/ruby/lrama/pull/414 + +### Widen the definable position of parameterizing rules + +Allow to define parameterizing rules in the middle of the grammar. + +``` +%rule defined_option(X): /* empty */ + | X + ; + +%% + +program : defined_option(number) + | defined_list(number) + ; + +%rule defined_list(X): /* empty */ /* <--- here */ + | defined_list(X) number + ; +``` + +https://github.com/ruby/lrama/pull/420 + +### Report unused terminal symbols + +Support to report unused terminal symbols. +Run `exe/lrama --report=terms` to show unused terminal symbols. + +``` +❯ exe/lrama --report=terms sample/calc.y + 11 Unused Terms + 0 YYerror + 1 YYUNDEF + 2 '\\\\' + 3 '\\13' + 4 keyword_class2 + 5 tNUMBER + 6 tPLUS + 7 tMINUS + 8 tEQ + 9 tEQEQ + 10 '>' +``` +https://github.com/ruby/lrama/pull/439 + +### Report unused rules + +Support to report unused rules. +Run `exe/lrama --report=rules` to show unused rules. + +``` +❯ exe/lrama --report=rules sample/calc.y + 3 Unused Rules + 0 unused_option + 1 unused_list + 2 unused_nonempty_list +``` + +https://github.com/ruby/lrama/pull/441 + +### Ensure compatibility with Bison for `%locations` directive + +Support `%locations` directive to ensure compatibility with Bison. +Change to `%locations` directive not set by default. + +https://github.com/ruby/lrama/pull/446 + +### Diagnostics report for parameterizing rules redefine + +Support to warning redefined parameterizing rules. +Run `exe/lrama -W` or `exe/lrama --warnings` to show redefined parameterizing rules. + +``` +❯ exe/lrama -W sample/calc.y +parameterizing rule redefined: redefined_method(X) +parameterizing rule redefined: redefined_method(X) +``` + +https://github.com/ruby/lrama/pull/448 + +### Support `-v` and `--verbose` option + +Support to `-v` and `--verbose` option. +These options align with Bison behavior. So same as '--report=state' option. + +https://github.com/ruby/lrama/pull/457 + +## Lrama 0.6.9 (2024-05-02) + +### Callee side tag specification of parameterizing rules + +Allow to specify tag on callee side of parameterizing rules. + +``` +%union { + int i; +} + +%rule with_tag(X) : X { $$ = $1; } + ; +``` + +### Named References for actions of RHS in parameterizing rules + +Allow to use named references for actions of RHS in parameterizing rules. + +``` +%rule option(number): /* empty */ + | number { $$ = $number; } + ; +``` + +## Lrama 0.6.8 (2024-04-29) + +### Nested parameterizing rules with tag + +Allow to nested parameterizing rules with tag. + +``` +%union { + int i; +} + +%rule nested_nested_option(X): /* empty */ + | X + ; + +%rule nested_option(X): /* empty */ + | nested_nested_option(X) + ; + +%rule option(Y): /* empty */ + | nested_option(Y) + ; +``` + +## Lrama 0.6.7 (2024-04-28) + +### RHS of user defined parameterizing rules contains `'symbol'?`, `'symbol'+` and `'symbol'*`. + +User can use `'symbol'?`, `'symbol'+` and `'symbol'*` in RHS of user defined parameterizing rules. + +``` +%rule with_word_seps(X): /* empty */ + | X ' '+ + ; +``` + +## Lrama 0.6.6 (2024-04-27) + +### Trace actions + +Support trace actions for debugging. +Run `exe/lrama --trace=actions` to show grammar rules with actions. + +``` +❯ exe/lrama --trace=actions sample/calc.y +Grammar rules with actions: +$accept -> list, YYEOF {} +list -> ε {} +list -> list, LF {} +list -> list, expr, LF { printf("=> %d\n", $2); } +expr -> NUM {} +expr -> expr, '+', expr { $$ = $1 + $3; } +expr -> expr, '-', expr { $$ = $1 - $3; } +expr -> expr, '*', expr { $$ = $1 * $3; } +expr -> expr, '/', expr { $$ = $1 / $3; } +expr -> '(', expr, ')' { $$ = $2; } +``` + +### Inlining + +Support inlining for rules. +The `%inline` directive causes all references to symbols to be replaced with its definition. + +``` +%rule %inline op: PLUS { + } + | TIMES { * } + ; + +%% + +expr : number { $$ = $1; } + | expr op expr { $$ = $1 $2 $3; } + ; +``` + +as same as + +``` +expr : number { $$ = $1; } + | expr '+' expr { $$ = $1 + $3; } + | expr '*' expr { $$ = $1 * $3; } + ; +``` + ## Lrama 0.6.5 (2024-03-25) ### Typed Midrule Actions diff --git a/tool/lrama/exe/lrama b/tool/lrama/exe/lrama index ba5fb06c82..1aece5d141 100755 --- a/tool/lrama/exe/lrama +++ b/tool/lrama/exe/lrama @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +# frozen_string_literal: true $LOAD_PATH << File.join(__dir__, "../lib") require "lrama" diff --git a/tool/lrama/lib/lrama.rb b/tool/lrama/lib/lrama.rb index 9e517b0d71..fe2e05807c 100644 --- a/tool/lrama/lib/lrama.rb +++ b/tool/lrama/lib/lrama.rb @@ -1,17 +1,22 @@ -require "lrama/bitmap" -require "lrama/command" -require "lrama/context" -require "lrama/counterexamples" -require "lrama/digraph" -require "lrama/grammar" -require "lrama/lexer" -require "lrama/option_parser" -require "lrama/options" -require "lrama/output" -require "lrama/parser" -require "lrama/report" -require "lrama/state" -require "lrama/states" -require "lrama/states_reporter" -require "lrama/version" -require "lrama/warning" +# frozen_string_literal: true + +require_relative "lrama/bitmap" +require_relative "lrama/command" +require_relative "lrama/context" +require_relative "lrama/counterexamples" +require_relative "lrama/diagnostics" +require_relative "lrama/digraph" +require_relative "lrama/grammar" +require_relative "lrama/grammar_validator" +require_relative "lrama/lexer" +require_relative "lrama/logger" +require_relative "lrama/option_parser" +require_relative "lrama/options" +require_relative "lrama/output" +require_relative "lrama/parser" +require_relative "lrama/report" +require_relative "lrama/state" +require_relative "lrama/states" +require_relative "lrama/states_reporter" +require_relative "lrama/trace_reporter" +require_relative "lrama/version" diff --git a/tool/lrama/lib/lrama/bitmap.rb b/tool/lrama/lib/lrama/bitmap.rb index 8349a23c34..23cbd30d4c 100644 --- a/tool/lrama/lib/lrama/bitmap.rb +++ b/tool/lrama/lib/lrama/bitmap.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama module Bitmap def self.from_array(ary) diff --git a/tool/lrama/lib/lrama/command.rb b/tool/lrama/lib/lrama/command.rb index 12fc4fc7ec..0095c1a119 100644 --- a/tool/lrama/lib/lrama/command.rb +++ b/tool/lrama/lib/lrama/command.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Command LRAMA_LIB = File.realpath(File.join(File.dirname(__FILE__))) @@ -14,7 +16,6 @@ module Lrama Report::Duration.enable if options.trace_opts[:time] - warning = Lrama::Warning.new text = options.y.read options.y.close if options.y != STDIN begin @@ -31,7 +32,7 @@ module Lrama message = message.gsub(/.+/, "\e[1m\\&\e[m") if Exception.to_tty? abort message end - states = Lrama::States.new(grammar, warning, trace_state: (options.trace_opts[:automaton] || options.trace_opts[:closure])) + states = Lrama::States.new(grammar, trace_state: (options.trace_opts[:automaton] || options.trace_opts[:closure])) states.compute context = Lrama::Context.new(states) @@ -42,15 +43,8 @@ module Lrama end end - if options.trace_opts && options.trace_opts[:rules] - puts "Grammar rules:" - puts grammar.rules - end - - if options.trace_opts && options.trace_opts[:actions] - puts "Grammar rules with actions:" - grammar.rules.each { |rule| puts rule.with_actions } - end + reporter = Lrama::TraceReporter.new(grammar) + reporter.report(**options.trace_opts) File.open(options.outfile, "w+") do |f| Lrama::Output.new( @@ -65,9 +59,9 @@ module Lrama ).render end - if warning.has_error? - exit false - end + logger = Lrama::Logger.new + exit false unless Lrama::GrammarValidator.new(grammar, states, logger).valid? + Lrama::Diagnostics.new(grammar, states, logger).run(options.diagnostic) end end end diff --git a/tool/lrama/lib/lrama/context.rb b/tool/lrama/lib/lrama/context.rb index 32017e65fc..4be2198860 100644 --- a/tool/lrama/lib/lrama/context.rb +++ b/tool/lrama/lib/lrama/context.rb @@ -1,4 +1,6 @@ -require "lrama/report/duration" +# frozen_string_literal: true + +require_relative "report/duration" module Lrama # This is passed to a template @@ -253,7 +255,7 @@ module Lrama # If no default_reduction_rule, default behavior is an # error then replace ErrorActionNumber with zero. - if !state.default_reduction_rule + unless state.default_reduction_rule actions.map! do |e| if e == ErrorActionNumber 0 @@ -301,10 +303,7 @@ module Lrama end @states.nterms.each do |nterm| - if !(states = nterm_to_next_states[nterm]) - default_goto = 0 - not_default_gotos = [] - else + if (states = nterm_to_next_states[nterm]) default_state = states.map(&:last).group_by {|s| s }.max_by {|_, v| v.count }.first default_goto = default_state.id not_default_gotos = [] @@ -312,6 +311,9 @@ module Lrama next if to_state.id == default_goto not_default_gotos << [from_state.id, to_state.id] end + else + default_goto = 0 + not_default_gotos = [] end k = nterm_number_to_sequence_number(nterm.number) diff --git a/tool/lrama/lib/lrama/counterexamples.rb b/tool/lrama/lib/lrama/counterexamples.rb index 046265da59..aaf2bb201f 100644 --- a/tool/lrama/lib/lrama/counterexamples.rb +++ b/tool/lrama/lib/lrama/counterexamples.rb @@ -1,13 +1,15 @@ +# frozen_string_literal: true + require "set" -require "lrama/counterexamples/derivation" -require "lrama/counterexamples/example" -require "lrama/counterexamples/path" -require "lrama/counterexamples/production_path" -require "lrama/counterexamples/start_path" -require "lrama/counterexamples/state_item" -require "lrama/counterexamples/transition_path" -require "lrama/counterexamples/triple" +require_relative "counterexamples/derivation" +require_relative "counterexamples/example" +require_relative "counterexamples/path" +require_relative "counterexamples/production_path" +require_relative "counterexamples/start_path" +require_relative "counterexamples/state_item" +require_relative "counterexamples/transition_path" +require_relative "counterexamples/triple" module Lrama # See: https://www.cs.cornell.edu/andru/papers/cupex/cupex.pdf @@ -171,7 +173,13 @@ module Lrama break end - if !si.item.beginning_of_rule? + if si.item.beginning_of_rule? + key = [si.state, si.item.lhs] + @reverse_productions[key].each do |item| + state_item = StateItem.new(si.state, item) + queue << (sis + [state_item]) + end + else key = [si, si.item.previous_sym] @reverse_transitions[key].each do |prev_target_state_item| next if prev_target_state_item.state != prev_state_item.state @@ -183,12 +191,6 @@ module Lrama queue.clear break end - else - key = [si.state, si.item.lhs] - @reverse_productions[key].each do |item| - state_item = StateItem.new(si.state, item) - queue << (sis + [state_item]) - end end end else diff --git a/tool/lrama/lib/lrama/counterexamples/derivation.rb b/tool/lrama/lib/lrama/counterexamples/derivation.rb index 691e935356..423e58b829 100644 --- a/tool/lrama/lib/lrama/counterexamples/derivation.rb +++ b/tool/lrama/lib/lrama/counterexamples/derivation.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Counterexamples class Derivation diff --git a/tool/lrama/lib/lrama/counterexamples/example.rb b/tool/lrama/lib/lrama/counterexamples/example.rb index 62244a77e0..8dda0d17d5 100644 --- a/tool/lrama/lib/lrama/counterexamples/example.rb +++ b/tool/lrama/lib/lrama/counterexamples/example.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Counterexamples class Example diff --git a/tool/lrama/lib/lrama/counterexamples/path.rb b/tool/lrama/lib/lrama/counterexamples/path.rb index edba67a3b6..243b6b4248 100644 --- a/tool/lrama/lib/lrama/counterexamples/path.rb +++ b/tool/lrama/lib/lrama/counterexamples/path.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Counterexamples class Path diff --git a/tool/lrama/lib/lrama/counterexamples/production_path.rb b/tool/lrama/lib/lrama/counterexamples/production_path.rb index d7db688518..0a230c7fce 100644 --- a/tool/lrama/lib/lrama/counterexamples/production_path.rb +++ b/tool/lrama/lib/lrama/counterexamples/production_path.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Counterexamples class ProductionPath < Path diff --git a/tool/lrama/lib/lrama/counterexamples/start_path.rb b/tool/lrama/lib/lrama/counterexamples/start_path.rb index 4a6821cd0f..c0351c8248 100644 --- a/tool/lrama/lib/lrama/counterexamples/start_path.rb +++ b/tool/lrama/lib/lrama/counterexamples/start_path.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Counterexamples class StartPath < Path diff --git a/tool/lrama/lib/lrama/counterexamples/state_item.rb b/tool/lrama/lib/lrama/counterexamples/state_item.rb index 930ff4a5f8..c919818324 100644 --- a/tool/lrama/lib/lrama/counterexamples/state_item.rb +++ b/tool/lrama/lib/lrama/counterexamples/state_item.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Counterexamples class StateItem < Struct.new(:state, :item) diff --git a/tool/lrama/lib/lrama/counterexamples/transition_path.rb b/tool/lrama/lib/lrama/counterexamples/transition_path.rb index 96e611612a..47bfbc4f98 100644 --- a/tool/lrama/lib/lrama/counterexamples/transition_path.rb +++ b/tool/lrama/lib/lrama/counterexamples/transition_path.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Counterexamples class TransitionPath < Path diff --git a/tool/lrama/lib/lrama/counterexamples/triple.rb b/tool/lrama/lib/lrama/counterexamples/triple.rb index e802beccf4..64014ee223 100644 --- a/tool/lrama/lib/lrama/counterexamples/triple.rb +++ b/tool/lrama/lib/lrama/counterexamples/triple.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Counterexamples # s: state diff --git a/tool/lrama/lib/lrama/diagnostics.rb b/tool/lrama/lib/lrama/diagnostics.rb new file mode 100644 index 0000000000..e9da398c89 --- /dev/null +++ b/tool/lrama/lib/lrama/diagnostics.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module Lrama + class Diagnostics + def initialize(grammar, states, logger) + @grammar = grammar + @states = states + @logger = logger + end + + def run(diagnostic) + if diagnostic + diagnose_conflict + diagnose_parameterizing_redefined + end + end + + private + + def diagnose_conflict + if @states.sr_conflicts_count != 0 + @logger.warn("shift/reduce conflicts: #{@states.sr_conflicts_count} found") + end + + if @states.rr_conflicts_count != 0 + @logger.warn("reduce/reduce conflicts: #{@states.rr_conflicts_count} found") + end + end + + def diagnose_parameterizing_redefined + @grammar.parameterizing_rule_resolver.redefined_rules.each do |rule| + @logger.warn("parameterizing rule redefined: #{rule}") + end + end + end +end diff --git a/tool/lrama/lib/lrama/digraph.rb b/tool/lrama/lib/lrama/digraph.rb index bbaa86019f..d2bb88101a 100644 --- a/tool/lrama/lib/lrama/digraph.rb +++ b/tool/lrama/lib/lrama/digraph.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama # Algorithm Digraph of https://dl.acm.org/doi/pdf/10.1145/69622.357187 (P. 625) class Digraph diff --git a/tool/lrama/lib/lrama/grammar.rb b/tool/lrama/lib/lrama/grammar.rb index a816b8261b..3724f828d7 100644 --- a/tool/lrama/lib/lrama/grammar.rb +++ b/tool/lrama/lib/lrama/grammar.rb @@ -1,43 +1,40 @@ +# frozen_string_literal: true + require "forwardable" -require "lrama/grammar/auxiliary" -require "lrama/grammar/binding" -require "lrama/grammar/code" -require "lrama/grammar/counter" -require "lrama/grammar/destructor" -require "lrama/grammar/error_token" -require "lrama/grammar/parameterizing_rule" -require "lrama/grammar/percent_code" -require "lrama/grammar/precedence" -require "lrama/grammar/printer" -require "lrama/grammar/reference" -require "lrama/grammar/rule" -require "lrama/grammar/rule_builder" -require "lrama/grammar/symbol" -require "lrama/grammar/symbols" -require "lrama/grammar/type" -require "lrama/grammar/union" -require "lrama/lexer" +require_relative "grammar/auxiliary" +require_relative "grammar/binding" +require_relative "grammar/code" +require_relative "grammar/counter" +require_relative "grammar/destructor" +require_relative "grammar/error_token" +require_relative "grammar/parameterizing_rule" +require_relative "grammar/percent_code" +require_relative "grammar/precedence" +require_relative "grammar/printer" +require_relative "grammar/reference" +require_relative "grammar/rule" +require_relative "grammar/rule_builder" +require_relative "grammar/symbol" +require_relative "grammar/symbols" +require_relative "grammar/type" +require_relative "grammar/union" +require_relative "lexer" module Lrama # Grammar is the result of parsing an input grammar file class Grammar extend Forwardable - attr_reader :percent_codes, :eof_symbol, :error_symbol, :undef_symbol, :accept_symbol, :aux - attr_accessor :union, :expect, - :printers, :error_tokens, - :lex_param, :parse_param, :initial_action, + attr_reader :percent_codes, :eof_symbol, :error_symbol, :undef_symbol, :accept_symbol, :aux, :parameterizing_rule_resolver + attr_accessor :union, :expect, :printers, :error_tokens, :lex_param, :parse_param, :initial_action, :after_shift, :before_reduce, :after_reduce, :after_shift_error_token, :after_pop_stack, - :symbols_resolver, :types, - :rules, :rule_builders, - :sym_to_rules, :no_stdlib + :symbols_resolver, :types, :rules, :rule_builders, :sym_to_rules, :no_stdlib, :locations def_delegators "@symbols_resolver", :symbols, :nterms, :terms, :add_nterm, :add_term, :find_symbol_by_number!, :find_symbol_by_id!, :token_to_symbol, :find_symbol_by_s_value!, :fill_symbol_number, :fill_nterm_type, :fill_printer, :fill_destructor, :fill_error_token, :sort_by_number! - def initialize(rule_counter) @rule_counter = rule_counter @@ -59,10 +56,15 @@ module Lrama @accept_symbol = nil @aux = Auxiliary.new @no_stdlib = false + @locations = false append_special_symbols end + def create_rule_builder(rule_counter, midrule_action_counter) + RuleBuilder.new(rule_counter, midrule_action_counter, @parameterizing_rule_resolver) + end + def add_percent_code(id:, code:) @percent_codes << PercentCode.new(id.s_value, code.s_value) end @@ -141,6 +143,7 @@ module Lrama end def prepare + resolve_inline_rules normalize_rules collect_symbols set_lhs_and_rhs @@ -149,6 +152,7 @@ module Lrama fill_sym_to_rules compute_nullable compute_first_set + set_locations end # TODO: More validation methods @@ -255,7 +259,7 @@ module Lrama def setup_rules @rule_builders.each do |builder| - builder.setup_rules(@parameterizing_rule_resolver) + builder.setup_rules end end @@ -289,10 +293,23 @@ module Lrama @accept_symbol = term end + def resolve_inline_rules + while @rule_builders.any? {|r| r.has_inline_rules? } do + @rule_builders = @rule_builders.flat_map do |builder| + if builder.has_inline_rules? + builder.resolve_inline_rules + else + builder + end + end + end + end + def normalize_rules # Add $accept rule to the top of rules - lineno = @rule_builders.first ? @rule_builders.first.line : 0 - @rules << Rule.new(id: @rule_counter.increment, _lhs: @accept_symbol.id, _rhs: [@rule_builders.first.lhs, @eof_symbol.id], token_code: nil, lineno: lineno) + rule_builder = @rule_builders.first # : RuleBuilder + lineno = rule_builder ? rule_builder.line : 0 + @rules << Rule.new(id: @rule_counter.increment, _lhs: @accept_symbol.id, _rhs: [rule_builder.lhs, @eof_symbol.id], token_code: nil, lineno: lineno) setup_rules @@ -370,12 +387,16 @@ module Lrama rules.each do |rule| next if rule.lhs.nterm? - errors << "[BUG] LHS of #{rule} (line: #{rule.lineno}) is term. It should be nterm." + errors << "[BUG] LHS of #{rule.display_name} (line: #{rule.lineno}) is term. It should be nterm." end return if errors.empty? raise errors.join("\n") end + + def set_locations + @locations = @locations || @rules.any? {|rule| rule.contains_at_reference? } + end end end diff --git a/tool/lrama/lib/lrama/grammar/auxiliary.rb b/tool/lrama/lib/lrama/grammar/auxiliary.rb index 933574b0f6..2bacee6f1a 100644 --- a/tool/lrama/lib/lrama/grammar/auxiliary.rb +++ b/tool/lrama/lib/lrama/grammar/auxiliary.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Grammar # Grammar file information not used by States but by Output diff --git a/tool/lrama/lib/lrama/grammar/binding.rb b/tool/lrama/lib/lrama/grammar/binding.rb index e5ea3fb037..5e6e7c594b 100644 --- a/tool/lrama/lib/lrama/grammar/binding.rb +++ b/tool/lrama/lib/lrama/grammar/binding.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Grammar class Binding @@ -16,9 +18,18 @@ module Lrama resolved_args = symbol.args.map { |arg| resolve_symbol(arg) } Lrama::Lexer::Token::InstantiateRule.new(s_value: symbol.s_value, location: symbol.location, args: resolved_args, lhs_tag: symbol.lhs_tag) else - @parameter_to_arg[symbol.s_value] || symbol + parameter_to_arg(symbol) || symbol end end + + private + + def parameter_to_arg(symbol) + if (arg = @parameter_to_arg[symbol.s_value].dup) + arg.alias_name = symbol.alias_name + end + arg + end end end end diff --git a/tool/lrama/lib/lrama/grammar/code.rb b/tool/lrama/lib/lrama/grammar/code.rb index 3bad599dae..b6c1cc49e7 100644 --- a/tool/lrama/lib/lrama/grammar/code.rb +++ b/tool/lrama/lib/lrama/grammar/code.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + require "forwardable" -require "lrama/grammar/code/destructor_code" -require "lrama/grammar/code/initial_action_code" -require "lrama/grammar/code/no_reference_code" -require "lrama/grammar/code/printer_code" -require "lrama/grammar/code/rule_action" +require_relative "code/destructor_code" +require_relative "code/initial_action_code" +require_relative "code/no_reference_code" +require_relative "code/printer_code" +require_relative "code/rule_action" module Lrama class Grammar diff --git a/tool/lrama/lib/lrama/grammar/code/destructor_code.rb b/tool/lrama/lib/lrama/grammar/code/destructor_code.rb index 70360eb90f..794017257c 100644 --- a/tool/lrama/lib/lrama/grammar/code/destructor_code.rb +++ b/tool/lrama/lib/lrama/grammar/code/destructor_code.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Grammar class Code diff --git a/tool/lrama/lib/lrama/grammar/code/initial_action_code.rb b/tool/lrama/lib/lrama/grammar/code/initial_action_code.rb index a694f193cb..02f2badc9e 100644 --- a/tool/lrama/lib/lrama/grammar/code/initial_action_code.rb +++ b/tool/lrama/lib/lrama/grammar/code/initial_action_code.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Grammar class Code diff --git a/tool/lrama/lib/lrama/grammar/code/no_reference_code.rb b/tool/lrama/lib/lrama/grammar/code/no_reference_code.rb index 6e614cc64a..ab12f32e29 100644 --- a/tool/lrama/lib/lrama/grammar/code/no_reference_code.rb +++ b/tool/lrama/lib/lrama/grammar/code/no_reference_code.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Grammar class Code diff --git a/tool/lrama/lib/lrama/grammar/code/printer_code.rb b/tool/lrama/lib/lrama/grammar/code/printer_code.rb index ffccd89395..c0b8d24306 100644 --- a/tool/lrama/lib/lrama/grammar/code/printer_code.rb +++ b/tool/lrama/lib/lrama/grammar/code/printer_code.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Grammar class Code diff --git a/tool/lrama/lib/lrama/grammar/code/rule_action.rb b/tool/lrama/lib/lrama/grammar/code/rule_action.rb index d3c0eab64a..363ecdf25d 100644 --- a/tool/lrama/lib/lrama/grammar/code/rule_action.rb +++ b/tool/lrama/lib/lrama/grammar/code/rule_action.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Grammar class Code @@ -41,6 +43,7 @@ module Lrama when ref.type == :dollar && ref.name == "$" # $$ tag = ref.ex_tag || lhs.tag raise_tag_not_found_error(ref) unless tag + # @type var tag: Lexer::Token::Tag "(yyval.#{tag.member})" when ref.type == :at && ref.name == "$" # @$ "(yyloc)" @@ -50,6 +53,7 @@ module Lrama i = -position_in_rhs + ref.index tag = ref.ex_tag || rhs[ref.index - 1].tag raise_tag_not_found_error(ref) unless tag + # @type var tag: Lexer::Token::Tag "(yyvsp[#{i}].#{tag.member})" when ref.type == :at # @n i = -position_in_rhs + ref.index @@ -69,18 +73,18 @@ module Lrama @rule.position_in_original_rule_rhs || @rule.rhs.count end - # If this is midrule action, RHS is a RHS of the original rule. + # If this is midrule action, RHS is an RHS of the original rule. def rhs (@rule.original_rule || @rule).rhs end - # Unlike `rhs`, LHS is always a LHS of the rule. + # Unlike `rhs`, LHS is always an LHS of the rule. def lhs @rule.lhs end def raise_tag_not_found_error(ref) - raise "Tag is not specified for '$#{ref.value}' in '#{@rule}'" + raise "Tag is not specified for '$#{ref.value}' in '#{@rule.display_name}'" end end end diff --git a/tool/lrama/lib/lrama/grammar/counter.rb b/tool/lrama/lib/lrama/grammar/counter.rb index c13f4ec3e3..dc91b87b71 100644 --- a/tool/lrama/lib/lrama/grammar/counter.rb +++ b/tool/lrama/lib/lrama/grammar/counter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Grammar class Counter diff --git a/tool/lrama/lib/lrama/grammar/destructor.rb b/tool/lrama/lib/lrama/grammar/destructor.rb index 4b7059e923..a2b6fde0ed 100644 --- a/tool/lrama/lib/lrama/grammar/destructor.rb +++ b/tool/lrama/lib/lrama/grammar/destructor.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Grammar class Destructor < Struct.new(:ident_or_tags, :token_code, :lineno, keyword_init: true) diff --git a/tool/lrama/lib/lrama/grammar/error_token.rb b/tool/lrama/lib/lrama/grammar/error_token.rb index 8efde7df33..50eaafeebc 100644 --- a/tool/lrama/lib/lrama/grammar/error_token.rb +++ b/tool/lrama/lib/lrama/grammar/error_token.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Grammar class ErrorToken < Struct.new(:ident_or_tags, :token_code, :lineno, keyword_init: true) diff --git a/tool/lrama/lib/lrama/grammar/parameterizing_rule.rb b/tool/lrama/lib/lrama/grammar/parameterizing_rule.rb index d371805f4b..ddc1a467ce 100644 --- a/tool/lrama/lib/lrama/grammar/parameterizing_rule.rb +++ b/tool/lrama/lib/lrama/grammar/parameterizing_rule.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative 'parameterizing_rule/resolver' require_relative 'parameterizing_rule/rhs' require_relative 'parameterizing_rule/rule' diff --git a/tool/lrama/lib/lrama/grammar/parameterizing_rule/resolver.rb b/tool/lrama/lib/lrama/grammar/parameterizing_rule/resolver.rb index d8f3ae7897..06f2f1cef7 100644 --- a/tool/lrama/lib/lrama/grammar/parameterizing_rule/resolver.rb +++ b/tool/lrama/lib/lrama/grammar/parameterizing_rule/resolver.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Grammar class ParameterizingRule @@ -18,13 +20,17 @@ module Lrama end def find_inline(token) - @rules.select { |rule| rule.name == token.s_value && rule.is_inline }.last + @rules.reverse.find { |rule| rule.name == token.s_value && rule.is_inline } end def created_lhs(lhs_s_value) @created_lhs_list.reverse.find { |created_lhs| created_lhs.s_value == lhs_s_value } end + def redefined_rules + @rules.select { |rule| @rules.count { |r| r.name == rule.name && r.required_parameters_count == rule.required_parameters_count } > 1 } + end + private def select_rules(rules, token) diff --git a/tool/lrama/lib/lrama/grammar/parameterizing_rule/rhs.rb b/tool/lrama/lib/lrama/grammar/parameterizing_rule/rhs.rb index 3eb92f8ef4..d574841d08 100644 --- a/tool/lrama/lib/lrama/grammar/parameterizing_rule/rhs.rb +++ b/tool/lrama/lib/lrama/grammar/parameterizing_rule/rhs.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Grammar class ParameterizingRule @@ -13,6 +15,7 @@ module Lrama def resolve_user_code(bindings) return unless user_code + resolved = Lexer::Token::UserCode.new(s_value: user_code.s_value, location: user_code.location) var_to_arg = {} symbols.each do |sym| resolved_sym = bindings.resolve_symbol(sym) @@ -22,14 +25,14 @@ module Lrama end var_to_arg.each do |var, arg| - user_code.references.each do |ref| + resolved.references.each do |ref| if ref.name == var ref.name = arg end end end - return user_code + return resolved end end end diff --git a/tool/lrama/lib/lrama/grammar/parameterizing_rule/rule.rb b/tool/lrama/lib/lrama/grammar/parameterizing_rule/rule.rb index 38f0fca4ea..cc200d2fb6 100644 --- a/tool/lrama/lib/lrama/grammar/parameterizing_rule/rule.rb +++ b/tool/lrama/lib/lrama/grammar/parameterizing_rule/rule.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Grammar class ParameterizingRule @@ -12,6 +14,10 @@ module Lrama @is_inline = is_inline @required_parameters_count = parameters.count end + + def to_s + "#{@name}(#{@parameters.map(&:s_value).join(', ')})" + end end end end diff --git a/tool/lrama/lib/lrama/grammar/percent_code.rb b/tool/lrama/lib/lrama/grammar/percent_code.rb index 8cbc5aef2c..416a2d2753 100644 --- a/tool/lrama/lib/lrama/grammar/percent_code.rb +++ b/tool/lrama/lib/lrama/grammar/percent_code.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Grammar class PercentCode diff --git a/tool/lrama/lib/lrama/grammar/precedence.rb b/tool/lrama/lib/lrama/grammar/precedence.rb index fed739b3c0..13cf960c32 100644 --- a/tool/lrama/lib/lrama/grammar/precedence.rb +++ b/tool/lrama/lib/lrama/grammar/precedence.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Grammar class Precedence < Struct.new(:type, :precedence, keyword_init: true) diff --git a/tool/lrama/lib/lrama/grammar/printer.rb b/tool/lrama/lib/lrama/grammar/printer.rb index 8984a96e1a..b78459e819 100644 --- a/tool/lrama/lib/lrama/grammar/printer.rb +++ b/tool/lrama/lib/lrama/grammar/printer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Grammar class Printer < Struct.new(:ident_or_tags, :token_code, :lineno, keyword_init: true) diff --git a/tool/lrama/lib/lrama/grammar/reference.rb b/tool/lrama/lib/lrama/grammar/reference.rb index c56e7673a6..b044516bdb 100644 --- a/tool/lrama/lib/lrama/grammar/reference.rb +++ b/tool/lrama/lib/lrama/grammar/reference.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Grammar # type: :dollar or :at diff --git a/tool/lrama/lib/lrama/grammar/rule.rb b/tool/lrama/lib/lrama/grammar/rule.rb index 0e06edc80d..1f55bf8bfb 100644 --- a/tool/lrama/lib/lrama/grammar/rule.rb +++ b/tool/lrama/lib/lrama/grammar/rule.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Grammar # _rhs holds original RHS element. Use rhs to refer to Symbol. @@ -16,8 +18,7 @@ module Lrama self.lineno == other.lineno end - # TODO: Change this to display_name - def to_s + def display_name l = lhs.id.s_value r = empty_rule? ? "ε" : rhs.map {|r| r.id.s_value }.join(" ") @@ -33,7 +34,7 @@ module Lrama end def with_actions - "#{to_s} {#{token_code&.s_value}}" + "#{display_name} {#{token_code&.s_value}}" end # opt_nl: ε <-- empty_rule @@ -55,6 +56,12 @@ module Lrama Code::RuleAction.new(type: :rule_action, token_code: token_code, rule: self).translated_code end + + def contains_at_reference? + return false unless token_code + + token_code.references.any? {|r| r.type == :at } + end end end end diff --git a/tool/lrama/lib/lrama/grammar/rule_builder.rb b/tool/lrama/lib/lrama/grammar/rule_builder.rb index ccb41e67f8..f6df22b6c7 100644 --- a/tool/lrama/lib/lrama/grammar/rule_builder.rb +++ b/tool/lrama/lib/lrama/grammar/rule_builder.rb @@ -1,12 +1,15 @@ +# frozen_string_literal: true + module Lrama class Grammar class RuleBuilder attr_accessor :lhs, :line attr_reader :lhs_tag, :rhs, :user_code, :precedence_sym - def initialize(rule_counter, midrule_action_counter, position_in_original_rule_rhs = nil, lhs_tag: nil, skip_preprocess_references: false) + def initialize(rule_counter, midrule_action_counter, parameterizing_rule_resolver, position_in_original_rule_rhs = nil, lhs_tag: nil, skip_preprocess_references: false) @rule_counter = rule_counter @midrule_action_counter = midrule_action_counter + @parameterizing_rule_resolver = parameterizing_rule_resolver @position_in_original_rule_rhs = position_in_original_rule_rhs @skip_preprocess_references = skip_preprocess_references @@ -19,16 +22,12 @@ module Lrama @rules = [] @rule_builders_for_parameterizing_rules = [] @rule_builders_for_derived_rules = [] - @rule_builders_for_inline_rules = [] @parameterizing_rules = [] - @inline_rules = [] @midrule_action_rules = [] end def add_rhs(rhs) - if !@line - @line = rhs.line - end + @line ||= rhs.line flush_user_code @@ -36,9 +35,7 @@ module Lrama end def user_code=(user_code) - if !@line - @line = user_code&.line - end + @line ||= user_code&.line flush_user_code @@ -55,18 +52,41 @@ module Lrama freeze_rhs end - def setup_rules(parameterizing_rule_resolver) + def setup_rules preprocess_references unless @skip_preprocess_references - if rhs.any? { |token| parameterizing_rule_resolver.find_inline(token) } - resolve_inline(parameterizing_rule_resolver) - else - process_rhs(parameterizing_rule_resolver) - end + process_rhs build_rules end def rules - @parameterizing_rules + @inline_rules + @midrule_action_rules + @rules + @parameterizing_rules + @midrule_action_rules + @rules + end + + def has_inline_rules? + rhs.any? { |token| @parameterizing_rule_resolver.find_inline(token) } + end + + def resolve_inline_rules + resolved_builders = [] + rhs.each_with_index do |token, i| + if (inline_rule = @parameterizing_rule_resolver.find_inline(token)) + inline_rule.rhs_list.each do |inline_rhs| + rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, @parameterizing_rule_resolver, lhs_tag: lhs_tag) + if token.is_a?(Lexer::Token::InstantiateRule) + resolve_inline_rhs(rule_builder, inline_rhs, i, Binding.new(inline_rule, token.args)) + else + resolve_inline_rhs(rule_builder, inline_rhs, i) + end + rule_builder.lhs = lhs + rule_builder.line = line + rule_builder.precedence_sym = precedence_sym + rule_builder.user_code = replace_inline_user_code(inline_rhs, i) + resolved_builders << rule_builder + end + break + end + end + resolved_builders end private @@ -82,31 +102,25 @@ module Lrama def build_rules tokens = @replaced_rhs - if tokens - rule = Rule.new( - id: @rule_counter.increment, _lhs: lhs, _rhs: tokens, lhs_tag: lhs_tag, token_code: user_code, - position_in_original_rule_rhs: @position_in_original_rule_rhs, precedence_sym: precedence_sym, lineno: line - ) - @rules = [rule] - @parameterizing_rules = @rule_builders_for_parameterizing_rules.map do |rule_builder| - rule_builder.rules - end.flatten - @midrule_action_rules = @rule_builders_for_derived_rules.map do |rule_builder| - rule_builder.rules - end.flatten - @midrule_action_rules.each do |r| - r.original_rule = rule - end - else - @inline_rules = @rule_builders_for_inline_rules.map do |rule_builder| - rule_builder.rules - end.flatten + rule = Rule.new( + id: @rule_counter.increment, _lhs: lhs, _rhs: tokens, lhs_tag: lhs_tag, token_code: user_code, + position_in_original_rule_rhs: @position_in_original_rule_rhs, precedence_sym: precedence_sym, lineno: line + ) + @rules = [rule] + @parameterizing_rules = @rule_builders_for_parameterizing_rules.map do |rule_builder| + rule_builder.rules + end.flatten + @midrule_action_rules = @rule_builders_for_derived_rules.map do |rule_builder| + rule_builder.rules + end.flatten + @midrule_action_rules.each do |r| + r.original_rule = rule end end # rhs is a mixture of variety type of tokens like `Ident`, `InstantiateRule`, `UserCode` and so on. # `#process_rhs` replaces some kind of tokens to `Ident` so that all `@replaced_rhs` are `Ident` or `Char`. - def process_rhs(parameterizing_rule_resolver) + def process_rhs return if @replaced_rhs @replaced_rhs = [] @@ -118,26 +132,26 @@ module Lrama when Lrama::Lexer::Token::Ident @replaced_rhs << token when Lrama::Lexer::Token::InstantiateRule - parameterizing_rule = parameterizing_rule_resolver.find_rule(token) + parameterizing_rule = @parameterizing_rule_resolver.find_rule(token) raise "Unexpected token. #{token}" unless parameterizing_rule bindings = Binding.new(parameterizing_rule, token.args) lhs_s_value = lhs_s_value(token, bindings) - if (created_lhs = parameterizing_rule_resolver.created_lhs(lhs_s_value)) + if (created_lhs = @parameterizing_rule_resolver.created_lhs(lhs_s_value)) @replaced_rhs << created_lhs else lhs_token = Lrama::Lexer::Token::Ident.new(s_value: lhs_s_value, location: token.location) @replaced_rhs << lhs_token - parameterizing_rule_resolver.created_lhs_list << lhs_token + @parameterizing_rule_resolver.created_lhs_list << lhs_token parameterizing_rule.rhs_list.each do |r| - rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, lhs_tag: token.lhs_tag || parameterizing_rule.tag) + rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, @parameterizing_rule_resolver, lhs_tag: token.lhs_tag || parameterizing_rule.tag) rule_builder.lhs = lhs_token r.symbols.each { |sym| rule_builder.add_rhs(bindings.resolve_symbol(sym)) } rule_builder.line = line rule_builder.precedence_sym = r.precedence_sym rule_builder.user_code = r.resolve_user_code(bindings) rule_builder.complete_input - rule_builder.setup_rules(parameterizing_rule_resolver) + rule_builder.setup_rules @rule_builders_for_parameterizing_rules << rule_builder end end @@ -147,11 +161,11 @@ module Lrama new_token = Lrama::Lexer::Token::Ident.new(s_value: prefix + @midrule_action_counter.increment.to_s) @replaced_rhs << new_token - rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, i, lhs_tag: tag, skip_preprocess_references: true) + rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, @parameterizing_rule_resolver, i, lhs_tag: tag, skip_preprocess_references: true) rule_builder.lhs = new_token rule_builder.user_code = token rule_builder.complete_input - rule_builder.setup_rules(parameterizing_rule_resolver) + rule_builder.setup_rules @rule_builders_for_derived_rules << rule_builder else @@ -172,27 +186,10 @@ module Lrama "#{token.rule_name}_#{s_values.join('_')}" end - def resolve_inline(parameterizing_rule_resolver) - rhs.each_with_index do |token, i| - if inline_rule = parameterizing_rule_resolver.find_inline(token) - inline_rule.rhs_list.each_with_index do |inline_rhs| - rule_builder = RuleBuilder.new(@rule_counter, @midrule_action_counter, lhs_tag: lhs_tag, skip_preprocess_references: true) - resolve_inline_rhs(rule_builder, inline_rhs, i) - rule_builder.lhs = lhs - rule_builder.line = line - rule_builder.user_code = replace_inline_user_code(inline_rhs, i) - rule_builder.complete_input - rule_builder.setup_rules(parameterizing_rule_resolver) - @rule_builders_for_inline_rules << rule_builder - end - end - end - end - - def resolve_inline_rhs(rule_builder, inline_rhs, index) + def resolve_inline_rhs(rule_builder, inline_rhs, index, bindings = nil) rhs.each_with_index do |token, i| if index == i - inline_rhs.symbols.each { |sym| rule_builder.add_rhs(sym) } + inline_rhs.symbols.each { |sym| rule_builder.add_rhs(bindings.nil? ? sym : bindings.resolve_symbol(sym)) } else rule_builder.add_rhs(token) end @@ -204,6 +201,11 @@ module Lrama return user_code if user_code.nil? code = user_code.s_value.gsub(/\$#{index + 1}/, inline_rhs.user_code.s_value) + user_code.references.each do |ref| + next if ref.index.nil? || ref.index <= index # nil is a case for `$$` + code = code.gsub(/\$#{ref.index}/, "$#{ref.index + (inline_rhs.symbols.count-1)}") + code = code.gsub(/@#{ref.index}/, "@#{ref.index + (inline_rhs.symbols.count-1)}") + end Lrama::Lexer::Token::UserCode.new(s_value: code, location: user_code.location) end @@ -238,9 +240,6 @@ module Lrama end if ref.number - # TODO: When Inlining is implemented, for example, if `$1` is expanded to multiple RHS tokens, - # `$2` needs to access `$2 + n` to actually access it. So, after the Inlining implementation, - # it needs resolves from number to index. ref.index = ref.number end diff --git a/tool/lrama/lib/lrama/grammar/symbol.rb b/tool/lrama/lib/lrama/grammar/symbol.rb index deb67ad9a8..f9dffcad6c 100644 --- a/tool/lrama/lib/lrama/grammar/symbol.rb +++ b/tool/lrama/lib/lrama/grammar/symbol.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Symbol is both of nterm and term # `number` is both for nterm and term # `token_id` is tokentype for term, internal sequence number for nterm diff --git a/tool/lrama/lib/lrama/grammar/symbols.rb b/tool/lrama/lib/lrama/grammar/symbols.rb index cc9b4ec559..337241d1b2 100644 --- a/tool/lrama/lib/lrama/grammar/symbols.rb +++ b/tool/lrama/lib/lrama/grammar/symbols.rb @@ -1 +1,3 @@ +# frozen_string_literal: true + require_relative "symbols/resolver" diff --git a/tool/lrama/lib/lrama/grammar/symbols/resolver.rb b/tool/lrama/lib/lrama/grammar/symbols/resolver.rb index 1788ed63fa..f245943ce1 100644 --- a/tool/lrama/lib/lrama/grammar/symbols/resolver.rb +++ b/tool/lrama/lib/lrama/grammar/symbols/resolver.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Grammar class Symbols @@ -42,7 +44,9 @@ module Lrama end def add_nterm(id:, alias_name: nil, tag: nil) - return if find_symbol_by_id(id) + if (sym = find_symbol_by_id(id)) + return sym + end @symbols = nil nterm = Symbol.new( diff --git a/tool/lrama/lib/lrama/grammar/type.rb b/tool/lrama/lib/lrama/grammar/type.rb index 6b4b0961a1..65537288b3 100644 --- a/tool/lrama/lib/lrama/grammar/type.rb +++ b/tool/lrama/lib/lrama/grammar/type.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Grammar class Type diff --git a/tool/lrama/lib/lrama/grammar/union.rb b/tool/lrama/lib/lrama/grammar/union.rb index 854bffb5c1..5f1bee0069 100644 --- a/tool/lrama/lib/lrama/grammar/union.rb +++ b/tool/lrama/lib/lrama/grammar/union.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Grammar class Union < Struct.new(:code, :lineno, keyword_init: true) diff --git a/tool/lrama/lib/lrama/grammar_validator.rb b/tool/lrama/lib/lrama/grammar_validator.rb new file mode 100644 index 0000000000..7790499589 --- /dev/null +++ b/tool/lrama/lib/lrama/grammar_validator.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module Lrama + class GrammarValidator + def initialize(grammar, states, logger) + @grammar = grammar + @states = states + @logger = logger + end + + def valid? + conflicts_within_threshold? + end + + private + + def conflicts_within_threshold? + return true unless @grammar.expect + + [sr_conflicts_within_threshold(@grammar.expect), rr_conflicts_within_threshold(0)].all? + end + + def sr_conflicts_within_threshold(expected) + return true if expected == @states.sr_conflicts_count + + @logger.error("shift/reduce conflicts: #{@states.sr_conflicts_count} found, #{expected} expected") + false + end + + def rr_conflicts_within_threshold(expected) + return true if expected == @states.rr_conflicts_count + + @logger.error("reduce/reduce conflicts: #{@states.rr_conflicts_count} found, #{expected} expected") + false + end + end +end diff --git a/tool/lrama/lib/lrama/lexer.rb b/tool/lrama/lib/lrama/lexer.rb index 40622a51b4..0a8f94334f 100644 --- a/tool/lrama/lib/lrama/lexer.rb +++ b/tool/lrama/lib/lrama/lexer.rb @@ -1,15 +1,17 @@ +# frozen_string_literal: true + require "strscan" -require "lrama/lexer/grammar_file" -require "lrama/lexer/location" -require "lrama/lexer/token" +require_relative "lexer/grammar_file" +require_relative "lexer/location" +require_relative "lexer/token" module Lrama class Lexer attr_reader :head_line, :head_column, :line attr_accessor :status, :end_symbol - SYMBOLS = ['%{', '%}', '%%', '{', '}', '\[', '\]', '\(', '\)', '\,', ':', '\|', ';'] + SYMBOLS = ['%{', '%}', '%%', '{', '}', '\[', '\]', '\(', '\)', '\,', ':', '\|', ';'].freeze PERCENT_TOKENS = %w( %union %token @@ -38,7 +40,8 @@ module Lrama %rule %no-stdlib %inline - ) + %locations + ).freeze def initialize(grammar_file) @grammar_file = grammar_file @@ -71,7 +74,7 @@ module Lrama end def lex_token - while !@scanner.eos? do + until @scanner.eos? do case when @scanner.scan(/\n/) newline @@ -126,7 +129,7 @@ module Lrama code = '' reset_first_position - while !@scanner.eos? do + until @scanner.eos? do case when @scanner.scan(/{/) code += @scanner.matched @@ -163,7 +166,7 @@ module Lrama private def lex_comment - while !@scanner.eos? do + until @scanner.eos? do case when @scanner.scan(/\n/) newline diff --git a/tool/lrama/lib/lrama/lexer/grammar_file.rb b/tool/lrama/lib/lrama/lexer/grammar_file.rb index 3d3368625d..45c3122975 100644 --- a/tool/lrama/lib/lrama/lexer/grammar_file.rb +++ b/tool/lrama/lib/lrama/lexer/grammar_file.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Lexer class GrammarFile diff --git a/tool/lrama/lib/lrama/lexer/location.rb b/tool/lrama/lib/lrama/lexer/location.rb index aefce3e16b..bf8f4f7e3e 100644 --- a/tool/lrama/lib/lrama/lexer/location.rb +++ b/tool/lrama/lib/lrama/lexer/location.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Lexer class Location diff --git a/tool/lrama/lib/lrama/lexer/token.rb b/tool/lrama/lib/lrama/lexer/token.rb index 59b49d5fba..45a097f682 100644 --- a/tool/lrama/lib/lrama/lexer/token.rb +++ b/tool/lrama/lib/lrama/lexer/token.rb @@ -1,8 +1,10 @@ -require 'lrama/lexer/token/char' -require 'lrama/lexer/token/ident' -require 'lrama/lexer/token/instantiate_rule' -require 'lrama/lexer/token/tag' -require 'lrama/lexer/token/user_code' +# frozen_string_literal: true + +require_relative 'token/char' +require_relative 'token/ident' +require_relative 'token/instantiate_rule' +require_relative 'token/tag' +require_relative 'token/user_code' module Lrama class Lexer diff --git a/tool/lrama/lib/lrama/lexer/token/char.rb b/tool/lrama/lib/lrama/lexer/token/char.rb index ec3560ca09..9e21952c42 100644 --- a/tool/lrama/lib/lrama/lexer/token/char.rb +++ b/tool/lrama/lib/lrama/lexer/token/char.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Lexer class Token diff --git a/tool/lrama/lib/lrama/lexer/token/ident.rb b/tool/lrama/lib/lrama/lexer/token/ident.rb index e576eaeccd..84835c00bc 100644 --- a/tool/lrama/lib/lrama/lexer/token/ident.rb +++ b/tool/lrama/lib/lrama/lexer/token/ident.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Lexer class Token diff --git a/tool/lrama/lib/lrama/lexer/token/instantiate_rule.rb b/tool/lrama/lib/lrama/lexer/token/instantiate_rule.rb index 1c4d1095c8..db7e611c5f 100644 --- a/tool/lrama/lib/lrama/lexer/token/instantiate_rule.rb +++ b/tool/lrama/lib/lrama/lexer/token/instantiate_rule.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Lexer class Token diff --git a/tool/lrama/lib/lrama/lexer/token/tag.rb b/tool/lrama/lib/lrama/lexer/token/tag.rb index e54d773915..52dcb50ce7 100644 --- a/tool/lrama/lib/lrama/lexer/token/tag.rb +++ b/tool/lrama/lib/lrama/lexer/token/tag.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Lexer class Token diff --git a/tool/lrama/lib/lrama/lexer/token/user_code.rb b/tool/lrama/lib/lrama/lexer/token/user_code.rb index 4d487bf01c..9712208642 100644 --- a/tool/lrama/lib/lrama/lexer/token/user_code.rb +++ b/tool/lrama/lib/lrama/lexer/token/user_code.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "strscan" module Lrama @@ -16,7 +18,7 @@ module Lrama scanner = StringScanner.new(s_value) references = [] - while !scanner.eos? do + until scanner.eos? do case when reference = scan_reference(scanner) references << reference diff --git a/tool/lrama/lib/lrama/logger.rb b/tool/lrama/lib/lrama/logger.rb new file mode 100644 index 0000000000..e98eef0fa5 --- /dev/null +++ b/tool/lrama/lib/lrama/logger.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Lrama + class Logger + def initialize(out = STDERR) + @out = out + end + + def warn(message) + @out << message << "\n" + end + + def error(message) + @out << message << "\n" + end + end +end diff --git a/tool/lrama/lib/lrama/option_parser.rb b/tool/lrama/lib/lrama/option_parser.rb index 1e4d448fd1..0727d1b37f 100644 --- a/tool/lrama/lib/lrama/option_parser.rb +++ b/tool/lrama/lib/lrama/option_parser.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'optparse' module Lrama @@ -16,7 +18,7 @@ module Lrama @options.report_opts = validate_report(@report) @options.grammar_file = argv.shift - if !@options.grammar_file + unless @options.grammar_file abort "File should be specified\n" end @@ -63,20 +65,35 @@ module Lrama 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('-r', '--report=REPORTS', Array, 'also produce details on the automaton') {|v| @report = v } o.on_tail '' - o.on_tail 'Valid Reports:' - o.on_tail " #{VALID_REPORTS.join(' ')}" - + o.on_tail 'REPORTS is a list of comma-separated words that can include:' + o.on_tail ' states describe the states' + o.on_tail ' itemsets complete the core item sets with their closure' + o.on_tail ' lookaheads explicitly associate lookahead tokens to items' + o.on_tail ' solved describe shift/reduce conflicts solving' + o.on_tail ' counterexamples, cex generate conflict counterexamples' + o.on_tail ' rules list unused rules' + o.on_tail ' terms list unused terminals' + o.on_tail ' verbose report detailed internal state and analysis results' + o.on_tail ' all include all the above reports' + o.on_tail ' none disable all reports' 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('--trace=TRACES', Array, 'also output trace logs at runtime') {|v| @trace = v } o.on_tail '' - o.on_tail 'Valid Traces:' - o.on_tail " #{VALID_TRACES.join(' ')}" - - o.on('-v', 'reserved, do nothing') { } + o.on_tail 'TRACES is a list of comma-separated words that can include:' + o.on_tail ' automaton display states' + o.on_tail ' closure display states' + o.on_tail ' rules display grammar rules' + o.on_tail ' actions display grammar rules with actions' + o.on_tail ' time display generation time' + o.on_tail ' all include all the above traces' + o.on_tail ' none disable all traces' + o.on('-v', '--verbose', "same as '--report=state'") {|_v| @report << 'states' } + o.separator '' + o.separator 'Diagnostics:' + o.on('-W', '--warnings', 'report the warnings') {|v| @options.diagnostic = true } o.separator '' o.separator 'Error Recovery:' o.on('-e', 'enable error recovery') {|v| @options.error_recovery = true } @@ -89,47 +106,55 @@ module Lrama end end - BISON_REPORTS = %w[states itemsets lookaheads solved counterexamples cex all none] - OTHER_REPORTS = %w[verbose] - NOT_SUPPORTED_REPORTS = %w[cex none] - VALID_REPORTS = BISON_REPORTS + OTHER_REPORTS - NOT_SUPPORTED_REPORTS + ALIASED_REPORTS = { cex: :counterexamples }.freeze + VALID_REPORTS = %i[states itemsets lookaheads solved counterexamples rules terms verbose].freeze def validate_report(report) - list = VALID_REPORTS h = { grammar: true } + return h if report.empty? + return {} if report == ['none'] + if report == ['all'] + VALID_REPORTS.each { |r| h[r] = true } + return h + end report.each do |r| - if list.include?(r) - h[r.to_sym] = true + aliased = aliased_report_option(r) + if VALID_REPORTS.include?(aliased) + h[aliased] = true else raise "Invalid report option \"#{r}\"." end end - if h[:all] - (BISON_REPORTS - NOT_SUPPORTED_REPORTS).each do |r| - h[r.to_sym] = true - end - - h.delete(:all) - end - return h end + def aliased_report_option(opt) + (ALIASED_REPORTS[opt.to_sym] || opt).to_sym + end + VALID_TRACES = %w[ - none locations scan parse automaton bitsets - closure grammar rules actions resource - sets muscles tools m4-early m4 skeleton time - ielr cex all - ] + locations scan parse automaton bitsets closure + grammar rules actions resource sets muscles + tools m4-early m4 skeleton time ielr cex + ].freeze + NOT_SUPPORTED_TRACES = %w[ + locations scan parse bitsets grammar resource + sets muscles tools m4-early m4 skeleton ielr cex + ].freeze def validate_trace(trace) - list = VALID_TRACES h = {} + return h if trace.empty? || trace == ['none'] + supported = VALID_TRACES - NOT_SUPPORTED_TRACES + if trace == ['all'] + supported.each { |t| h[t.to_sym] = true } + return h + end trace.each do |t| - if list.include?(t) + if supported.include?(t) h[t.to_sym] = true else raise "Invalid trace option \"#{t}\"." diff --git a/tool/lrama/lib/lrama/options.rb b/tool/lrama/lib/lrama/options.rb index 739ca16f55..ccd7680348 100644 --- a/tool/lrama/lib/lrama/options.rb +++ b/tool/lrama/lib/lrama/options.rb @@ -1,11 +1,13 @@ +# frozen_string_literal: true + module Lrama # Command line options. class Options attr_accessor :skeleton, :header, :header_file, :report_file, :outfile, :error_recovery, :grammar_file, - :trace_opts, :report_opts, :y, - :debug + :trace_opts, :report_opts, + :diagnostic, :y, :debug def initialize @skeleton = "bison/yacc.c" @@ -17,6 +19,7 @@ module Lrama @grammar_file = nil @trace_opts = nil @report_opts = nil + @diagnostic = false @y = STDIN @debug = false end diff --git a/tool/lrama/lib/lrama/output.rb b/tool/lrama/lib/lrama/output.rb index 642c8b4708..3c7316ac6d 100644 --- a/tool/lrama/lib/lrama/output.rb +++ b/tool/lrama/lib/lrama/output.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require "erb" require "forwardable" -require "lrama/report/duration" +require_relative "report/duration" module Lrama class Output @@ -63,37 +65,29 @@ module Lrama # A part of b4_token_enums def token_enums - str = "" - - @context.yytokentype.each do |s_value, token_id, display_name| + @context.yytokentype.map do |s_value, token_id, display_name| s = sprintf("%s = %d%s", s_value, token_id, token_id == yymaxutok ? "" : ",") if display_name - str << sprintf(" %-30s /* %s */\n", s, display_name) + sprintf(" %-30s /* %s */\n", s, display_name) else - str << sprintf(" %s\n", s) + sprintf(" %s\n", s) end - end - - str + end.join end # b4_symbol_enum def symbol_enum - str = "" - last_sym_number = @context.yysymbol_kind_t.last[1] - @context.yysymbol_kind_t.each do |s_value, sym_number, display_name| + @context.yysymbol_kind_t.map do |s_value, sym_number, display_name| s = sprintf("%s = %d%s", s_value, sym_number, (sym_number == last_sym_number) ? "" : ",") if display_name - str << sprintf(" %-40s /* %s */\n", s, display_name) + sprintf(" %-40s /* %s */\n", s, display_name) else - str << sprintf(" %s\n", s) + sprintf(" %s\n", s) end - end - - str + end.join end def yytranslate @@ -132,12 +126,10 @@ module Lrama end def symbol_actions_for_printer - str = "" - - @grammar.symbols.each do |sym| + @grammar.symbols.map do |sym| next unless sym.printer - str << <<-STR + <<-STR case #{sym.enum_name}: /* #{sym.comment} */ #line #{sym.printer.lineno} "#{@grammar_file_path}" {#{sym.printer.translated_code(sym.tag)}} @@ -145,18 +137,14 @@ module Lrama break; STR - end - - str + end.join end def symbol_actions_for_destructor - str = "" - - @grammar.symbols.each do |sym| + @grammar.symbols.map do |sym| next unless sym.destructor - str << <<-STR + <<-STR case #{sym.enum_name}: /* #{sym.comment} */ #line #{sym.destructor.lineno} "#{@grammar_file_path}" {#{sym.destructor.translated_code(sym.tag)}} @@ -164,9 +152,7 @@ module Lrama break; STR - end - - str + end.join end # b4_user_initial_action @@ -236,12 +222,10 @@ module Lrama end def symbol_actions_for_error_token - str = "" - - @grammar.symbols.each do |sym| + @grammar.symbols.map do |sym| next unless sym.error_token - str << <<-STR + <<-STR case #{sym.enum_name}: /* #{sym.comment} */ #line #{sym.error_token.lineno} "#{@grammar_file_path}" {#{sym.error_token.translated_code(sym.tag)}} @@ -249,22 +233,18 @@ module Lrama break; STR - end - - str + end.join end # b4_user_actions def user_actions - str = "" - - @context.states.rules.each do |rule| + action = @context.states.rules.map do |rule| next unless rule.token_code code = rule.token_code spaces = " " * (code.column - 1) - str << <<-STR + <<-STR case #{rule.id + 1}: /* #{rule.as_comment} */ #line #{code.line} "#{@grammar_file_path}" #{spaces}{#{rule.translated_code}} @@ -272,14 +252,12 @@ module Lrama break; STR - end + end.join - str << <<-STR + action + <<-STR #line [@oline@] [@ofile@] STR - - str end def omit_blanks(param) @@ -343,7 +321,7 @@ module Lrama # b4_parse_param_use def parse_param_use(val, loc) - str = <<-STR + str = <<-STR.dup YY_USE (#{val}); YY_USE (#{loc}); STR @@ -357,7 +335,8 @@ module Lrama # b4_yylex_formals def yylex_formals - ary = ["&yylval", "&yylloc"] + ary = ["&yylval"] + ary << "&yylloc" if @grammar.locations if @grammar.lex_param ary << lex_param_name @@ -397,17 +376,9 @@ module Lrama def int_array_to_string(ary) last = ary.count - 1 - s = ary.each_with_index.each_slice(10).map do |slice| - str = " " - - slice.each do |e, i| - str << sprintf("%6d%s", e, (i == last) ? "" : ",") - end - - str - end - - s.join("\n") + ary.each_with_index.each_slice(10).map do |slice| + " " + slice.map { |e, i| sprintf("%6d%s", e, (i == last) ? "" : ",") }.join + end.join("\n") end def spec_mapped_header_file @@ -457,26 +428,24 @@ module Lrama end def template_dir - File.expand_path("../../../template", __FILE__) + File.expand_path('../../template', __dir__) end def string_array_to_string(ary) - str = "" + result = "" tmp = " " ary.each do |s| - s = s.gsub('\\', '\\\\\\\\') - s = s.gsub('"', '\\"') - - if (tmp + s + " \"\",").length > 75 - str << tmp << "\n" - tmp = " \"#{s}\"," + replaced = s.gsub('\\', '\\\\\\\\').gsub('"', '\\"') + if (tmp + replaced + " \"\",").length > 75 + result = "#{result}#{tmp}\n" + tmp = " \"#{replaced}\"," else - tmp << " \"#{s}\"," + tmp = "#{tmp} \"#{replaced}\"," end end - str << tmp + result + tmp end def replace_special_variables(str, ofile) diff --git a/tool/lrama/lib/lrama/parser.rb b/tool/lrama/lib/lrama/parser.rb index 04603105b4..6a35dba290 100644 --- a/tool/lrama/lib/lrama/parser.rb +++ b/tool/lrama/lib/lrama/parser.rb @@ -1,6 +1,6 @@ # # DO NOT MODIFY!!!! -# This file is automatically generated by Racc 1.7.3 +# This file is automatically generated by Racc 1.8.1 # from Racc grammar file "parser.y". # @@ -23,7 +23,7 @@ unless $".find {|p| p.end_with?('/racc/info.rb')} $".push "#{__dir__}/racc/info.rb" module Racc - VERSION = '1.7.3' + VERSION = '1.8.1' Version = VERSION Copyright = 'Copyright (c) 1999-2006 Minero Aoki' end @@ -31,10 +31,6 @@ end end -unless defined?(NotImplementedError) - NotImplementedError = NotImplementError # :nodoc: -end - module Racc class ParseError < StandardError; end end @@ -42,7 +38,7 @@ unless defined?(::ParseError) ParseError = Racc::ParseError # :nodoc: end -# Racc is a LALR(1) parser generator. +# Racc is an LALR(1) parser generator. # It is written in Ruby itself, and generates Ruby programs. # # == Command-line Reference @@ -658,7 +654,7 @@ end module Lrama class Parser < Racc::Parser -module_eval(<<'...end parser.y/module_eval...', 'parser.y', 536) +module_eval(<<'...end parser.y/module_eval...', 'parser.y', 417) include Lrama::Report::Duration @@ -732,322 +728,297 @@ end ##### State transition tables begin ### racc_action_table = [ - 98, 51, 99, 163, 88, 79, 51, 51, 180, 163, - 79, 79, 51, 162, 180, 156, 79, 165, 157, 51, - 3, 50, 181, 165, 70, 51, 8, 50, 181, 79, - 75, 51, 6, 50, 7, 161, 82, 47, 51, 51, - 50, 50, 89, 82, 82, 166, 41, 51, 100, 50, - 182, 166, 82, 51, 48, 50, 182, 23, 25, 26, + 94, 48, 95, 166, 48, 77, 172, 48, 77, 166, + 48, 77, 172, 48, 77, 47, 6, 85, 69, 48, + 48, 47, 47, 77, 74, 81, 48, 48, 47, 47, + 40, 81, 81, 48, 41, 47, 92, 48, 81, 47, + 44, 77, 103, 168, 169, 45, 175, 169, 96, 168, + 169, 52, 175, 169, 86, 20, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 92, 48, 4, 47, 5, 77, 103, 48, 48, + 47, 47, 77, 103, 116, 48, 4, 47, 5, 77, + 20, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 52, 20, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 47, 51, 51, 50, 50, 93, 79, 197, - 51, 51, 50, 50, 79, 197, 51, 51, 50, 50, - 79, 197, 23, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 9, 51, 54, - 50, 14, 15, 16, 17, 18, 19, 54, 54, 20, - 21, 22, 23, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 51, 51, - 50, 50, 79, 197, 51, 51, 50, 50, 79, 197, - 51, 51, 50, 50, 79, 197, 51, 51, 50, 50, - 79, 79, 51, 51, 50, 50, 79, 79, 51, 51, - 50, 50, 79, 79, 51, 51, 50, 207, 79, 79, - 51, 51, 207, 207, 79, 79, 51, 51, 50, 50, - 79, 187, 188, 189, 96, 187, 188, 189, 96, 217, - 221, 229, 218, 218, 218, 51, 51, 50, 50, 187, - 188, 189, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 90, 94, 96, 101, 101, 101, 103, - 109, 113, 114, 117, 117, 117, 117, 120, 47, 124, - 125, 127, 129, 130, 131, 132, 133, 136, 140, 141, - 142, 143, 146, 147, 148, 150, 160, 168, 170, 171, - 172, 173, 174, 176, 177, 178, 146, 184, 192, 193, - 200, 160, 204, 176, 211, 160, 215, 216, 178, 176, - 226, 176, 228, 96, 96, 176 ] + 37, 38, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 43, 20, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 48, 48, + 47, 47, 77, 103, 48, 48, 47, 47, 77, 77, + 48, 48, 47, 47, 77, 77, 48, 48, 196, 196, + 77, 77, 48, 48, 47, 196, 77, 77, 148, 170, + 52, 149, 149, 180, 181, 182, 131, 180, 181, 182, + 131, 203, 208, 215, 204, 204, 204, 48, 48, 47, + 47, 48, 48, 47, 47, 48, 48, 47, 47, 180, + 181, 182, 119, 120, 55, 52, 52, 52, 52, 52, + 61, 62, 63, 64, 65, 87, 52, 52, 106, 109, + 111, 118, 125, 126, 128, 131, 132, 77, 140, 141, + 142, 143, 145, 146, 153, 140, 155, 153, 159, 160, + 161, 163, 164, 171, 176, 153, 183, 131, 187, 153, + 189, 131, 153, 198, 153, 131, 161, 164, 205, 164, + 161, 161, 213, 131, 161 ] racc_action_check = [ - 49, 145, 49, 145, 39, 145, 159, 183, 159, 183, - 159, 183, 201, 144, 201, 139, 201, 145, 139, 33, - 1, 33, 159, 183, 33, 34, 3, 34, 201, 34, - 34, 35, 2, 35, 2, 144, 35, 9, 36, 37, - 36, 37, 39, 36, 37, 145, 7, 38, 49, 38, - 159, 183, 38, 15, 14, 15, 201, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 42, 69, 172, 69, 172, 42, 172, 172, - 173, 70, 173, 70, 173, 173, 174, 81, 174, 81, - 174, 174, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 4, 82, 16, - 82, 4, 4, 4, 4, 4, 4, 17, 18, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 194, 109, - 194, 109, 194, 194, 198, 111, 198, 111, 198, 198, - 199, 117, 199, 117, 199, 199, 74, 75, 74, 75, - 74, 75, 114, 116, 114, 116, 114, 116, 137, 166, - 137, 166, 137, 166, 182, 184, 182, 184, 182, 184, - 204, 216, 204, 216, 204, 216, 218, 119, 218, 119, - 218, 164, 164, 164, 164, 179, 179, 179, 179, 208, - 214, 223, 208, 214, 223, 134, 138, 134, 138, 209, - 209, 209, 19, 20, 23, 25, 26, 27, 28, 29, - 30, 31, 32, 40, 45, 46, 53, 55, 56, 57, - 68, 72, 73, 80, 85, 86, 87, 88, 89, 95, - 96, 102, 104, 105, 106, 107, 108, 112, 120, 121, - 122, 123, 124, 125, 126, 128, 141, 149, 151, 152, - 153, 154, 155, 156, 157, 158, 161, 163, 167, 169, - 175, 178, 180, 186, 190, 200, 205, 207, 213, 217, - 220, 221, 222, 226, 228, 230 ] + 46, 151, 46, 151, 157, 151, 157, 177, 157, 177, + 188, 177, 188, 32, 188, 32, 1, 38, 32, 33, + 34, 33, 34, 33, 33, 34, 35, 36, 35, 36, + 5, 35, 36, 37, 6, 37, 44, 58, 37, 58, + 9, 58, 58, 151, 151, 11, 157, 157, 46, 177, + 177, 13, 188, 188, 38, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 88, 59, 0, 59, 0, 59, 59, 60, 79, + 60, 79, 60, 60, 79, 72, 2, 72, 2, 72, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 14, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 100, 12, + 100, 12, 100, 100, 74, 111, 74, 111, 74, 111, + 168, 175, 168, 175, 168, 175, 183, 189, 183, 189, + 183, 189, 204, 205, 204, 205, 204, 205, 139, 154, + 15, 139, 154, 165, 165, 165, 165, 173, 173, 173, + 173, 195, 200, 212, 195, 200, 212, 67, 69, 67, + 69, 81, 106, 81, 106, 114, 116, 114, 116, 197, + 197, 197, 86, 86, 16, 17, 20, 24, 25, 26, + 27, 28, 29, 30, 31, 39, 50, 55, 66, 70, + 71, 85, 89, 90, 91, 92, 98, 110, 118, 119, + 120, 121, 130, 131, 141, 142, 144, 145, 146, 147, + 148, 149, 150, 156, 162, 164, 166, 167, 170, 171, + 172, 174, 176, 186, 187, 191, 192, 194, 196, 199, + 201, 203, 207, 208, 214 ] racc_action_pointer = [ - nil, 20, 22, 26, 98, nil, nil, 39, nil, 33, - nil, nil, nil, nil, 48, 50, 90, 98, 99, 207, - 194, nil, nil, 195, nil, 196, 197, 198, 213, 214, - 215, 216, 217, 16, 22, 28, 35, 36, 44, -1, - 221, nil, 68, nil, nil, 201, 174, nil, nil, -5, - nil, nil, nil, 207, nil, 208, 209, 210, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, 222, 70, - 78, nil, 225, 224, 153, 154, nil, nil, nil, nil, - 225, 84, 105, nil, nil, 226, 227, 228, 197, 234, - nil, nil, nil, nil, nil, 197, 235, nil, nil, nil, - nil, nil, 239, nil, 240, 241, 242, 243, 244, 136, - nil, 142, 240, nil, 159, nil, 160, 148, nil, 184, - 243, 207, 239, 249, 206, 201, 252, nil, 253, nil, - nil, nil, nil, nil, 202, nil, nil, 165, 203, -26, - nil, 210, nil, nil, -10, -2, nil, nil, nil, 237, - nil, 238, 239, 240, 241, 242, 255, 259, 220, 3, - nil, 220, nil, 227, 143, nil, 166, 248, nil, 249, - nil, nil, 71, 77, 83, 228, nil, nil, 225, 147, - 232, nil, 171, 4, 172, nil, 265, nil, nil, nil, - 272, nil, nil, nil, 135, nil, nil, nil, 141, 147, - 229, 9, nil, nil, 177, 274, nil, 237, 158, 161, - nil, nil, nil, 233, 159, nil, 178, 271, 183, nil, - 260, 273, 262, 160, nil, nil, 232, nil, 233, nil, - 277, nil, nil ] + 63, 16, 76, 93, nil, 23, 34, nil, 119, 31, + nil, 39, 156, 5, 69, 144, 219, 179, nil, nil, + 180, nil, nil, nil, 181, 182, 183, 225, 226, 227, + 228, 229, 10, 16, 17, 23, 24, 30, 12, 233, + nil, nil, nil, nil, 32, nil, -5, nil, nil, nil, + 190, nil, nil, nil, nil, 191, nil, nil, 34, 69, + 75, nil, nil, nil, nil, nil, 230, 204, nil, 205, + 233, 232, 82, nil, 161, nil, nil, nil, nil, 76, + nil, 208, nil, nil, nil, 202, 218, nil, 67, 233, + 221, 222, 194, nil, nil, nil, nil, nil, 244, nil, + 155, nil, nil, nil, nil, nil, 209, nil, nil, nil, + 240, 162, nil, nil, 212, nil, 213, nil, 243, 208, + 211, 240, nil, nil, nil, nil, nil, nil, nil, nil, + 211, 248, nil, nil, nil, nil, nil, nil, nil, 148, + nil, 200, 250, nil, 254, 203, 206, 212, 252, 256, + 218, -2, nil, nil, 149, nil, 219, 1, nil, nil, + nil, nil, 223, nil, 211, 145, 227, 216, 167, nil, + 227, 215, 231, 149, 220, 168, 218, 4, nil, nil, + nil, nil, nil, 173, nil, nil, 271, 220, 7, 174, + nil, 224, 268, nil, 233, 161, 239, 171, nil, 235, + 162, 272, nil, 273, 179, 180, nil, 235, 232, nil, + nil, nil, 163, nil, 276, nil, nil ] racc_action_default = [ - -2, -138, -8, -138, -138, -3, -4, -138, 233, -138, - -9, -10, -11, -12, -138, -138, -138, -138, -138, -138, - -138, -24, -25, -138, -29, -138, -138, -138, -138, -138, - -138, -138, -138, -138, -138, -138, -138, -138, -138, -138, - -138, -7, -123, -96, -98, -138, -120, -122, -13, -127, - -94, -95, -126, -15, -85, -16, -17, -138, -21, -26, - -30, -33, -36, -39, -40, -41, -42, -43, -44, -50, - -138, -53, -71, -45, -75, -138, -78, -80, -81, -135, - -46, -88, -138, -91, -93, -47, -48, -49, -138, -138, - -5, -1, -97, -124, -99, -138, -138, -14, -128, -129, - -130, -82, -138, -18, -138, -138, -138, -138, -138, -138, - -54, -51, -73, -72, -138, -79, -76, -138, -92, -89, - -138, -138, -138, -138, -104, -138, -138, -86, -138, -22, - -27, -31, -34, -37, -52, -55, -74, -77, -90, -138, - -58, -62, -6, -125, -100, -101, -105, -121, -83, -138, - -19, -138, -138, -138, -138, -138, -136, -138, -57, -60, - -63, -104, -103, -94, -120, -109, -138, -138, -87, -138, - -23, -28, -138, -138, -138, -138, -137, -59, -62, -120, - -94, -67, -138, -102, -138, -106, -136, -113, -114, -115, - -138, -112, -84, -20, -32, -131, -133, -134, -35, -38, - -62, -61, -64, -65, -138, -138, -70, -94, -138, -116, - -107, -110, -132, -56, -138, -68, -138, -136, -138, -118, - -138, -136, -138, -138, -108, -117, -120, -66, -120, -119, - -136, -69, -111 ] + -1, -127, -1, -3, -10, -127, -127, -2, -3, -127, + -16, -127, -127, -127, -127, -127, -127, -127, -24, -25, + -127, -30, -31, -32, -127, -127, -127, -127, -127, -127, + -127, -127, -127, -127, -127, -127, -127, -127, -127, -127, + -13, 217, -4, -26, -127, -17, -118, -89, -90, -117, + -14, -19, -81, -20, -21, -127, -23, -29, -127, -127, + -127, -36, -37, -38, -39, -40, -41, -47, -49, -127, + -52, -42, -74, -76, -127, -79, -80, -126, -43, -84, + -86, -127, -44, -45, -46, -127, -127, -11, -5, -7, + -91, -127, -64, -18, -119, -120, -121, -15, -127, -22, + -27, -33, -122, -123, -34, -35, -127, -48, -50, -53, + -72, -127, -75, -77, -84, -85, -127, -87, -127, -127, + -127, -127, -6, -8, -9, -115, -92, -93, -94, -65, + -127, -127, -82, -28, -51, -54, -73, -78, -88, -127, + -60, -124, -127, -12, -127, -124, -127, -127, -55, -127, + -58, -62, -66, -125, -127, -116, -95, -96, -98, -114, + -83, -56, -127, -61, -124, -64, -89, -64, -127, -111, + -127, -124, -89, -64, -64, -127, -124, -63, -67, -68, + -104, -105, -106, -127, -70, -71, -127, -124, -97, -127, + -99, -64, -55, -103, -57, -127, -89, -107, -112, -59, + -127, -55, -102, -55, -127, -127, -109, -127, -64, -100, + -69, -108, -127, -113, -55, -110, -101 ] racc_goto_table = [ - 76, 95, 69, 52, 74, 158, 110, 175, 118, 119, - 145, 208, 1, 212, 186, 2, 43, 212, 212, 4, - 42, 72, 91, 84, 84, 84, 84, 5, 40, 203, - 122, 214, 80, 85, 86, 87, 10, 210, 11, 111, - 115, 76, 12, 223, 138, 116, 118, 183, 110, 92, - 53, 55, 56, 194, 198, 199, 13, 72, 72, 219, - 49, 97, 128, 169, 213, 118, 104, 151, 224, 84, - 84, 110, 227, 105, 152, 106, 153, 107, 134, 154, - 76, 232, 115, 108, 137, 155, 68, 73, 112, 135, - 139, 121, 201, 205, 222, 126, 167, 72, 102, 72, - 149, 144, 190, 115, 220, 84, 123, 84, nil, nil, - nil, 164, nil, nil, nil, nil, nil, nil, nil, 185, - nil, nil, 72, nil, nil, 179, 84, nil, nil, nil, - nil, nil, 191, nil, 202, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, 206, 164, - 209, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, 179, nil, nil, - 209, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, 230, 209, 231, 225 ] + 102, 102, 102, 49, 130, 73, 68, 89, 162, 91, + 150, 139, 101, 104, 105, 1, 9, 174, 51, 53, + 54, 42, 115, 70, 117, 79, 79, 79, 79, 56, + 123, 3, 57, 7, 124, 154, 58, 59, 60, 179, + 158, 107, 102, 108, 112, 194, 113, 191, 174, 157, + 39, 122, 202, 91, 133, 97, 199, 115, 70, 138, + 70, 209, 195, 210, 121, 46, 158, 99, 200, 93, + 114, 206, 114, 66, 216, 188, 71, 178, 135, 184, + 134, 110, 177, 137, 212, 190, 192, 78, 82, 83, + 84, 136, 98, 165, 147, 127, 156, 70, 186, 173, + 207, 144, nil, 201, nil, 114, nil, 114, nil, nil, + 185, nil, nil, nil, nil, nil, nil, 193, nil, 165, + 214, nil, nil, nil, nil, 197, nil, nil, nil, nil, + 173, 197, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 211, 197 ] racc_goto_check = [ - 43, 44, 33, 35, 49, 40, 34, 39, 56, 55, - 60, 46, 1, 64, 45, 2, 57, 64, 64, 3, - 4, 35, 5, 35, 35, 35, 35, 6, 7, 45, - 8, 46, 32, 32, 32, 32, 9, 39, 10, 33, - 43, 43, 11, 46, 55, 49, 56, 60, 34, 57, - 15, 15, 15, 21, 21, 21, 12, 35, 35, 45, - 13, 14, 16, 17, 40, 56, 18, 19, 39, 35, - 35, 34, 39, 22, 23, 24, 25, 26, 33, 27, - 43, 39, 43, 28, 49, 29, 30, 31, 36, 37, - 38, 41, 42, 47, 48, 51, 52, 35, 53, 35, - 54, 59, 61, 43, 62, 35, 63, 35, nil, nil, - nil, 43, nil, nil, nil, nil, nil, nil, nil, 44, - nil, nil, 35, nil, nil, 43, 35, nil, nil, nil, - nil, nil, 43, nil, 44, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, 43, 43, - 43, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, 43, nil, nil, - 43, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, 44, 43, 44, 43 ] + 35, 35, 35, 27, 40, 42, 26, 8, 32, 12, + 31, 30, 21, 21, 21, 1, 7, 39, 16, 16, + 16, 7, 45, 27, 45, 27, 27, 27, 27, 15, + 5, 6, 15, 6, 9, 30, 15, 15, 15, 37, + 34, 26, 35, 26, 42, 31, 42, 37, 39, 49, + 10, 8, 32, 12, 21, 16, 31, 45, 27, 45, + 27, 32, 38, 32, 11, 13, 34, 15, 38, 14, + 27, 37, 27, 22, 32, 49, 23, 40, 28, 40, + 26, 29, 33, 42, 38, 40, 40, 24, 24, 24, + 24, 41, 43, 35, 44, 47, 48, 27, 50, 35, + 51, 52, nil, 40, nil, 27, nil, 27, nil, nil, + 35, nil, nil, nil, nil, nil, nil, 35, nil, 35, + 40, nil, nil, nil, nil, 35, nil, nil, nil, nil, + 35, 35, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 35, 35 ] racc_goto_pointer = [ - nil, 12, 15, 17, 11, -20, 25, 22, -60, 32, - 34, 38, 52, 45, 12, 34, -41, -87, 8, -62, - nil, -119, 14, -56, 15, -55, 16, -53, 21, -48, - 53, 53, -3, -31, -63, -12, 16, -23, -30, -149, - -136, 2, -86, -34, -45, -150, -173, -88, -121, -30, - nil, -6, -52, 44, -27, -73, -73, 7, nil, -23, - -114, -63, -107, 13, -181 ] + nil, 15, nil, nil, nil, -59, 31, 13, -37, -55, + 46, -23, -35, 53, 23, 12, 5, nil, nil, nil, + nil, -46, 41, 43, 53, nil, -26, -9, -32, 11, + -107, -131, -140, -82, -105, -58, nil, -126, -121, -140, + -88, -19, -28, 40, -38, -57, nil, 5, -49, -96, + -71, -98, -24 ] racc_goto_default = [ - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - 45, nil, nil, nil, nil, nil, nil, nil, nil, nil, - 24, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, 71, 77, nil, nil, nil, nil, - nil, 46, 159, 196, nil, nil, nil, nil, nil, nil, - 78, nil, nil, nil, nil, 81, 83, nil, 44, nil, - nil, nil, nil, nil, 195 ] + nil, nil, 2, 8, 88, nil, nil, nil, nil, nil, + nil, nil, 10, nil, nil, 50, nil, 21, 22, 23, + 100, nil, nil, nil, nil, 67, nil, 75, nil, nil, + nil, nil, nil, 151, 152, 72, 129, nil, nil, 167, + nil, 76, nil, nil, nil, 80, 90, nil, nil, nil, + nil, nil, nil ] racc_reduce_table = [ 0, 0, :racc_error, - 5, 55, :_reduce_none, - 0, 56, :_reduce_none, - 2, 56, :_reduce_none, - 0, 61, :_reduce_4, - 0, 62, :_reduce_5, - 5, 60, :_reduce_6, - 2, 60, :_reduce_none, - 0, 57, :_reduce_8, - 2, 57, :_reduce_none, - 1, 63, :_reduce_none, - 1, 63, :_reduce_none, - 1, 63, :_reduce_none, - 2, 63, :_reduce_13, - 3, 63, :_reduce_none, - 2, 63, :_reduce_none, - 2, 63, :_reduce_16, - 2, 63, :_reduce_17, - 0, 70, :_reduce_18, - 0, 71, :_reduce_19, - 7, 63, :_reduce_20, - 0, 72, :_reduce_21, - 0, 73, :_reduce_22, - 6, 63, :_reduce_23, - 1, 63, :_reduce_24, - 1, 63, :_reduce_none, - 0, 76, :_reduce_26, - 0, 77, :_reduce_27, - 6, 64, :_reduce_28, + 0, 61, :_reduce_1, + 2, 61, :_reduce_2, + 0, 62, :_reduce_3, + 2, 62, :_reduce_4, + 1, 63, :_reduce_5, + 2, 63, :_reduce_6, + 0, 64, :_reduce_none, 1, 64, :_reduce_none, - 0, 78, :_reduce_30, - 0, 79, :_reduce_31, - 7, 64, :_reduce_32, - 0, 80, :_reduce_33, - 0, 81, :_reduce_34, - 7, 64, :_reduce_35, - 0, 82, :_reduce_36, - 0, 83, :_reduce_37, - 7, 64, :_reduce_38, - 2, 64, :_reduce_39, - 2, 64, :_reduce_40, - 2, 64, :_reduce_41, - 2, 64, :_reduce_42, - 2, 64, :_reduce_43, - 2, 74, :_reduce_none, - 2, 74, :_reduce_45, - 2, 74, :_reduce_46, - 2, 74, :_reduce_47, - 2, 74, :_reduce_48, - 2, 74, :_reduce_49, - 1, 84, :_reduce_50, - 2, 84, :_reduce_51, - 3, 84, :_reduce_52, - 1, 87, :_reduce_53, - 2, 87, :_reduce_54, - 3, 88, :_reduce_55, - 8, 65, :_reduce_56, - 5, 66, :_reduce_57, - 1, 92, :_reduce_58, - 3, 92, :_reduce_59, - 1, 94, :_reduce_60, - 3, 94, :_reduce_61, - 0, 96, :_reduce_62, - 1, 96, :_reduce_63, - 3, 96, :_reduce_64, - 3, 96, :_reduce_65, - 6, 96, :_reduce_66, - 0, 101, :_reduce_67, - 0, 102, :_reduce_68, - 7, 96, :_reduce_69, - 3, 96, :_reduce_70, - 0, 90, :_reduce_none, - 1, 90, :_reduce_none, - 0, 91, :_reduce_none, - 1, 91, :_reduce_none, - 1, 85, :_reduce_75, - 2, 85, :_reduce_76, - 3, 85, :_reduce_77, - 1, 103, :_reduce_78, - 2, 103, :_reduce_79, - 1, 97, :_reduce_none, - 1, 97, :_reduce_none, - 0, 105, :_reduce_82, - 0, 106, :_reduce_83, - 6, 69, :_reduce_84, - 0, 107, :_reduce_85, - 0, 108, :_reduce_86, - 5, 69, :_reduce_87, - 1, 86, :_reduce_88, - 2, 86, :_reduce_89, - 3, 86, :_reduce_90, - 1, 109, :_reduce_91, - 2, 109, :_reduce_92, - 1, 110, :_reduce_none, - 1, 89, :_reduce_94, - 1, 89, :_reduce_95, + 5, 56, :_reduce_none, + 0, 65, :_reduce_10, + 0, 66, :_reduce_11, + 5, 57, :_reduce_12, + 2, 57, :_reduce_none, + 1, 71, :_reduce_14, + 2, 71, :_reduce_15, 1, 58, :_reduce_none, + 2, 58, :_reduce_17, + 3, 58, :_reduce_none, 2, 58, :_reduce_none, - 1, 111, :_reduce_none, - 2, 111, :_reduce_none, - 4, 112, :_reduce_100, - 1, 113, :_reduce_101, - 3, 113, :_reduce_102, - 2, 113, :_reduce_none, - 0, 114, :_reduce_104, - 1, 114, :_reduce_105, - 3, 114, :_reduce_106, - 4, 114, :_reduce_107, - 6, 114, :_reduce_108, - 0, 115, :_reduce_109, - 0, 116, :_reduce_110, - 8, 114, :_reduce_111, - 3, 114, :_reduce_112, - 1, 99, :_reduce_113, - 1, 99, :_reduce_114, - 1, 99, :_reduce_115, - 1, 100, :_reduce_116, - 3, 100, :_reduce_117, - 2, 100, :_reduce_118, - 4, 100, :_reduce_119, - 0, 98, :_reduce_none, - 3, 98, :_reduce_121, - 1, 95, :_reduce_none, - 0, 59, :_reduce_none, - 0, 117, :_reduce_124, - 3, 59, :_reduce_125, + 2, 58, :_reduce_20, + 2, 58, :_reduce_21, + 3, 58, :_reduce_22, + 2, 58, :_reduce_23, + 1, 58, :_reduce_24, + 1, 58, :_reduce_25, + 2, 58, :_reduce_none, + 1, 76, :_reduce_27, + 2, 76, :_reduce_28, + 2, 67, :_reduce_29, 1, 67, :_reduce_none, - 0, 68, :_reduce_none, + 1, 67, :_reduce_none, + 1, 67, :_reduce_none, + 3, 67, :_reduce_33, + 3, 67, :_reduce_34, + 3, 67, :_reduce_35, + 2, 67, :_reduce_36, + 2, 67, :_reduce_37, + 2, 67, :_reduce_38, + 2, 67, :_reduce_39, + 2, 67, :_reduce_40, + 2, 72, :_reduce_none, + 2, 72, :_reduce_42, + 2, 72, :_reduce_43, + 2, 72, :_reduce_44, + 2, 72, :_reduce_45, + 2, 72, :_reduce_46, + 1, 81, :_reduce_47, + 2, 81, :_reduce_48, + 1, 77, :_reduce_49, + 2, 77, :_reduce_50, + 3, 77, :_reduce_51, + 0, 84, :_reduce_none, + 1, 84, :_reduce_none, + 3, 80, :_reduce_54, + 0, 87, :_reduce_none, + 1, 87, :_reduce_none, + 8, 73, :_reduce_57, + 5, 74, :_reduce_58, + 8, 74, :_reduce_59, + 1, 85, :_reduce_60, + 3, 85, :_reduce_61, + 1, 86, :_reduce_62, + 3, 86, :_reduce_63, + 0, 95, :_reduce_none, + 1, 95, :_reduce_none, + 1, 88, :_reduce_66, + 3, 88, :_reduce_67, + 3, 88, :_reduce_68, + 6, 88, :_reduce_69, + 3, 88, :_reduce_70, + 3, 88, :_reduce_71, + 0, 83, :_reduce_none, + 1, 83, :_reduce_73, + 1, 97, :_reduce_74, + 2, 97, :_reduce_75, + 1, 78, :_reduce_76, + 2, 78, :_reduce_77, + 3, 78, :_reduce_78, + 1, 90, :_reduce_none, + 1, 90, :_reduce_none, + 0, 98, :_reduce_81, + 0, 99, :_reduce_82, + 5, 70, :_reduce_83, + 1, 100, :_reduce_84, + 2, 100, :_reduce_85, + 1, 79, :_reduce_86, + 2, 79, :_reduce_87, + 3, 79, :_reduce_88, + 1, 82, :_reduce_89, + 1, 82, :_reduce_90, + 0, 102, :_reduce_none, + 1, 102, :_reduce_none, + 2, 59, :_reduce_none, + 2, 59, :_reduce_none, + 4, 101, :_reduce_95, + 1, 103, :_reduce_96, + 3, 103, :_reduce_97, + 1, 104, :_reduce_98, + 3, 104, :_reduce_99, + 5, 104, :_reduce_100, + 7, 104, :_reduce_101, + 4, 104, :_reduce_102, + 3, 104, :_reduce_103, + 1, 92, :_reduce_104, + 1, 92, :_reduce_105, + 1, 92, :_reduce_106, + 1, 93, :_reduce_107, + 3, 93, :_reduce_108, + 2, 93, :_reduce_109, + 4, 93, :_reduce_110, + 0, 105, :_reduce_111, + 0, 106, :_reduce_112, + 5, 94, :_reduce_113, + 3, 91, :_reduce_114, + 0, 107, :_reduce_115, + 3, 60, :_reduce_116, 1, 68, :_reduce_none, - 1, 68, :_reduce_none, - 1, 68, :_reduce_none, - 1, 75, :_reduce_131, - 2, 75, :_reduce_132, - 1, 118, :_reduce_none, - 1, 118, :_reduce_none, - 1, 104, :_reduce_135, - 0, 93, :_reduce_none, - 1, 93, :_reduce_none ] + 0, 69, :_reduce_none, + 1, 69, :_reduce_none, + 1, 69, :_reduce_none, + 1, 69, :_reduce_none, + 1, 75, :_reduce_none, + 1, 75, :_reduce_none, + 0, 89, :_reduce_none, + 1, 89, :_reduce_none, + 1, 96, :_reduce_126 ] -racc_reduce_n = 138 +racc_reduce_n = 127 -racc_shift_n = 233 +racc_shift_n = 217 racc_token_table = { false => 0, @@ -1069,43 +1040,44 @@ racc_token_table = { "%lex-param" => 16, "%parse-param" => 17, "%code" => 18, - "{" => 19, - "}" => 20, - "%initial-action" => 21, - "%no-stdlib" => 22, - ";" => 23, - "%union" => 24, - "%destructor" => 25, - "%printer" => 26, - "%error-token" => 27, - "%after-shift" => 28, - "%before-reduce" => 29, - "%after-reduce" => 30, - "%after-shift-error-token" => 31, - "%after-pop-stack" => 32, - "%token" => 33, - "%type" => 34, - "%left" => 35, - "%right" => 36, - "%precedence" => 37, - "%nonassoc" => 38, - "%rule" => 39, - "(" => 40, - ")" => 41, - ":" => 42, - "%inline" => 43, - "," => 44, - "|" => 45, - "%empty" => 46, - "%prec" => 47, + "%initial-action" => 19, + "%no-stdlib" => 20, + "%locations" => 21, + ";" => 22, + "%union" => 23, + "%destructor" => 24, + "%printer" => 25, + "%error-token" => 26, + "%after-shift" => 27, + "%before-reduce" => 28, + "%after-reduce" => 29, + "%after-shift-error-token" => 30, + "%after-pop-stack" => 31, + "%token" => 32, + "%type" => 33, + "%left" => 34, + "%right" => 35, + "%precedence" => 36, + "%nonassoc" => 37, + "%rule" => 38, + "(" => 39, + ")" => 40, + ":" => 41, + "%inline" => 42, + "," => 43, + "|" => 44, + "%prec" => 45, + "{" => 46, + "}" => 47, "?" => 48, "+" => 49, "*" => 50, "[" => 51, "]" => 52, - "{...}" => 53 } + "{...}" => 53, + "%empty" => 54 } -racc_nt_base = 54 +racc_nt_base = 55 racc_use_result_var = true @@ -1146,10 +1118,9 @@ Racc_token_to_s_table = [ "\"%lex-param\"", "\"%parse-param\"", "\"%code\"", - "\"{\"", - "\"}\"", "\"%initial-action\"", "\"%no-stdlib\"", + "\"%locations\"", "\";\"", "\"%union\"", "\"%destructor\"", @@ -1173,79 +1144,69 @@ Racc_token_to_s_table = [ "\"%inline\"", "\",\"", "\"|\"", - "\"%empty\"", "\"%prec\"", + "\"{\"", + "\"}\"", "\"?\"", "\"+\"", "\"*\"", "\"[\"", "\"]\"", "\"{...}\"", + "\"%empty\"", "$start", "input", - "prologue_declarations", - "bison_declarations", - "grammar", - "epilogue_opt", "prologue_declaration", + "bison_declaration", + "rules_or_grammar_declaration", + "epilogue_declaration", + "\"-many@prologue_declaration\"", + "\"-many@bison_declaration\"", + "\"-many1@rules_or_grammar_declaration\"", + "\"-option@epilogue_declaration\"", "@1", "@2", - "bison_declaration", "grammar_declaration", - "rule_declaration", - "inline_declaration", "variable", "value", - "params", - "@3", - "@4", - "@5", - "@6", + "param", + "\"-many1@param\"", "symbol_declaration", - "generic_symlist", - "@7", - "@8", - "@9", - "@10", - "@11", - "@12", - "@13", - "@14", + "rule_declaration", + "inline_declaration", + "generic_symbol", + "\"-many1@generic_symbol\"", "token_declarations", "symbol_declarations", "token_declarations_for_precedence", - "token_declaration_list", "token_declaration", + "\"-many1@token_declaration\"", "id", - "int_opt", "alias", + "\"-option@INTEGER\"", "rule_args", - "tag_opt", "rule_rhs_list", - "id_colon", + "\"-option@TAG\"", "rule_rhs", + "empty", "symbol", - "named_ref_opt", + "named_ref", "parameterizing_suffix", "parameterizing_args", - "@15", - "@16", - "symbol_declaration_list", + "midrule_action", + "\"-option@named_ref\"", "string_as_id", - "@17", - "@18", - "@19", - "@20", - "token_declaration_list_for_precedence", - "token_declaration_for_precedence", - "rules_or_grammar_declaration", + "\"-many1@symbol\"", + "@3", + "@4", + "\"-many1@id\"", "rules", + "\"-option@;\"", "rhs_list", "rhs", - "@21", - "@22", - "@23", - "generic_symlist_item" ] + "@5", + "@6", + "@7" ] Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) Racc_debug_parser = true @@ -1254,14 +1215,56 @@ Racc_debug_parser = true # reduce 0 omitted -# reduce 1 omitted +module_eval(<<'.,.,', 'parser.y', 11) + def _reduce_1(val, _values, result) + result = val[1] ? val[1].unshift(val[0]) : val + result + end +.,., -# reduce 2 omitted +module_eval(<<'.,.,', 'parser.y', 11) + def _reduce_2(val, _values, result) + result = val[1] ? val[1].unshift(val[0]) : val + result + end +.,., -# reduce 3 omitted +module_eval(<<'.,.,', 'parser.y', 11) + def _reduce_3(val, _values, result) + result = val[1] ? val[1].unshift(val[0]) : val + result + end +.,., -module_eval(<<'.,.,', 'parser.y', 14) +module_eval(<<'.,.,', 'parser.y', 11) def _reduce_4(val, _values, result) + result = val[1] ? val[1].unshift(val[0]) : val + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 11) + def _reduce_5(val, _values, result) + result = val[1] ? val[1].unshift(val[0]) : val + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 11) + def _reduce_6(val, _values, result) + result = val[1] ? val[1].unshift(val[0]) : val + result + end +.,., + +# reduce 7 omitted + +# reduce 8 omitted + +# reduce 9 omitted + +module_eval(<<'.,.,', 'parser.y', 12) + def _reduce_10(val, _values, result) begin_c_declaration("%}") @grammar.prologue_first_lineno = @lexer.line @@ -1269,52 +1272,53 @@ module_eval(<<'.,.,', 'parser.y', 14) end .,., -module_eval(<<'.,.,', 'parser.y', 19) - def _reduce_5(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 17) + def _reduce_11(val, _values, result) end_c_declaration result end .,., -module_eval(<<'.,.,', 'parser.y', 23) - def _reduce_6(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 21) + def _reduce_12(val, _values, result) @grammar.prologue = val[2].s_value result end .,., -# reduce 7 omitted +# reduce 13 omitted -module_eval(<<'.,.,', 'parser.y', 27) - def _reduce_8(val, _values, result) - result = "" +module_eval(<<'.,.,', 'parser.y', 54) + def _reduce_14(val, _values, result) + result = val[1] ? val[1].unshift(val[0]) : val result end .,., -# reduce 9 omitted +module_eval(<<'.,.,', 'parser.y', 54) + def _reduce_15(val, _values, result) + result = val[1] ? val[1].unshift(val[0]) : val + result + end +.,., -# reduce 10 omitted +# reduce 16 omitted -# reduce 11 omitted - -# reduce 12 omitted - -module_eval(<<'.,.,', 'parser.y', 33) - def _reduce_13(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 26) + def _reduce_17(val, _values, result) @grammar.expect = val[1] result end .,., -# reduce 14 omitted +# reduce 18 omitted -# reduce 15 omitted +# reduce 19 omitted -module_eval(<<'.,.,', 'parser.y', 38) - def _reduce_16(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 31) + def _reduce_20(val, _values, result) val[1].each {|token| @grammar.lex_param = Grammar::Code::NoReferenceCode.new(type: :lex_param, token_code: token).token_code.s_value } @@ -1323,8 +1327,8 @@ module_eval(<<'.,.,', 'parser.y', 38) end .,., -module_eval(<<'.,.,', 'parser.y', 44) - def _reduce_17(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 37) + def _reduce_21(val, _values, result) val[1].each {|token| @grammar.parse_param = Grammar::Code::NoReferenceCode.new(type: :parse_param, token_code: token).token_code.s_value } @@ -1333,220 +1337,149 @@ module_eval(<<'.,.,', 'parser.y', 44) end .,., -module_eval(<<'.,.,', 'parser.y', 50) - def _reduce_18(val, _values, result) - begin_c_declaration("}") - - result - end -.,., - -module_eval(<<'.,.,', 'parser.y', 54) - def _reduce_19(val, _values, result) - end_c_declaration - - result - end -.,., - -module_eval(<<'.,.,', 'parser.y', 58) - def _reduce_20(val, _values, result) - @grammar.add_percent_code(id: val[1], code: val[4]) - - result - end -.,., - -module_eval(<<'.,.,', 'parser.y', 62) - def _reduce_21(val, _values, result) - begin_c_declaration("}") - - result - end -.,., - -module_eval(<<'.,.,', 'parser.y', 66) +module_eval(<<'.,.,', 'parser.y', 43) def _reduce_22(val, _values, result) - end_c_declaration + @grammar.add_percent_code(id: val[1], code: val[2]) result end .,., -module_eval(<<'.,.,', 'parser.y', 70) +module_eval(<<'.,.,', 'parser.y', 47) def _reduce_23(val, _values, result) - @grammar.initial_action = Grammar::Code::InitialActionCode.new(type: :initial_action, token_code: val[3]) + @grammar.initial_action = Grammar::Code::InitialActionCode.new(type: :initial_action, token_code: val[1]) result end .,., -module_eval(<<'.,.,', 'parser.y', 72) +module_eval(<<'.,.,', 'parser.y', 49) def _reduce_24(val, _values, result) @grammar.no_stdlib = true result end .,., -# reduce 25 omitted +module_eval(<<'.,.,', 'parser.y', 50) + def _reduce_25(val, _values, result) + @grammar.locations = true + result + end +.,., -module_eval(<<'.,.,', 'parser.y', 77) - def _reduce_26(val, _values, result) - begin_c_declaration("}") +# reduce 26 omitted + +module_eval(<<'.,.,', 'parser.y', 109) + def _reduce_27(val, _values, result) + result = val[1] ? val[1].unshift(val[0]) : val + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 109) + def _reduce_28(val, _values, result) + result = val[1] ? val[1].unshift(val[0]) : val + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 55) + def _reduce_29(val, _values, result) + @grammar.set_union( + Grammar::Code::NoReferenceCode.new(type: :union, token_code: val[1]), + val[1].line + ) + + result + end +.,., + +# reduce 30 omitted + +# reduce 31 omitted + +# reduce 32 omitted + +module_eval(<<'.,.,', 'parser.y', 65) + def _reduce_33(val, _values, result) + @grammar.add_destructor( + ident_or_tags: val[2], + token_code: val[1], + lineno: val[1].line + ) + + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 73) + def _reduce_34(val, _values, result) + @grammar.add_printer( + ident_or_tags: val[2], + token_code: val[1], + lineno: val[1].line + ) result end .,., module_eval(<<'.,.,', 'parser.y', 81) - def _reduce_27(val, _values, result) - end_c_declaration - - result - end -.,., - -module_eval(<<'.,.,', 'parser.y', 85) - def _reduce_28(val, _values, result) - @grammar.set_union( - Grammar::Code::NoReferenceCode.new(type: :union, token_code: val[3]), - val[3].line - ) - - result - end -.,., - -# reduce 29 omitted - -module_eval(<<'.,.,', 'parser.y', 93) - def _reduce_30(val, _values, result) - begin_c_declaration("}") - - result - end -.,., - -module_eval(<<'.,.,', 'parser.y', 97) - def _reduce_31(val, _values, result) - end_c_declaration - - result - end -.,., - -module_eval(<<'.,.,', 'parser.y', 101) - def _reduce_32(val, _values, result) - @grammar.add_destructor( - ident_or_tags: val[6], - token_code: val[3], - lineno: val[3].line - ) - - result - end -.,., - -module_eval(<<'.,.,', 'parser.y', 109) - def _reduce_33(val, _values, result) - begin_c_declaration("}") - - result - end -.,., - -module_eval(<<'.,.,', 'parser.y', 113) - def _reduce_34(val, _values, result) - end_c_declaration - - result - end -.,., - -module_eval(<<'.,.,', 'parser.y', 117) def _reduce_35(val, _values, result) - @grammar.add_printer( - ident_or_tags: val[6], - token_code: val[3], - lineno: val[3].line - ) - - result - end -.,., - -module_eval(<<'.,.,', 'parser.y', 125) - def _reduce_36(val, _values, result) - begin_c_declaration("}") - - result - end -.,., - -module_eval(<<'.,.,', 'parser.y', 129) - def _reduce_37(val, _values, result) - end_c_declaration - - result - end -.,., - -module_eval(<<'.,.,', 'parser.y', 133) - def _reduce_38(val, _values, result) @grammar.add_error_token( - ident_or_tags: val[6], - token_code: val[3], - lineno: val[3].line + ident_or_tags: val[2], + token_code: val[1], + lineno: val[1].line ) result end .,., -module_eval(<<'.,.,', 'parser.y', 141) - def _reduce_39(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 89) + def _reduce_36(val, _values, result) @grammar.after_shift = val[1] result end .,., -module_eval(<<'.,.,', 'parser.y', 145) - def _reduce_40(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 93) + def _reduce_37(val, _values, result) @grammar.before_reduce = val[1] result end .,., -module_eval(<<'.,.,', 'parser.y', 149) - def _reduce_41(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 97) + def _reduce_38(val, _values, result) @grammar.after_reduce = val[1] result end .,., -module_eval(<<'.,.,', 'parser.y', 153) - def _reduce_42(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 101) + def _reduce_39(val, _values, result) @grammar.after_shift_error_token = val[1] result end .,., -module_eval(<<'.,.,', 'parser.y', 157) - def _reduce_43(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 105) + def _reduce_40(val, _values, result) @grammar.after_pop_stack = val[1] result end .,., -# reduce 44 omitted +# reduce 41 omitted -module_eval(<<'.,.,', 'parser.y', 163) - def _reduce_45(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 111) + def _reduce_42(val, _values, result) val[1].each {|hash| hash[:tokens].each {|id| @grammar.add_type(id: id, tag: hash[:tag]) @@ -1557,8 +1490,8 @@ module_eval(<<'.,.,', 'parser.y', 163) end .,., -module_eval(<<'.,.,', 'parser.y', 171) - def _reduce_46(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 119) + def _reduce_43(val, _values, result) val[1].each {|hash| hash[:tokens].each {|id| sym = @grammar.add_term(id: id) @@ -1571,8 +1504,8 @@ module_eval(<<'.,.,', 'parser.y', 171) end .,., -module_eval(<<'.,.,', 'parser.y', 181) - def _reduce_47(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 129) + def _reduce_44(val, _values, result) val[1].each {|hash| hash[:tokens].each {|id| sym = @grammar.add_term(id: id) @@ -1585,8 +1518,8 @@ module_eval(<<'.,.,', 'parser.y', 181) end .,., -module_eval(<<'.,.,', 'parser.y', 191) - def _reduce_48(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 139) + def _reduce_45(val, _values, result) val[1].each {|hash| hash[:tokens].each {|id| sym = @grammar.add_term(id: id) @@ -1599,8 +1532,8 @@ module_eval(<<'.,.,', 'parser.y', 191) end .,., -module_eval(<<'.,.,', 'parser.y', 201) - def _reduce_49(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 149) + def _reduce_46(val, _values, result) val[1].each {|hash| hash[:tokens].each {|id| sym = @grammar.add_term(id: id) @@ -1613,8 +1546,22 @@ module_eval(<<'.,.,', 'parser.y', 201) end .,., -module_eval(<<'.,.,', 'parser.y', 212) - def _reduce_50(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 178) + def _reduce_47(val, _values, result) + result = val[1] ? val[1].unshift(val[0]) : val + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 178) + def _reduce_48(val, _values, result) + result = val[1] ? val[1].unshift(val[0]) : val + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 160) + def _reduce_49(val, _values, result) val[0].each {|token_declaration| @grammar.add_term(id: token_declaration[0], alias_name: token_declaration[2], token_id: token_declaration[1], tag: nil, replace: true) } @@ -1623,8 +1570,8 @@ module_eval(<<'.,.,', 'parser.y', 212) end .,., -module_eval(<<'.,.,', 'parser.y', 218) - def _reduce_51(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 166) + def _reduce_50(val, _values, result) val[1].each {|token_declaration| @grammar.add_term(id: token_declaration[0], alias_name: token_declaration[2], token_id: token_declaration[1], tag: val[0], replace: true) } @@ -1633,8 +1580,8 @@ module_eval(<<'.,.,', 'parser.y', 218) end .,., -module_eval(<<'.,.,', 'parser.y', 224) - def _reduce_52(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 172) + def _reduce_51(val, _values, result) val[2].each {|token_declaration| @grammar.add_term(id: token_declaration[0], alias_name: token_declaration[2], token_id: token_declaration[1], tag: val[1], replace: true) } @@ -1643,29 +1590,23 @@ module_eval(<<'.,.,', 'parser.y', 224) end .,., -module_eval(<<'.,.,', 'parser.y', 229) - def _reduce_53(val, _values, result) - result = [val[0]] - result - end -.,., +# reduce 52 omitted -module_eval(<<'.,.,', 'parser.y', 230) +# reduce 53 omitted + +module_eval(<<'.,.,', 'parser.y', 177) def _reduce_54(val, _values, result) - result = val[0].append(val[1]) - result - end -.,., - -module_eval(<<'.,.,', 'parser.y', 232) - def _reduce_55(val, _values, result) result = val result end .,., -module_eval(<<'.,.,', 'parser.y', 236) - def _reduce_56(val, _values, result) +# reduce 55 omitted + +# reduce 56 omitted + +module_eval(<<'.,.,', 'parser.y', 181) + def _reduce_57(val, _values, result) rule = Grammar::ParameterizingRule::Rule.new(val[1].s_value, val[3], val[7], tag: val[5]) @grammar.add_parameterizing_rule(rule) @@ -1673,8 +1614,8 @@ module_eval(<<'.,.,', 'parser.y', 236) end .,., -module_eval(<<'.,.,', 'parser.y', 242) - def _reduce_57(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 187) + def _reduce_58(val, _values, result) rule = Grammar::ParameterizingRule::Rule.new(val[2].s_value, [], val[4], is_inline: true) @grammar.add_parameterizing_rule(rule) @@ -1682,22 +1623,31 @@ module_eval(<<'.,.,', 'parser.y', 242) end .,., -module_eval(<<'.,.,', 'parser.y', 246) - def _reduce_58(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 192) + def _reduce_59(val, _values, result) + rule = Grammar::ParameterizingRule::Rule.new(val[2].s_value, val[4], val[7], is_inline: true) + @grammar.add_parameterizing_rule(rule) + + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 196) + def _reduce_60(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'parser.y', 247) - def _reduce_59(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 197) + def _reduce_61(val, _values, result) result = val[0].append(val[2]) result end .,., -module_eval(<<'.,.,', 'parser.y', 251) - def _reduce_60(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 201) + def _reduce_62(val, _values, result) builder = val[0] result = [builder] @@ -1705,8 +1655,8 @@ module_eval(<<'.,.,', 'parser.y', 251) end .,., -module_eval(<<'.,.,', 'parser.y', 256) - def _reduce_61(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 206) + def _reduce_63(val, _values, result) builder = val[2] result = val[0].append(builder) @@ -1714,8 +1664,12 @@ module_eval(<<'.,.,', 'parser.y', 256) end .,., -module_eval(<<'.,.,', 'parser.y', 262) - def _reduce_62(val, _values, result) +# reduce 64 omitted + +# reduce 65 omitted + +module_eval(<<'.,.,', 'parser.y', 212) + def _reduce_66(val, _values, result) reset_precs result = Grammar::ParameterizingRule::Rhs.new @@ -1723,17 +1677,8 @@ module_eval(<<'.,.,', 'parser.y', 262) end .,., -module_eval(<<'.,.,', 'parser.y', 267) - def _reduce_63(val, _values, result) - reset_precs - result = Grammar::ParameterizingRule::Rhs.new - - result - end -.,., - -module_eval(<<'.,.,', 'parser.y', 272) - def _reduce_64(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 217) + def _reduce_67(val, _values, result) token = val[1] token.alias_name = val[2] builder = val[0] @@ -1744,8 +1689,8 @@ module_eval(<<'.,.,', 'parser.y', 272) end .,., -module_eval(<<'.,.,', 'parser.y', 280) - def _reduce_65(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 225) + def _reduce_68(val, _values, result) builder = val[0] builder.symbols << Lrama::Lexer::Token::InstantiateRule.new(s_value: val[2], location: @lexer.location, args: [val[1]]) result = builder @@ -1754,8 +1699,8 @@ module_eval(<<'.,.,', 'parser.y', 280) end .,., -module_eval(<<'.,.,', 'parser.y', 286) - def _reduce_66(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 231) + def _reduce_69(val, _values, result) builder = val[0] builder.symbols << Lrama::Lexer::Token::InstantiateRule.new(s_value: val[1].s_value, location: @lexer.location, args: val[3], lhs_tag: val[5]) result = builder @@ -1764,30 +1709,10 @@ module_eval(<<'.,.,', 'parser.y', 286) end .,., -module_eval(<<'.,.,', 'parser.y', 292) - def _reduce_67(val, _values, result) - if @prec_seen - on_action_error("multiple User_code after %prec", val[0]) if @code_after_prec - @code_after_prec = true - end - begin_c_declaration("}") - - result - end -.,., - -module_eval(<<'.,.,', 'parser.y', 300) - def _reduce_68(val, _values, result) - end_c_declaration - - result - end -.,., - -module_eval(<<'.,.,', 'parser.y', 304) - def _reduce_69(val, _values, result) - user_code = val[3] - user_code.alias_name = val[6] +module_eval(<<'.,.,', 'parser.y', 237) + def _reduce_70(val, _values, result) + user_code = val[1] + user_code.alias_name = val[2] builder = val[0] builder.user_code = user_code result = builder @@ -1796,8 +1721,8 @@ module_eval(<<'.,.,', 'parser.y', 304) end .,., -module_eval(<<'.,.,', 'parser.y', 312) - def _reduce_70(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 245) + def _reduce_71(val, _values, result) sym = @grammar.find_symbol_by_id!(val[2]) @prec_seen = true builder = val[0] @@ -1808,168 +1733,137 @@ module_eval(<<'.,.,', 'parser.y', 312) end .,., -# reduce 71 omitted - # reduce 72 omitted -# reduce 73 omitted +module_eval(<<'.,.,', 'parser.y', 253) + def _reduce_73(val, _values, result) + result = val[0].s_value + result + end +.,., -# reduce 74 omitted +module_eval(<<'.,.,', 'parser.y', 260) + def _reduce_74(val, _values, result) + result = val[1] ? val[1].unshift(val[0]) : val + result + end +.,., -module_eval(<<'.,.,', 'parser.y', 327) +module_eval(<<'.,.,', 'parser.y', 260) def _reduce_75(val, _values, result) - result = [{tag: nil, tokens: val[0]}] - + result = val[1] ? val[1].unshift(val[0]) : val result end .,., -module_eval(<<'.,.,', 'parser.y', 331) +module_eval(<<'.,.,', 'parser.y', 255) def _reduce_76(val, _values, result) - result = [{tag: val[0], tokens: val[1]}] - + result = [{tag: nil, tokens: val[0]}] result end .,., -module_eval(<<'.,.,', 'parser.y', 335) +module_eval(<<'.,.,', 'parser.y', 256) def _reduce_77(val, _values, result) - result = val[0].append({tag: val[1], tokens: val[2]}) - + result = [{tag: val[0], tokens: val[1]}] result end .,., -module_eval(<<'.,.,', 'parser.y', 338) +module_eval(<<'.,.,', 'parser.y', 257) def _reduce_78(val, _values, result) - result = [val[0]] + result = val[0].append({tag: val[1], tokens: val[2]}) result end .,., -module_eval(<<'.,.,', 'parser.y', 339) - def _reduce_79(val, _values, result) - result = val[0].append(val[1]) - result - end -.,., +# reduce 79 omitted # reduce 80 omitted -# reduce 81 omitted +module_eval(<<'.,.,', 'parser.y', 263) + def _reduce_81(val, _values, result) + begin_c_declaration("}") -module_eval(<<'.,.,', 'parser.y', 346) + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 267) def _reduce_82(val, _values, result) - begin_c_declaration("}") + end_c_declaration result end .,., -module_eval(<<'.,.,', 'parser.y', 350) +module_eval(<<'.,.,', 'parser.y', 271) def _reduce_83(val, _values, result) - end_c_declaration + result = val[2] result end .,., -module_eval(<<'.,.,', 'parser.y', 354) +module_eval(<<'.,.,', 'parser.y', 279) def _reduce_84(val, _values, result) - result = val[0].append(val[3]) - + result = val[1] ? val[1].unshift(val[0]) : val result end .,., -module_eval(<<'.,.,', 'parser.y', 358) +module_eval(<<'.,.,', 'parser.y', 279) def _reduce_85(val, _values, result) - begin_c_declaration("}") - + result = val[1] ? val[1].unshift(val[0]) : val result end .,., -module_eval(<<'.,.,', 'parser.y', 362) +module_eval(<<'.,.,', 'parser.y', 274) def _reduce_86(val, _values, result) - end_c_declaration - + result = [{tag: nil, tokens: val[0]}] result end .,., -module_eval(<<'.,.,', 'parser.y', 366) +module_eval(<<'.,.,', 'parser.y', 275) def _reduce_87(val, _values, result) - result = [val[2]] - + result = [{tag: val[0], tokens: val[1]}] result end .,., -module_eval(<<'.,.,', 'parser.y', 371) +module_eval(<<'.,.,', 'parser.y', 276) def _reduce_88(val, _values, result) - result = [{tag: nil, tokens: val[0]}] - + result = val[0].append({tag: val[1], tokens: val[2]}) result end .,., -module_eval(<<'.,.,', 'parser.y', 375) +module_eval(<<'.,.,', 'parser.y', 278) def _reduce_89(val, _values, result) - result = [{tag: val[0], tokens: val[1]}] - - result - end -.,., - -module_eval(<<'.,.,', 'parser.y', 379) - def _reduce_90(val, _values, result) - result = val[0].append({tag: val[1], tokens: val[2]}) - - result - end -.,., - -module_eval(<<'.,.,', 'parser.y', 382) - def _reduce_91(val, _values, result) - result = [val[0]] - result - end -.,., - -module_eval(<<'.,.,', 'parser.y', 383) - def _reduce_92(val, _values, result) - result = val[0].append(val[1]) - result - end -.,., - -# reduce 93 omitted - -module_eval(<<'.,.,', 'parser.y', 387) - def _reduce_94(val, _values, result) on_action_error("ident after %prec", val[0]) if @prec_seen result end .,., -module_eval(<<'.,.,', 'parser.y', 388) - def _reduce_95(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 279) + def _reduce_90(val, _values, result) on_action_error("char after %prec", val[0]) if @prec_seen result end .,., -# reduce 96 omitted +# reduce 91 omitted -# reduce 97 omitted +# reduce 92 omitted -# reduce 98 omitted +# reduce 93 omitted -# reduce 99 omitted +# reduce 94 omitted -module_eval(<<'.,.,', 'parser.y', 398) - def _reduce_100(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 287) + def _reduce_95(val, _values, result) lhs = val[0] lhs.alias_name = val[1] val[3].each do |builder| @@ -1982,8 +1876,8 @@ module_eval(<<'.,.,', 'parser.y', 398) end .,., -module_eval(<<'.,.,', 'parser.y', 409) - def _reduce_101(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 298) + def _reduce_96(val, _values, result) builder = val[0] if !builder.line builder.line = @lexer.line - 1 @@ -1994,8 +1888,8 @@ module_eval(<<'.,.,', 'parser.y', 409) end .,., -module_eval(<<'.,.,', 'parser.y', 417) - def _reduce_102(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 306) + def _reduce_97(val, _values, result) builder = val[2] if !builder.line builder.line = @lexer.line - 1 @@ -2006,28 +1900,17 @@ module_eval(<<'.,.,', 'parser.y', 417) end .,., -# reduce 103 omitted - -module_eval(<<'.,.,', 'parser.y', 427) - def _reduce_104(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 315) + def _reduce_98(val, _values, result) reset_precs - result = Grammar::RuleBuilder.new(@rule_counter, @midrule_action_counter) + result = @grammar.create_rule_builder(@rule_counter, @midrule_action_counter) result end .,., -module_eval(<<'.,.,', 'parser.y', 432) - def _reduce_105(val, _values, result) - reset_precs - result = Grammar::RuleBuilder.new(@rule_counter, @midrule_action_counter) - - result - end -.,., - -module_eval(<<'.,.,', 'parser.y', 437) - def _reduce_106(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 320) + def _reduce_99(val, _values, result) token = val[1] token.alias_name = val[2] builder = val[0] @@ -2038,9 +1921,9 @@ module_eval(<<'.,.,', 'parser.y', 437) end .,., -module_eval(<<'.,.,', 'parser.y', 445) - def _reduce_107(val, _values, result) - token = Lrama::Lexer::Token::InstantiateRule.new(s_value: val[2], location: @lexer.location, args: [val[1]], lhs_tag: val[3]) +module_eval(<<'.,.,', 'parser.y', 328) + def _reduce_100(val, _values, result) + token = Lrama::Lexer::Token::InstantiateRule.new(s_value: val[2], alias_name: val[3], location: @lexer.location, args: [val[1]], lhs_tag: val[4]) builder = val[0] builder.add_rhs(token) builder.line = val[1].first_line @@ -2050,9 +1933,9 @@ module_eval(<<'.,.,', 'parser.y', 445) end .,., -module_eval(<<'.,.,', 'parser.y', 453) - def _reduce_108(val, _values, result) - token = Lrama::Lexer::Token::InstantiateRule.new(s_value: val[1].s_value, location: @lexer.location, args: val[3], lhs_tag: val[5]) +module_eval(<<'.,.,', 'parser.y', 336) + def _reduce_101(val, _values, result) + token = Lrama::Lexer::Token::InstantiateRule.new(s_value: val[1].s_value, alias_name: val[5], location: @lexer.location, args: val[3], lhs_tag: val[6]) builder = val[0] builder.add_rhs(token) builder.line = val[1].first_line @@ -2062,31 +1945,11 @@ module_eval(<<'.,.,', 'parser.y', 453) end .,., -module_eval(<<'.,.,', 'parser.y', 461) - def _reduce_109(val, _values, result) - if @prec_seen - on_action_error("multiple User_code after %prec", val[0]) if @code_after_prec - @code_after_prec = true - end - begin_c_declaration("}") - - result - end -.,., - -module_eval(<<'.,.,', 'parser.y', 469) - def _reduce_110(val, _values, result) - end_c_declaration - - result - end -.,., - -module_eval(<<'.,.,', 'parser.y', 473) - def _reduce_111(val, _values, result) - user_code = val[3] - user_code.alias_name = val[6] - user_code.tag = val[7] +module_eval(<<'.,.,', 'parser.y', 344) + def _reduce_102(val, _values, result) + user_code = val[1] + user_code.alias_name = val[2] + user_code.tag = val[3] builder = val[0] builder.user_code = user_code result = builder @@ -2095,8 +1958,8 @@ module_eval(<<'.,.,', 'parser.y', 473) end .,., -module_eval(<<'.,.,', 'parser.y', 482) - def _reduce_112(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 353) + def _reduce_103(val, _values, result) sym = @grammar.find_symbol_by_id!(val[2]) @prec_seen = true builder = val[0] @@ -2107,125 +1970,133 @@ module_eval(<<'.,.,', 'parser.y', 482) end .,., -module_eval(<<'.,.,', 'parser.y', 489) - def _reduce_113(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 360) + def _reduce_104(val, _values, result) result = "option" result end .,., -module_eval(<<'.,.,', 'parser.y', 490) - def _reduce_114(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 361) + def _reduce_105(val, _values, result) result = "nonempty_list" result end .,., -module_eval(<<'.,.,', 'parser.y', 491) - def _reduce_115(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 362) + def _reduce_106(val, _values, result) result = "list" result end .,., -module_eval(<<'.,.,', 'parser.y', 493) - def _reduce_116(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 364) + def _reduce_107(val, _values, result) result = [val[0]] result end .,., -module_eval(<<'.,.,', 'parser.y', 494) - def _reduce_117(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 365) + def _reduce_108(val, _values, result) result = val[0].append(val[2]) result end .,., -module_eval(<<'.,.,', 'parser.y', 495) - def _reduce_118(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 366) + def _reduce_109(val, _values, result) result = [Lrama::Lexer::Token::InstantiateRule.new(s_value: val[1].s_value, location: @lexer.location, args: val[0])] result end .,., -module_eval(<<'.,.,', 'parser.y', 496) - def _reduce_119(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 367) + def _reduce_110(val, _values, result) result = [Lrama::Lexer::Token::InstantiateRule.new(s_value: val[0].s_value, location: @lexer.location, args: val[2])] result end .,., -# reduce 120 omitted +module_eval(<<'.,.,', 'parser.y', 371) + def _reduce_111(val, _values, result) + if @prec_seen + on_action_error("multiple User_code after %prec", val[0]) if @code_after_prec + @code_after_prec = true + end + begin_c_declaration("}") -module_eval(<<'.,.,', 'parser.y', 499) - def _reduce_121(val, _values, result) + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 379) + def _reduce_112(val, _values, result) + end_c_declaration + + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 383) + def _reduce_113(val, _values, result) + result = val[2] + + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 386) + def _reduce_114(val, _values, result) result = val[1].s_value result end .,., +module_eval(<<'.,.,', 'parser.y', 390) + def _reduce_115(val, _values, result) + begin_c_declaration('\Z') + @grammar.epilogue_first_lineno = @lexer.line + 1 + + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 395) + def _reduce_116(val, _values, result) + end_c_declaration + @grammar.epilogue = val[2].s_value + + result + end +.,., + +# reduce 117 omitted + +# reduce 118 omitted + +# reduce 119 omitted + +# reduce 120 omitted + +# reduce 121 omitted + # reduce 122 omitted # reduce 123 omitted -module_eval(<<'.,.,', 'parser.y', 506) - def _reduce_124(val, _values, result) - begin_c_declaration('\Z') - @grammar.epilogue_first_lineno = @lexer.line + 1 +# reduce 124 omitted - result - end -.,., +# reduce 125 omitted -module_eval(<<'.,.,', 'parser.y', 511) - def _reduce_125(val, _values, result) - end_c_declaration - @grammar.epilogue = val[2].s_value - - result - end -.,., - -# reduce 126 omitted - -# reduce 127 omitted - -# reduce 128 omitted - -# reduce 129 omitted - -# reduce 130 omitted - -module_eval(<<'.,.,', 'parser.y', 522) - def _reduce_131(val, _values, result) - result = [val[0]] - result - end -.,., - -module_eval(<<'.,.,', 'parser.y', 523) - def _reduce_132(val, _values, result) - result = val[0].append(val[1]) - result - end -.,., - -# reduce 133 omitted - -# reduce 134 omitted - -module_eval(<<'.,.,', 'parser.y', 528) - def _reduce_135(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 412) + def _reduce_126(val, _values, result) result = Lrama::Lexer::Token::Ident.new(s_value: val[0]) result end .,., -# reduce 136 omitted - -# reduce 137 omitted - def _reduce_none(val, _values, result) val[0] end diff --git a/tool/lrama/lib/lrama/report.rb b/tool/lrama/lib/lrama/report.rb index 650ac09d52..890e5f1e8c 100644 --- a/tool/lrama/lib/lrama/report.rb +++ b/tool/lrama/lib/lrama/report.rb @@ -1,2 +1,4 @@ -require 'lrama/report/duration' -require 'lrama/report/profile' +# frozen_string_literal: true + +require_relative 'report/duration' +require_relative 'report/profile' diff --git a/tool/lrama/lib/lrama/report/duration.rb b/tool/lrama/lib/lrama/report/duration.rb index 7afe284f1a..fe09a0d028 100644 --- a/tool/lrama/lib/lrama/report/duration.rb +++ b/tool/lrama/lib/lrama/report/duration.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Report module Duration diff --git a/tool/lrama/lib/lrama/report/profile.rb b/tool/lrama/lib/lrama/report/profile.rb index 36156800a4..10488cf913 100644 --- a/tool/lrama/lib/lrama/report/profile.rb +++ b/tool/lrama/lib/lrama/report/profile.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class Report module Profile diff --git a/tool/lrama/lib/lrama/state.rb b/tool/lrama/lib/lrama/state.rb index ceb74d856a..c2623746aa 100644 --- a/tool/lrama/lib/lrama/state.rb +++ b/tool/lrama/lib/lrama/state.rb @@ -1,8 +1,10 @@ -require "lrama/state/reduce" -require "lrama/state/reduce_reduce_conflict" -require "lrama/state/resolved_conflict" -require "lrama/state/shift" -require "lrama/state/shift_reduce_conflict" +# frozen_string_literal: true + +require_relative "state/reduce" +require_relative "state/reduce_reduce_conflict" +require_relative "state/resolved_conflict" +require_relative "state/shift" +require_relative "state/shift_reduce_conflict" module Lrama class State diff --git a/tool/lrama/lib/lrama/state/reduce.rb b/tool/lrama/lib/lrama/state/reduce.rb index 8ba51f45f2..a2b7c26cfe 100644 --- a/tool/lrama/lib/lrama/state/reduce.rb +++ b/tool/lrama/lib/lrama/state/reduce.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class State class Reduce @@ -25,6 +27,7 @@ module Lrama def selected_look_ahead if @look_ahead + # @type ivar @look_ahead: Array @look_ahead - @not_selected_symbols else [] diff --git a/tool/lrama/lib/lrama/state/reduce_reduce_conflict.rb b/tool/lrama/lib/lrama/state/reduce_reduce_conflict.rb index 0a0e4dc20a..736d08376a 100644 --- a/tool/lrama/lib/lrama/state/reduce_reduce_conflict.rb +++ b/tool/lrama/lib/lrama/state/reduce_reduce_conflict.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class State class ReduceReduceConflict < Struct.new(:symbols, :reduce1, :reduce2, keyword_init: true) diff --git a/tool/lrama/lib/lrama/state/resolved_conflict.rb b/tool/lrama/lib/lrama/state/resolved_conflict.rb index 02ea892147..3bb3d1446e 100644 --- a/tool/lrama/lib/lrama/state/resolved_conflict.rb +++ b/tool/lrama/lib/lrama/state/resolved_conflict.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class State # * symbol: A symbol under discussion @@ -6,7 +8,7 @@ module Lrama class ResolvedConflict < Struct.new(:symbol, :reduce, :which, :same_prec, keyword_init: true) def report_message s = symbol.display_name - r = reduce.rule.precedence_sym.display_name + r = reduce.rule.precedence_sym&.display_name case when which == :shift && same_prec msg = "resolved as #{which} (%right #{s})" diff --git a/tool/lrama/lib/lrama/state/shift.rb b/tool/lrama/lib/lrama/state/shift.rb index 2021eb61f6..81ef013a17 100644 --- a/tool/lrama/lib/lrama/state/shift.rb +++ b/tool/lrama/lib/lrama/state/shift.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class State class Shift diff --git a/tool/lrama/lib/lrama/state/shift_reduce_conflict.rb b/tool/lrama/lib/lrama/state/shift_reduce_conflict.rb index f80bd5f352..fd66834539 100644 --- a/tool/lrama/lib/lrama/state/shift_reduce_conflict.rb +++ b/tool/lrama/lib/lrama/state/shift_reduce_conflict.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class State class ShiftReduceConflict < Struct.new(:symbols, :shift, :reduce, keyword_init: true) diff --git a/tool/lrama/lib/lrama/states.rb b/tool/lrama/lib/lrama/states.rb index 290e996b82..0ed4bff9c1 100644 --- a/tool/lrama/lib/lrama/states.rb +++ b/tool/lrama/lib/lrama/states.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require "forwardable" -require "lrama/report/duration" -require "lrama/states/item" +require_relative "report/duration" +require_relative "states/item" module Lrama # States is passed to a template file @@ -16,9 +18,8 @@ module Lrama attr_reader :states, :reads_relation, :includes_relation, :lookback_relation - def initialize(grammar, warning, trace_state: false) + def initialize(grammar, trace_state: false) @grammar = grammar - @warning = warning @trace_state = trace_state @states = [] @@ -89,8 +90,6 @@ module Lrama report_duration(:compute_conflicts) { compute_conflicts } report_duration(:compute_default_reduction) { compute_default_reduction } - - check_conflicts end def reporter @@ -125,16 +124,16 @@ module Lrama end end + def sr_conflicts_count + @sr_conflicts_count ||= @states.flat_map(&:sr_conflicts).count + end + + def rr_conflicts_count + @rr_conflicts_count ||= @states.flat_map(&:rr_conflicts).count + end + private - def sr_conflicts - @states.flat_map(&:sr_conflicts) - end - - def rr_conflicts - @states.flat_map(&:rr_conflicts) - end - def trace_state if @trace_state yield STDERR @@ -350,7 +349,7 @@ module Lrama # TODO: need to omit if state == state2 ? @includes_relation[key] ||= [] @includes_relation[key] << [state.id, nterm.token_id] - break if !sym.nullable + break unless sym.nullable i -= 1 end end @@ -385,7 +384,7 @@ module Lrama @states.each do |state| rules.each do |rule| ary = @lookback_relation[[state.id, rule.id]] - next if !ary + next unless ary ary.each do |state2_id, nterm_token_id| # q = state, A -> ω = rule, p = state2, A = nterm @@ -428,7 +427,7 @@ module Lrama sym = shift.next_sym next unless reduce.look_ahead - next if !reduce.look_ahead.include?(sym) + next unless reduce.look_ahead.include?(sym) # Shift/Reduce conflict shift_prec = sym.precedence @@ -492,17 +491,17 @@ module Lrama states.each do |state| count = state.reduces.count - for i in 0...count do + (0...count).each do |i| reduce1 = state.reduces[i] next if reduce1.look_ahead.nil? - for j in (i+1)...count do + ((i+1)...count).each do |j| reduce2 = state.reduces[j] next if reduce2.look_ahead.nil? intersection = reduce1.look_ahead & reduce2.look_ahead - if !intersection.empty? + unless intersection.empty? state.conflicts << State::ReduceReduceConflict.new(symbols: intersection, reduce1: reduce1, reduce2: reduce2) end end @@ -514,7 +513,7 @@ module Lrama states.each do |state| next if state.reduces.empty? # Do not set, if conflict exist - next if !state.conflicts.empty? + next unless state.conflicts.empty? # Do not set, if shift with `error` exists. next if state.shifts.map(&:next_sym).include?(@grammar.error_symbol) @@ -525,32 +524,5 @@ module Lrama end.first end end - - def check_conflicts - sr_count = sr_conflicts.count - rr_count = rr_conflicts.count - - if @grammar.expect - - expected_sr_conflicts = @grammar.expect - expected_rr_conflicts = 0 - - if expected_sr_conflicts != sr_count - @warning.error("shift/reduce conflicts: #{sr_count} found, #{expected_sr_conflicts} expected") - end - - if expected_rr_conflicts != rr_count - @warning.error("reduce/reduce conflicts: #{rr_count} found, #{expected_rr_conflicts} expected") - end - else - if sr_count != 0 - @warning.warn("shift/reduce conflicts: #{sr_count} found") - end - - if rr_count != 0 - @warning.warn("reduce/reduce conflicts: #{rr_count} found") - end - end - end end end diff --git a/tool/lrama/lib/lrama/states/item.rb b/tool/lrama/lib/lrama/states/item.rb index 31b74b9d34..5074e943b7 100644 --- a/tool/lrama/lib/lrama/states/item.rb +++ b/tool/lrama/lib/lrama/states/item.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # TODO: Validate position is not over rule rhs require "forwardable" @@ -54,11 +56,11 @@ module Lrama Item.new(rule: rule, position: position + 1) end - def symbols_before_dot + def symbols_before_dot # steep:ignore rhs[0...position] end - def symbols_after_dot + def symbols_after_dot # steep:ignore rhs[position..-1] end @@ -73,7 +75,7 @@ module Lrama # Right after position def display_rest - r = rhs[position..-1].map(&:display_name).join(" ") + r = symbols_after_dot.map(&:display_name).join(" ") ". #{r} (rule #{rule_id})" end end diff --git a/tool/lrama/lib/lrama/states_reporter.rb b/tool/lrama/lib/lrama/states_reporter.rb index 6f96cc6f65..64ff4de100 100644 --- a/tool/lrama/lib/lrama/states_reporter.rb +++ b/tool/lrama/lib/lrama/states_reporter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama class StatesReporter include Lrama::Report::Duration @@ -14,15 +16,54 @@ module Lrama private - def _report(io, grammar: false, states: false, itemsets: false, lookaheads: false, solved: false, counterexamples: false, verbose: false) - # TODO: Unused terms - # TODO: Unused rules - + def _report(io, grammar: false, rules: false, terms: false, states: false, itemsets: false, lookaheads: false, solved: false, counterexamples: false, verbose: false) + report_unused_rules(io) if rules + report_unused_terms(io) if terms report_conflicts(io) report_grammar(io) if grammar report_states(io, itemsets, lookaheads, solved, counterexamples, verbose) end + def report_unused_terms(io) + look_aheads = @states.states.each do |state| + state.reduces.flat_map do |reduce| + reduce.look_ahead unless reduce.look_ahead.nil? + end + end + + next_terms = @states.states.flat_map do |state| + state.shifts.map(&:next_sym).select(&:term?) + end + + unused_symbols = @states.terms.select do |term| + !(look_aheads + next_terms).include?(term) + end + + unless unused_symbols.empty? + io << "#{unused_symbols.count} Unused Terms\n\n" + unused_symbols.each_with_index do |term, index| + io << sprintf("%5d %s\n", index, term.id.s_value) + end + io << "\n\n" + end + end + + def report_unused_rules(io) + used_rules = @states.rules.flat_map(&:rhs) + + unused_rules = @states.rules.map(&:lhs).select do |rule| + !used_rules.include?(rule) && rule.token_id != 0 + end + + unless unused_rules.empty? + io << "#{unused_rules.count} Unused Rules\n\n" + unused_rules.each_with_index do |rule, index| + io << sprintf("%5d %s\n", index, rule.display_name) + end + io << "\n\n" + end + end + def report_conflicts(io) has_conflict = false @@ -37,7 +78,7 @@ module Lrama messages << "#{cs[:reduce_reduce].count} reduce/reduce" end - if !messages.empty? + unless messages.empty? has_conflict = true io << "State #{state.id} conflicts: #{messages.join(', ')}\n" end @@ -98,7 +139,7 @@ module Lrama if lookaheads && item.end_of_rule? reduce = state.find_reduce_by_item!(item) look_ahead = reduce.selected_look_ahead - if !look_ahead.empty? + unless look_ahead.empty? la = " [#{look_ahead.map(&:display_name).join(", ")}]" end end @@ -118,7 +159,7 @@ module Lrama tmp.each do |term, state_id| io << " #{term.display_name.ljust(max_len)} shift, and go to state #{state_id}\n" end - io << "\n" if !tmp.empty? + io << "\n" unless tmp.empty? # Report error caused by %nonassoc nl = false @@ -132,7 +173,7 @@ module Lrama nl = true io << " #{name.ljust(max_len)} error (nonassociative)\n" end - io << "\n" if !tmp.empty? + io << "\n" unless tmp.empty? # Report reduces nl = false @@ -181,14 +222,14 @@ module Lrama tmp.each do |nterm, state_id| io << " #{nterm.id.s_value.ljust(max_len)} go to state #{state_id}\n" end - io << "\n" if !tmp.empty? + io << "\n" unless tmp.empty? if solved # Report conflict resolutions state.resolved_conflicts.each do |resolved| io << " #{resolved.report_message}\n" end - io << "\n" if !state.resolved_conflicts.empty? + io << "\n" unless state.resolved_conflicts.empty? end if counterexamples && state.has_conflicts? @@ -219,7 +260,7 @@ module Lrama direct_read_sets = @states.direct_read_sets @states.nterms.each do |nterm| terms = direct_read_sets[[state.id, nterm.token_id]] - next if !terms + next unless terms next if terms.empty? str = terms.map {|sym| sym.id.s_value }.join(", ") @@ -231,7 +272,7 @@ module Lrama io << " [Reads Relation]\n" @states.nterms.each do |nterm| a = @states.reads_relation[[state.id, nterm.token_id]] - next if !a + next unless a a.each do |state_id2, nterm_id2| n = @states.nterms.find {|n| n.token_id == nterm_id2 } @@ -245,7 +286,7 @@ module Lrama read_sets = @states.read_sets @states.nterms.each do |nterm| terms = read_sets[[state.id, nterm.token_id]] - next if !terms + next unless terms next if terms.empty? terms.each do |sym| @@ -258,7 +299,7 @@ module Lrama io << " [Includes Relation]\n" @states.nterms.each do |nterm| a = @states.includes_relation[[state.id, nterm.token_id]] - next if !a + next unless a a.each do |state_id2, nterm_id2| n = @states.nterms.find {|n| n.token_id == nterm_id2 } @@ -271,11 +312,11 @@ module Lrama io << " [Lookback Relation]\n" @states.rules.each do |rule| a = @states.lookback_relation[[state.id, rule.id]] - next if !a + next unless a a.each do |state_id2, nterm_id2| n = @states.nterms.find {|n| n.token_id == nterm_id2 } - io << " (Rule: #{rule}) -> (State #{state_id2}, #{n.id.s_value})\n" + io << " (Rule: #{rule.display_name}) -> (State #{state_id2}, #{n.id.s_value})\n" end end io << "\n" @@ -286,7 +327,7 @@ module Lrama @states.nterms.each do |nterm| terms = follow_sets[[state.id, nterm.token_id]] - next if !terms + next unless terms terms.each do |sym| io << " #{nterm.id.s_value} -> #{sym.id.s_value}\n" @@ -300,7 +341,7 @@ module Lrama max_len = 0 @states.rules.each do |rule| syms = @states.la[[state.id, rule.id]] - next if !syms + next unless syms tmp << [rule, syms] max_len = ([max_len] + syms.map {|s| s.id.s_value.length }).max @@ -310,7 +351,7 @@ module Lrama io << " #{sym.id.s_value.ljust(max_len)} reduce using rule #{rule.id} (#{rule.lhs.id.s_value})\n" end end - io << "\n" if !tmp.empty? + io << "\n" unless tmp.empty? end # End of Report State diff --git a/tool/lrama/lib/lrama/trace_reporter.rb b/tool/lrama/lib/lrama/trace_reporter.rb new file mode 100644 index 0000000000..87c01a4c8a --- /dev/null +++ b/tool/lrama/lib/lrama/trace_reporter.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module Lrama + class TraceReporter + def initialize(grammar) + @grammar = grammar + end + + def report(**options) + _report(**options) + end + + private + + def _report(rules: false, actions: false, **_) + report_rules if rules + report_actions if actions + end + + def report_rules + puts "Grammar rules:" + @grammar.rules.each { |rule| puts rule.display_name } + end + + def report_actions + puts "Grammar rules with actions:" + @grammar.rules.each { |rule| puts rule.with_actions } + end + end +end diff --git a/tool/lrama/lib/lrama/version.rb b/tool/lrama/lib/lrama/version.rb index ef840ce435..d452430b3e 100644 --- a/tool/lrama/lib/lrama/version.rb +++ b/tool/lrama/lib/lrama/version.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Lrama - VERSION = "0.6.9".freeze + VERSION = "0.6.10".freeze end diff --git a/tool/lrama/template/bison/yacc.c b/tool/lrama/template/bison/yacc.c index 2d6753c282..6edd59a0d5 100644 --- a/tool/lrama/template/bison/yacc.c +++ b/tool/lrama/template/bison/yacc.c @@ -1166,9 +1166,9 @@ yydestruct (const char *yymsg, #endif enum yy_repair_type { - insert, - delete, - shift, + inserting, + deleting, + shifting, }; struct yy_repair { @@ -1401,27 +1401,27 @@ yyrecover(yy_state_t *yyss, yy_state_t *yyssp, int yychar<%= output.user_formals if (current->repair_length + 1 > YYMAXREPAIR(<%= output.parse_param_name %>)) continue; - yy_repairs *new = (yy_repairs *) YYMALLOC (sizeof (yy_repairs)); - new->id = count; - new->next = 0; - new->stack_length = stack_length; - new->states = (yy_state_t *) YYMALLOC (sizeof (yy_state_t) * (stack_length)); - new->state = new->states + (current->state - current->states); - YYCOPY (new->states, current->states, current->state - current->states + 1); - new->repair_length = current->repair_length + 1; - new->prev_repair = current; - new->repair.type = insert; - new->repair.term = (yysymbol_kind_t) yyx; + yy_repairs *reps = (yy_repairs *) YYMALLOC (sizeof (yy_repairs)); + reps->id = count; + reps->next = 0; + reps->stack_length = stack_length; + reps->states = (yy_state_t *) YYMALLOC (sizeof (yy_state_t) * (stack_length)); + reps->state = reps->states + (current->state - current->states); + YYCOPY (reps->states, current->states, current->state - current->states + 1); + reps->repair_length = current->repair_length + 1; + reps->prev_repair = current; + reps->repair.type = inserting; + reps->repair.term = (yysymbol_kind_t) yyx; /* Process PDA assuming next token is yyx */ - if (! yy_process_repairs (new, yyx)) + if (! yy_process_repairs (reps, (yysymbol_kind_t)yyx)) { - YYFREE (new); + YYFREE (reps); continue; } - tail->next = new; - tail = new; + tail->next = reps; + tail = reps; count++; if (yyx == yytoken) @@ -1437,7 +1437,7 @@ yyrecover(yy_state_t *yyss, yy_state_t *yyssp, int yychar<%= output.user_formals YYDPRINTF ((stderr, "New repairs is enqueued. count: %d, yystate: %d, yyx: %d\n", count, yystate, yyx)); - yy_print_repairs (new<%= output.user_args %>); + yy_print_repairs (reps<%= output.user_args %>); } } } @@ -1475,7 +1475,12 @@ int yychar; /* The semantic value of the lookahead symbol. */ /* Default value used for initialization, for pacifying older GCCs or non-GCC compilers. */ +#ifdef __cplusplus +static const YYSTYPE yyval_default = {}; +(void) yyval_default; +#else YY_INITIAL_VALUE (static const YYSTYPE yyval_default;) +#endif YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); /* Location data for the lookahead symbol. */