Class: Lrama::Grammar::Symbols::Resolver

Inherits:
Object
  • Object
show all
Defined in:
lib/lrama/grammar/symbols/resolver.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeResolver

Returns a new instance of Resolver.



36
37
38
39
# File 'lib/lrama/grammar/symbols/resolver.rb', line 36

def initialize
  @terms = []
  @nterms = []
end

Instance Attribute Details

#ntermsObject (readonly)

: Array



33
34
35
# File 'lib/lrama/grammar/symbols/resolver.rb', line 33

def nterms
  @nterms
end

#termsObject (readonly)

@rbs!

interface _DelegatedMethods
def symbols: () -> Array[Grammar::Symbol]
def nterms: () -> Array[Grammar::Symbol]
def terms: () -> Array[Grammar::Symbol]
def add_nterm: (id: Lexer::Token::Base, ?alias_name: String?, ?tag: Lexer::Token::Tag?) -> Grammar::Symbol
def add_term: (id: Lexer::Token::Base, ?alias_name: String?, ?tag: Lexer::Token::Tag?, ?token_id: Integer?, ?replace: bool) -> Grammar::Symbol
def find_symbol_by_number!: (Integer number) -> Grammar::Symbol
def find_symbol_by_id!: (Lexer::Token::Base id) -> Grammar::Symbol
def token_to_symbol: (Lexer::Token::Base token) -> Grammar::Symbol
def find_symbol_by_s_value!: (::String s_value) -> Grammar::Symbol
def fill_nterm_type: (Array[Grammar::Type] types) -> void
def fill_symbol_number: () -> void
def fill_printer: (Array[Grammar::Printer] printers) -> void
def fill_destructor: (Array[Destructor] destructors) -> (Destructor | bot)
def fill_error_token: (Array[Grammar::ErrorToken] error_tokens) -> void
def sort_by_number!: () -> Array[Grammar::Symbol]
end

@symbols: Array[Grammar::Symbol]?
@number: Integer
@used_numbers: Hash[Integer, bool]


32
33
34
# File 'lib/lrama/grammar/symbols/resolver.rb', line 32

def terms
  @terms
end

Instance Method Details

#add_nterm(id:, alias_name: nil, tag: nil) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/lrama/grammar/symbols/resolver.rb', line 77

def add_nterm(id:, alias_name: nil, tag: nil)
  if (sym = find_symbol_by_id(id))
    return sym
  end

  @symbols = nil
  nterm = Symbol.new(
    id: id, alias_name: alias_name, number: nil, tag: tag,
    term: false, token_id: nil, nullable: nil,
  )
  @nterms << nterm
  nterm
end

#add_term(id:, alias_name: nil, tag: nil, token_id: nil, replace: false) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/lrama/grammar/symbols/resolver.rb', line 52

def add_term(id:, alias_name: nil, tag: nil, token_id: nil, replace: false)
  if token_id && (sym = find_symbol_by_token_id(token_id))
    if replace
      sym.id = id
      sym.alias_name = alias_name
      sym.tag = tag
    end

    return sym
  end

  if (sym = find_symbol_by_id(id))
    return sym
  end

  @symbols = nil
  term = Symbol.new(
    id: id, alias_name: alias_name, number: nil, tag: tag,
    term: true, token_id: token_id, nullable: false
  )
  @terms << term
  term
end

#fill_destructor(destructors) ⇒ Object



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/lrama/grammar/symbols/resolver.rb', line 171

def fill_destructor(destructors)
  symbols.each do |sym|
    destructors.each do |destructor|
      destructor.ident_or_tags.each do |ident_or_tag|
        case ident_or_tag
        when Lrama::Lexer::Token::Ident
          sym.destructor = destructor if sym.id == ident_or_tag
        when Lrama::Lexer::Token::Tag
          sym.destructor = destructor if sym.tag == ident_or_tag
        else
          raise "Unknown token type. #{destructor}"
        end
      end
    end
  end
end

#fill_error_token(error_tokens) ⇒ Object



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/lrama/grammar/symbols/resolver.rb', line 189

def fill_error_token(error_tokens)
  symbols.each do |sym|
    error_tokens.each do |token|
      token.ident_or_tags.each do |ident_or_tag|
        case ident_or_tag
        when Lrama::Lexer::Token::Ident
          sym.error_token = token if sym.id == ident_or_tag
        when Lrama::Lexer::Token::Tag
          sym.error_token = token if sym.tag == ident_or_tag
        else
          raise "Unknown token type. #{token}"
        end
      end
    end
  end
