Class: Ibex::LALR::Builder
- Inherits:
-
Object
- Object
- Ibex::LALR::Builder
- Defined in:
- lib/ibex/lalr/builder.rb
Overview
Builds deterministic SLR, direct LALR(1), or canonical LR(1) automata. rubocop:disable Metrics/ClassLength -- collection strategies share one action/conflict construction path.
Constant Summary collapse
- AUGMENTED_PRODUCTION =
: Integer
-1 #: Integer
- ALGORITHMS =
: Array
%i[slr lalr ielr lr1].freeze
- LALR_STRATEGIES =
: Array
%i[direct canonical_merge].freeze
Instance Attribute Summary collapse
- #metrics ⇒ Object readonly
Instance Method Summary collapse
- #build ⇒ Object
-
#initialize(grammar, algorithm: :lalr, lalr_strategy: :direct, entry_isolation: false, starts: nil, attribute_entries: true) ⇒ Builder
constructor
A new instance of Builder.
Constructor Details
#initialize(grammar, algorithm: :lalr, lalr_strategy: :direct, entry_isolation: false, starts: nil, attribute_entries: true) ⇒ Builder
Returns a new instance of Builder.
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/ibex/lalr/builder.rb', line 33 def initialize(grammar, algorithm: :lalr, lalr_strategy: :direct, entry_isolation: false, starts: nil, attribute_entries: true) unless ALGORITHMS.include?(algorithm.to_sym) raise ArgumentError, "unknown parser algorithm #{algorithm.inspect}" end unless LALR_STRATEGIES.include?(lalr_strategy.to_sym) raise ArgumentError, "unknown LALR construction strategy #{lalr_strategy.inspect}" end @grammar = grammar @algorithm = algorithm.to_sym @lalr_strategy = lalr_strategy.to_sym @sets = Analysis::Sets.new(grammar) @productions_by_lhs = grammar.productions.group_by(&:lhs) @resolver = ConflictResolver.new(grammar) @metrics = nil @canonical_suffix_lookahead_cache = {} @canonical_item_cache = nil @canonical_key_radices = nil @start_names = starts || grammar.starts if @start_names.empty? || (@start_names - grammar.starts).any? raise ArgumentError, "starts must be a nonempty subset of grammar starts" end @entry_isolation = entry_isolation @attribute_entries = attribute_entries end |
Instance Attribute Details
#metrics ⇒ Object (readonly)
29 30 31 |
# File 'lib/ibex/lalr/builder.rb', line 29 def metrics @metrics end |
Instance Method Details
#build ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/ibex/lalr/builder.rb', line 62 def build return build_isolated_automaton if @entry_isolation && @start_names.length > 1 merged_items, merged_transitions, construction_states, canonical_states, strategy = automaton_collection states = build_states(merged_items, merged_transitions) states = OnErrorReductions.apply(@grammar, states) states = DefaultReductions.apply(states, terminal_ids: @grammar.terminals.map(&:id)) entry_states = entry_states_for(merged_items) states = attribute_entry_conflicts(states, entry_states) if @attribute_entries && @start_names.length > 1 summary = conflict_summary(states) @metrics = BuildMetrics.new( construction_states: construction_states, canonical_states: canonical_states, final_states: states.length, strategy: strategy ) IR::Automaton.new(grammar: @grammar, states: states, conflict_summary: summary, algorithm: algorithm_name, entry_states: entry_states) end |