Class: Lrama::Output

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Report::Duration
Defined in:
lib/lrama/output.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Report::Duration

enable, enabled?, #report_duration

Constructor Details

#initialize(out:, output_file_path:, template_name:, grammar_file_path:, header_out: nil, header_file_path: nil, context:, grammar:, error_recovery: false) ⇒ Output

Returns a new instance of Output.



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/lrama/output.rb', line 17

def initialize(
  out:, output_file_path:, template_name:, grammar_file_path:,
  header_out: nil, header_file_path: nil,
  context:, grammar:, error_recovery: false
)
  @out = out
  @output_file_path = output_file_path
  @template_name = template_name
  @grammar_file_path = grammar_file_path
  @header_out = header_out
  @header_file_path = header_file_path
  @context = context
  @grammar = grammar
  @error_recovery = error_recovery
end

Instance Attribute Details

#contextObject (readonly)

Returns the value of attribute context.



10
11
12
# File 'lib/lrama/output.rb', line 10

def context
  @context
end

#error_recoveryObject (readonly)

Returns the value of attribute error_recovery.



10
11
12
# File 'lib/lrama/output.rb', line 10

def error_recovery
  @error_recovery
end

#grammarObject (readonly)

Returns the value of attribute grammar.



10
11
12
# File 'lib/lrama/output.rb', line 10

def grammar
  @grammar
end

#grammar_file_pathObject (readonly)

Returns the value of attribute grammar_file_path.



10
11
12
# File 'lib/lrama/output.rb', line 10

def grammar_file_path
  @grammar_file_path
end

Class Method Details

.erb(input) ⇒ Object



34
35
36
# File 'lib/lrama/output.rb', line 34

def self.erb(input)
  ERB.new(input, trim_mode: '-')
end

Instance Method Details

#auxObject



323
324
325
# File 'lib/lrama/output.rb', line 323

def aux
  @grammar.aux
end

#b4_cpp_guard__b4_spec_mapped_header_fileObject



347
348
349
350
351
352
353
# File 'lib/lrama/output.rb', line 347

def b4_cpp_guard__b4_spec_mapped_header_file
  if @header_file_path
    "YY_YY_" + @header_file_path.gsub(/[^a-zA-Z_0-9]+/, "_").upcase + "_INCLUDED"
  else
    ""
  end
end

#eval_template(file, path) ⇒ Object



43
44
45
46
47
48
# File 'lib/lrama/output.rb', line 43

def eval_template(file, path)
  erb = self.class.erb(File.read(file))
  erb.filename = file
  tmp = erb.result_with_hash(context: @context, output: self)
  replace_special_variables(tmp, path)
end

#extract_param_name(param) ⇒ Object



254
255
256
# File 'lib/lrama/output.rb', line 254

def extract_param_name(param)
  param[/\b([a-zA-Z0-9_]+)(?=\s*\z)/]
end

#int_array_to_string(ary) ⇒ Object



327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
# File 'lib/lrama/output.rb', line 327

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")
end

#int_type_for(ary) ⇒ Object

b4_int_type_for



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/lrama/output.rb', line 119

def int_type_for(ary)
  min = ary.min
  max = ary.max

  case
  when (-127 <= min && min <= 127) && (-127 <= max && max <= 127)
    "yytype_int8"
  when (0 <= min && min <= 255) && (0 <= max && max <= 255)
    "yytype_uint8"
  when (-32767 <= min && min <= 32767) && (-32767 <= max && max <= 32767)
    "yytype_int16"
  when (0 <= min && min <= 65535) && (0 <= max && max <= 65535)
    "yytype_uint16"
  else
    "int"
  end
end

#lex_paramObject



228
229
230
231
232
233
234
# File 'lib/lrama/output.rb', line 228

def lex_param
  if @grammar.lex_param
    omit_braces_and_blanks(@grammar.lex_param)
  else
    ""
  end
end

#lex_param_nameObject



266
267
268
269
270
271
272
# File 'lib/lrama/output.rb', line 266

def lex_param_name
  if @grammar.lex_param
    extract_param_name(lex_param)
  else
    ""
  end
end

#omit_braces_and_blanks(param) ⇒ Object



215
216
217
# File 'lib/lrama/output.rb', line 215

def omit_braces_and_blanks(param)
  param[1..-2].strip
end

#parse_paramObject

b4_parse_param



220
221
222
223
224
225
226
# File 'lib/lrama/output.rb', line 220

def parse_param
  if @grammar.parse_param
    omit_braces_and_blanks(@grammar.parse_param)
  else
    ""
  end
end

#parse_param_nameObject



258
259
260
261
262
263
264
# File 'lib/lrama/output.rb', line 258

def parse_param_name
  if @grammar.parse_param
    extract_param_name(parse_param)
  else
    ""
  end
end

#parse_param_use(val, loc) ⇒ Object

b4_parse_param_use



275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/lrama/output.rb', line 275