end

#fill_nterm_type(types) ⇒ Object



145
146
147
148
149
150
# File 'lib/lrama/grammar/symbols/resolver.rb', line 145

def fill_nterm_type(types)
  types.each do |type|
    nterm = find_nterm_by_id!(type.id)
    nterm.tag = type.tag
  end
end

#fill_printer(printers) ⇒ Object



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/lrama/grammar/symbols/resolver.rb', line 153

def fill_printer(printers)
  symbols.each do |sym|
    printers.each do |printer|
      printer.ident_or_tags.each do |ident_or_tag|
        case ident_or_tag
        when Lrama::Lexer::Token::Ident
          sym.printer = printer if sym.id == ident_or_tag
        when Lrama::Lexer::Token::Tag
          sym.printer = printer if sym.tag == ident_or_tag
        else
          raise "Unknown token type. #{printer}"
        end
      end
    end
  end
end

#fill_symbol_numberObject



134
135
136
137
138
139
140
141
142
# File 'lib/lrama/grammar/symbols/resolver.rb', line 134

def fill_symbol_number
  # YYEMPTY = -2
  # YYEOF   =  0
  # YYerror =  1
  # YYUNDEF =  2
  @number = 3
  fill_terms_number
  fill_nterms_number
end

#find_symbol_by_id(id) ⇒ Object



107
108
109
110
111
# File 'lib/lrama/grammar/symbols/resolver.rb', line 107

def find_symbol_by_id(id)
  symbols.find do |s|
    s.id == id || s.alias_name == id.s_value
  end
end

#find_symbol_by_id!(id) ⇒ Object



114
115
116
# File 'lib/lrama/grammar/symbols/resolver.rb', line 114

def find_symbol_by_id!(id)
  find_symbol_by_id(id) || (raise "Symbol not found. #{id}")
end

#find_symbol_by_number!(number) ⇒ Object



124
125
126
127
128
129
130
131
# File 'lib/lrama/grammar/symbols/resolver.rb', line 124

def find_symbol_by_number!(number)
  sym = symbols[number]

  raise "Symbol not found. number: `#{number}`" unless sym
  raise "[BUG] Symbol number mismatch. #{number}, #{sym}" if sym.number != number

  sym
end

#find_symbol_by_s_value(s_value) ⇒ Object



97
98
99
# File 'lib/lrama/grammar/symbols/resolver.rb', line 97

def find_symbol_by_s_value(s_value)
  symbols.find { |s| s.id.s_value == s_value }
end

#find_symbol_by_s_value!(s_value) ⇒ Object



102
103
104
# File 'lib/lrama/grammar/symbols/resolver.rb', line 102

def find_symbol_by_s_value!(s_value)
  find_symbol_by_s_value(s_value) || (raise "Symbol not found. value: `#{s_value}`")
end

#find_symbol_by_token_id(token_id) ⇒ Object



119
120
121
# File 'lib/lrama/grammar/symbols/resolver.rb', line 119

def find_symbol_by_token_id(token_id)
  symbols.find {|s| s.token_id == token_id }
end

#find_term_by_s_value(s_value) ⇒ Object



92
93
94
# File 'lib/lrama/grammar/symbols/resolver.rb', line 92

def find_term_by_s_value(s_value)
  terms.find { |s| s.id.s_value == s_value }
end

#sort_by_number!Object



47
48
49
# File 'lib/lrama/grammar/symbols/resolver.rb', line 47

def sort_by_number!
  symbols.sort_by!(&:number)
end

#symbolsObject



42
43
44
# File 'lib/lrama/grammar/symbols/resolver.rb', line 42

def symbols
  @symbols ||= (@terms + @nterms)
end

#token_to_symbol(token) ⇒ Object



207
208
209
210
211
212
213
214
# File 'lib/lrama/grammar/symbols/resolver.rb', line 207

def token_to_symbol(token)
  case token
  when Lrama::Lexer::Token::Base
    find_symbol_by_id!(token)
  else
    raise "Unknown class: #{token}"
  end
end

#validate!Object



217
218
219
220
221
# File 'lib/lrama/grammar/symbols/resolver.rb', line 217

def validate!
  validate_number_uniqueness!
  validate_alias_name_uniqueness!
  validate_symbols!
end