Class: Ibex::IR::Automaton
- Inherits:
-
Object
- Object
- Ibex::IR::Automaton
- Defined in:
- lib/ibex/ir/automaton_ir.rb,
sig/ibex/ir/automaton_ir.rbs
Overview
Immutable LALR automaton and its source grammar.
Instance Attribute Summary collapse
- #algorithm ⇒ String readonly
- #conflict_summary ⇒ conflict_summary readonly
- #entry_construction ⇒ String readonly
- #entry_states ⇒ Hash[String, Integer] readonly
- #grammar ⇒ Grammar readonly
- #grammar_digest ⇒ String readonly
- #schema_version ⇒ Integer readonly
- #states ⇒ Array[AutomatonState] readonly
Instance Method Summary collapse
- #digest_for(grammar) ⇒ String
-
#initialize(grammar:, states:, conflict_summary:, algorithm: "lalr1", grammar_digest: nil, entry_states: nil, entry_construction: "shared") ⇒ Automaton
constructor
A new instance of Automaton.
- #initialize_current(grammar:, states:, conflict_summary:, algorithm:, grammar_digest:, entry_states:, entry_construction:) ⇒ void
- #to_h ⇒ Hash[Symbol, Object?]
- #validate_entry_construction(value) ⇒ String
- #validate_entry_states ⇒ void
- #validate_parser_algorithm(contract) ⇒ void
- #validate_parser_contract ⇒ void
- #validate_parser_entries(contract) ⇒ void
Constructor Details
#initialize(grammar:, states:, conflict_summary:, algorithm: "lalr1", grammar_digest: nil, entry_states: nil, entry_construction: "shared") ⇒ Automaton
Returns a new instance of Automaton.
85 86 87 88 89 90 91 |
# File 'lib/ibex/ir/automaton_ir.rb', line 85 def initialize(grammar:, states:, conflict_summary:, algorithm: "lalr1", grammar_digest: nil, entry_states: nil, entry_construction: "shared") initialize_current( grammar: grammar, states: states, conflict_summary: conflict_summary, algorithm: algorithm, grammar_digest: grammar_digest, entry_states: entry_states, entry_construction: entry_construction ) end |
Instance Attribute Details
#algorithm ⇒ String (readonly)
73 74 75 |
# File 'lib/ibex/ir/automaton_ir.rb', line 73 def algorithm @algorithm end |
#conflict_summary ⇒ conflict_summary (readonly)
78 79 80 |
# File 'lib/ibex/ir/automaton_ir.rb', line 78 def conflict_summary @conflict_summary end |
#entry_construction ⇒ String (readonly)
80 81 82 |
# File 'lib/ibex/ir/automaton_ir.rb', line 80 def entry_construction @entry_construction end |
#entry_states ⇒ Hash[String, Integer] (readonly)
77 78 79 |
# File 'lib/ibex/ir/automaton_ir.rb', line 77 def entry_states @entry_states end |
#grammar ⇒ Grammar (readonly)
75 76 77 |
# File 'lib/ibex/ir/automaton_ir.rb', line 75 def grammar @grammar end |
#grammar_digest ⇒ String (readonly)
74 75 76 |
# File 'lib/ibex/ir/automaton_ir.rb', line 74 def grammar_digest @grammar_digest end |
#schema_version ⇒ Integer (readonly)
79 80 81 |
# File 'lib/ibex/ir/automaton_ir.rb', line 79 def schema_version @schema_version end |
#states ⇒ Array[AutomatonState] (readonly)
76 77 78 |
# File 'lib/ibex/ir/automaton_ir.rb', line 76 def states @states end |
Instance Method Details
#digest_for(grammar) ⇒ String
149 150 151 152 |
# File 'lib/ibex/ir/automaton_ir.rb', line 149 def digest_for(grammar) require "digest" "sha256:#{Digest::SHA256.hexdigest(IR::Serialize.dump(grammar))}" end |
#initialize_current(grammar:, states:, conflict_summary:, algorithm:, grammar_digest:, entry_states:, entry_construction:) ⇒ void
This method returns an undefined value.
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/ibex/ir/automaton_ir.rb', line 96 def initialize_current(grammar:, states:, conflict_summary:, algorithm:, grammar_digest:, entry_states:, entry_construction:) unless grammar.schema_version == SCHEMA_VERSION raise Ibex::Error, "automaton requires the current Grammar IR format" end @algorithm = algorithm.freeze @grammar = grammar expected_digest = digest_for(grammar) if grammar_digest && grammar_digest != expected_digest raise Ibex::Error, "(ir):1:1: $.grammar_digest does not match the embedded grammar; expected #{expected_digest.inspect}" end @grammar_digest = (grammar_digest || expected_digest).freeze @states = states.freeze @entry_states = IR.deep_freeze(entry_states || { grammar.start => 0 }) validate_entry_states @conflict_summary = IR.deep_freeze(conflict_summary) @schema_version = SCHEMA_VERSION @entry_construction = validate_entry_construction(entry_construction) validate_parser_contract freeze end |
#to_h ⇒ Hash[Symbol, Object?]
122 123 124 125 126 127 128 129 130 |
# File 'lib/ibex/ir/automaton_ir.rb', line 122 def to_h value = { ibex_ir: "automaton", schema_version: @schema_version, algorithm: @algorithm, grammar_digest: @grammar_digest, grammar: @grammar.to_h, states: @states.map { |state| state.to_h(@grammar) }, conflict_summary: @conflict_summary } #: Hash[Symbol, Object?] value[:entry_states] = @entry_states unless @entry_states == { @grammar.start => 0 } value[:entry_construction] = @entry_construction value end |
#validate_entry_construction(value) ⇒ String
155 156 157 158 159 |
# File 'lib/ibex/ir/automaton_ir.rb', line 155 def validate_entry_construction(value) raise Ibex::Error, "entry construction must be shared or isolated" unless %w[shared isolated].include?(value) value.dup.freeze end |
#validate_entry_states ⇒ void
This method returns an undefined value.
135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/ibex/ir/automaton_ir.rb', line 135 def validate_entry_states ordered = @grammar.starts.select { |name| @entry_states.key?(name) } unless @entry_states.any? && @entry_states.keys == ordered raise Ibex::Error, "(ir):1:1: automaton entry states must be an ordered subset of grammar starts" end @entry_states.each do |name, state| next if state.between?(0, @states.length - 1) raise Ibex::Error, "(ir):1:1: entry #{name} references missing state #{state}" end end |
#validate_parser_algorithm(contract) ⇒ void
This method returns an undefined value.
169 170 171 172 173 174 |
# File 'lib/ibex/ir/automaton_ir.rb', line 169 def validate_parser_algorithm(contract) selected_algorithm = { "lalr1" => :lalr, "ielr1" => :ielr }.fetch(@algorithm, @algorithm.to_sym) return unless contract.algorithm.explicit && contract.algorithm.value != selected_algorithm raise Ibex::Error, "automaton algorithm conflicts with the embedded parser contract" end |
#validate_parser_contract ⇒ void
This method returns an undefined value.
162 163 164 165 166 |
# File 'lib/ibex/ir/automaton_ir.rb', line 162 def validate_parser_contract contract = @grammar.parser_contract validate_parser_algorithm(contract) validate_parser_entries(contract) end |
#validate_parser_entries(contract) ⇒ void
This method returns an undefined value.
177 178 179 180 181 |
# File 'lib/ibex/ir/automaton_ir.rb', line 177 def validate_parser_entries(contract) return unless contract.entries.explicit && contract.entries.value.to_s != @entry_construction raise Ibex::Error, "automaton entry construction conflicts with the embedded parser contract" end |