def parse_param_use(val, loc)
  str = <<-STR
  YY_USE (#{val});
  YY_USE (#{loc});
  STR

  if @grammar.parse_param
    str << "  YY_USE (#{parse_param_name});"
  end

  str
end

#renderObject



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/lrama/output.rb', line 50

def render
  report_duration(:render) do
    tmp = eval_template(template_file, @output_file_path)
    @out << tmp

    if @header_file_path
      tmp = eval_template(header_template_file, @header_file_path)

      if @header_out
        @header_out << tmp
      else
        File.write(@header_file_path, tmp)
      end
    end
  end
end

#spec_mapped_header_fileObject



343
344
345
# File 'lib/lrama/output.rb', line 343

def spec_mapped_header_file
  @header_file_path
end

#symbol_actions_for_error_tokenObject



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/lrama/output.rb', line 167

def symbol_actions_for_error_token
  str = ""

  @grammar.symbols.each do |sym|
    next unless sym.error_token

    str << <<-STR
case #{sym.enum_name}: /* #{sym.comment}  */
#line #{sym.error_token.lineno} "#{@grammar_file_path}"
     #{sym.error_token.translated_code(sym.tag)}
#line [@oline@] [@ofile@]
    break;

    STR
  end

  str
end

#symbol_actions_for_printerObject



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/lrama/output.rb', line 137

def symbol_actions_for_printer
  str = ""

  @grammar.symbols.each do |sym|
    next unless sym.printer

    str << <<-STR
case #{sym.enum_name}: /* #{sym.comment}  */
#line #{sym.printer.lineno} "#{@grammar_file_path}"
     #{sym.printer.translated_code(sym.tag)}
#line [@oline@] [@ofile@]
    break;

    STR
  end

  str
end

#symbol_enumObject

b4_symbol_enum



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/lrama/output.rb', line 85

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|
    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)
    else
      str << sprintf("  %s\n", s)
    end
  end

  str
end

#table_value_equals(table, value, literal, symbol) ⇒ Object

b4_table_value_equals



300
301
302
303
304
305
306
# File 'lib/lrama/output.rb', line 300

def table_value_equals(table, value, literal, symbol)
  if literal < table.min || table.max < literal
    "0"
  else
    "((#{value}) == #{symbol})"
  end
end

#template_basenameObject



319
320
321
# File 'lib/lrama/output.rb', line 319

def template_basename
  File.basename(template_file)
end

#token_enumsObject

A part of b4_token_enums



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/lrama/output.rb', line 68

def token_enums
  str = ""

  @context.yytokentype.each 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)
    else
      str << sprintf("    %s\n", s)
    end
  end

  str
end

#user_actionsObject

b4_user_actions



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/lrama/output.rb', line 187

def 
  str = ""

  @context.states.rules.each do |rule|
    next unless rule.code

    rule = rule
    code = rule.code
    spaces = " " * (code.column - 1)

    str << <<-STR
  case #{rule.id + 1}: /* #{rule.as_comment}  */
#line #{code.line} "#{@grammar_file_path}"
#{spaces}#{rule.translated_code}
#line [@oline@] [@ofile@]
break;

    STR
  end

  str << <<-STR

#line [@oline@] [@ofile@]
  STR

  str
end

#user_argsObject

b4_user_args



246
247
248
249
250
251
252
# File 'lib/lrama/output.rb', line 246

def user_args
  if @grammar.parse_param
    ", #{parse_param_name}"
  else
    ""
  end
end

#user_formalsObject

b4_user_formals



237
238
239
240
241
242
243
# File 'lib/lrama/output.rb', line 237

def user_formals
  if @grammar.parse_param
    ", #{parse_param}"
  else
    ""
  end
end

#user_initial_action(comment = "") ⇒ Object

b4_user_initial_action



157
158
159
160
161
162
163
164
165
# File 'lib/lrama/output.rb', line 157

def user_initial_action(comment = "")
  return "" unless @grammar.initial_action

  <<-STR
    #{comment}
#line #{@grammar.initial_action.line} "#{@grammar_file_path}"
    #{@grammar.initial_action.translated_code}
  STR
end

#yyerror_argsObject

b4_yyerror_args



309
310
311
312
313
314
315
316
317
# File 'lib/lrama/output.rb', line 309

def yyerror_args
  ary = ["&yylloc"]

  if @grammar.parse_param
    ary << parse_param_name
  end

  "#{ary.join(', ')}"
end

#yylex_formalsObject

b4_yylex_formals



289
290
291
292
293
294
295
296
297
# File 'lib/lrama/output.rb', line 289

def yylex_formals
  ary = ["&yylval", "&yylloc"]

  if @grammar.lex_param
    ary << lex_param_name
  end

  "(#{ary.join(', ')})"
end

#yyrlineObject



110
111
112
# File 'lib/lrama/output.rb', line 110

def yyrline
  int_array_to_string(@context.yyrline)
end

#yytnameObject



114
115
116
# File 'lib/lrama/output.rb', line 114

def yytname
  string_array_to_string(@context.yytname) + " YY_NULLPTR"
end

#yytranslateObject



102
103
104
# File 'lib/lrama/output.rb', line 102

def yytranslate
  int_array_to_string(@context.yytranslate)
end

#yytranslate_invertedObject



106
107
108
# File 'lib/lrama/output.rb', line 106

def yytranslate_inverted
  int_array_to_string(@context.yytranslate_inverted)
end