lrama 0.5.8 → 0.5.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 52e495f849079217c2cb4ee28edf873dd7c999d02f2f486acf8b9c2c1e74006f
4
- data.tar.gz: 708aea3d87d066b71857d09c4b9fc0705c8abaedc1e8b8e465ae5f6c2a5e0315
3
+ metadata.gz: 5369d73367ea2fee299dbb73336a7801c98faa51bb3f68e66327c12f5a2d6716
4
+ data.tar.gz: b79943902e78f921d3361800cd1c371cebc594f527e940b83be3d26fcab190a9
5
5
  SHA512:
6
- metadata.gz: 779e08f5090a78347214d8fbe73e710469ed62f61e923b5fbf50ed1e4c022a4096961df035b517b4c6434fa69326d3a006d94cff144f2c87b48407093f8961c7
7
- data.tar.gz: df1e4828906ae7613bca0f5f7dda3466091aa0fe15d7d5147e92bcd803f8ef0e58b6935a6e5061bb18d715a1e0f8b47aaab678c553edda828cb7ff1b05b2bc0f
6
+ metadata.gz: 93fd0bb99180b74f7a98b1186273b9324ac8855f599add59a4eb86b7b38b7930975c32463568ae93ff5d829d7c605dbd8a264c8127e40d92f7f7b0bd46637b0a
7
+ data.tar.gz: 06a43beddb6b78b4a1866164c63ebff7309c134b74dc32b5272e181f88ba4b2ff2ea30d756a16016e194e6c0babf0e6ee1536984e90835798eaa57be8eb09c9f
@@ -57,7 +57,7 @@ jobs:
57
57
 
58
58
  - name: Check for parser.rb is up to date
59
59
  run: |
60
- bundle exec rake build:racc_parser
60
+ bundle exec rake build:parser
61
61
  git diff --color --no-ext-diff --ignore-submodules --exit-code lib/lrama/parser.rb
62
62
  steep-check:
63
63
  runs-on: ubuntu-20.04
data/Gemfile CHANGED
@@ -6,7 +6,7 @@ gem "rspec"
6
6
  gem "pry"
7
7
  # stackprof doesn't support Windows
8
8
  gem "stackprof", platforms: [:ruby]
9
- gem "racc"
9
+ gem "racc", "1.7.3"
10
10
  gem "rake"
11
11
  gem "rbs", require: false
12
12
  gem "steep", require: false
data/README.md CHANGED
@@ -65,13 +65,13 @@ This also requires Lrama to be able to run with only default gems because BASERU
65
65
 
66
66
  ## Development
67
67
 
68
- ### How to generate new_parser.rb
68
+ ### How to generate parser.rb
69
69
 
70
70
  ```shell
71
- $ rake build:racc_parser
71
+ $ rake build:parser
72
72
  ```
73
73
 
74
- `new_parser.rb` is generated from `parser.y` by Racc.
74
+ `parser.rb` is generated from `parser.y` by Racc.
75
75
  Run the rake command when you update `parser.y` then commit changes of both files.
76
76
 
77
77
  ### Test
data/Rakefile CHANGED
@@ -1,13 +1,8 @@
1
1
  require "bundler/gem_tasks"
2
2
 
3
3
  namespace "build" do
4
- desc "build parser from parser.y by using Racc"
5
- task :racc_parser do
6
- sh "bundle exec racc parser.y --embedded -o lib/lrama/parser.rb"
7
- end
8
-
9
- desc "build parser for debugging"
10
- task :racc_verbose_parser do
4
+ desc "build parser from parser.y"
5
+ task :parser do
11
6
  sh "bundle exec racc parser.y --embedded -o lib/lrama/parser.rb -t --log-file=parser.output"
12
7
  end
13
8
  end
data/Steepfile CHANGED
@@ -6,8 +6,16 @@ target :lib do
6
6
 
7
7
  check "lib/lrama/bitmap.rb"
8
8
  check "lib/lrama/digraph.rb"
9
+ check "lib/lrama/grammar/percent_code.rb"
10
+ # TODO: Include this file once Lrama::Grammar::Symbol type is defined
11
+ # check "lib/lrama/grammar/reference.rb"
12
+ check "lib/lrama/lexer/token.rb"
13
+ check "lib/lrama/lexer/token/char.rb"
14
+ check "lib/lrama/lexer/token/ident.rb"
15
+ check "lib/lrama/lexer/token/parameterizing.rb"
16
+ check "lib/lrama/lexer/token/tag.rb"
17
+ check "lib/lrama/lexer/token/user_code.rb"
9
18
  check "lib/lrama/report/duration.rb"
10
19
  check "lib/lrama/report/profile.rb"
11
- check "lib/lrama/token/type.rb"
12
20
  check "lib/lrama/warning.rb"
13
21
  end
data/lib/lrama/command.rb CHANGED
@@ -8,7 +8,7 @@ module Lrama
8
8
  warning = Lrama::Warning.new
9
9
  text = options.y.read
10
10
  options.y.close if options.y != STDIN
11
- grammar = Lrama::Parser.new(text, options.grammar_file).parse
11
+ grammar = Lrama::Parser.new(text, options.grammar_file, options.debug).parse
12
12
  states = Lrama::States.new(grammar, warning, trace_state: (options.trace_opts[:automaton] || options.trace_opts[:closure]))
13
13
  states.compute
14
14
  context = Lrama::Context.new(states)
@@ -20,6 +20,11 @@ module Lrama
20
20
  end
21
21
  end
22
22
 
23
+ if options.trace_opts && options.trace_opts[:rules]
24
+ puts "Grammar rules:"
25
+ puts grammar.rules
26
+ end
27
+
23
28
  File.open(options.outfile, "w+") do |f|
24
29
  Lrama::Output.new(
25
30
  out: f,
@@ -0,0 +1,12 @@
1
+ module Lrama
2
+ class Grammar
3
+ class PercentCode
4
+ attr_reader :id, :code
5
+
6
+ def initialize(id, code)
7
+ @id = id
8
+ @code = code
9
+ end
10
+ end
11
+ end
12
+ end
@@ -47,9 +47,9 @@ module Lrama
47
47
  name = "YYACCEPT"
48
48
  when eof_symbol?
49
49
  name = "YYEOF"
50
- when term? && id.type == Token::Char
50
+ when term? && id.is_a?(Lrama::Lexer::Token::Char)
51
51
  name = number.to_s + display_name
52
- when term? && id.type == Token::Ident
52
+ when term? && id.is_a?(Lrama::Lexer::Token::Ident)
53
53
  name = id.s_value
54
54
  when nterm? && (id.s_value.include?("$") || id.s_value.include?("@"))
55
55
  name = number.to_s + id.s_value
data/lib/lrama/grammar.rb CHANGED
@@ -3,6 +3,7 @@ require "strscan"
3
3
  require "lrama/grammar/auxiliary"
4
4
  require "lrama/grammar/code"
5
5
  require "lrama/grammar/error_token"
6
+ require "lrama/grammar/percent_code"
6
7
  require "lrama/grammar/precedence"
7
8
  require "lrama/grammar/printer"
8
9
  require "lrama/grammar/reference"
@@ -13,11 +14,9 @@ require "lrama/lexer"
13
14
  require "lrama/type"
14
15
 
15
16
  module Lrama
16
- Token = Lrama::Lexer::Token
17
-
18
17
  # Grammar is the result of parsing an input grammar file
19
18
  class Grammar
20
- attr_reader :eof_symbol, :error_symbol, :undef_symbol, :accept_symbol, :aux
19
+ attr_reader :percent_codes, :eof_symbol, :error_symbol, :undef_symbol, :accept_symbol, :aux
21
20
  attr_accessor :union, :expect,
22
21
  :printers, :error_tokens,
23
22
  :lex_param, :parse_param, :initial_action,
@@ -26,6 +25,8 @@ module Lrama
26
25
  :sym_to_rules
27
26
 
28
27
  def initialize
28
+ # Code defined by "%code"
29
+ @percent_codes = []
29
30
  @printers = []
30
31
  @error_tokens = []
31
32
  @symbols = []
@@ -43,6 +44,10 @@ module Lrama
43
44
  append_special_symbols
44
45
  end
45
46
 
47
+ def add_percent_code(id:, code:)
48
+ @percent_codes << PercentCode.new(id, code)
49
+ end
50
+
46
51
  def add_printer(ident_or_tags:, code:, lineno:)
47
52
  @printers << Printer.new(ident_or_tags: ident_or_tags, code: code, lineno: lineno)
48
53
  end
@@ -122,16 +127,7 @@ module Lrama
122
127
  @_rules << [lhs, rhs, lineno]
123
128
  end
124
129
 
125
- def build_references(token_code)
126
- token_code.references.map! do |type, value, tag, first_column, last_column|
127
- Reference.new(type: type, value: value, ex_tag: tag, first_column: first_column, last_column: last_column)
128
- end
129
-
130
- token_code
131
- end
132
-
133
130
  def build_code(type, token_code)
134
- build_references(token_code)
135
131
  Code.new(type: type, token_code: token_code)
136
132
  end
137
133
 
@@ -152,6 +148,7 @@ module Lrama
152
148
  end
153
149
 
154
150
  def prepare
151
+ extract_references
155
152
  normalize_rules
156
153
  collect_symbols
157
154
  replace_token_with_symbol
@@ -314,31 +311,33 @@ module Lrama
314
311
  # $ references
315
312
  # It need to wrap an identifier with brackets to use ".-" for identifiers
316
313
  when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?\$/) # $$, $<long>$
317
- tag = scanner[1] ? Lrama::Lexer::Token.new(type: Lrama::Lexer::Token::Tag, s_value: scanner[1]) : nil
318
- return [:dollar, "$", tag, start, scanner.pos - 1]
314
+ tag = scanner[1] ? Lrama::Lexer::Token::Tag.new(s_value: scanner[1]) : nil
315
+ return Reference.new(type: :dollar, value: "$", ex_tag: tag, first_column: start, last_column: scanner.pos - 1)
319
316
  when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?(\d+)/) # $1, $2, $<long>1
320
- tag = scanner[1] ? Lrama::Lexer::Token.new(type: Lrama::Lexer::Token::Tag, s_value: scanner[1]) : nil
321
- return [:dollar, Integer(scanner[2]), tag, start, scanner.pos - 1]
317
+ tag = scanner[1] ? Lrama::Lexer::Token::Tag.new(s_value: scanner[1]) : nil
318
+ return Reference.new(type: :dollar, value: Integer(scanner[2]), ex_tag: tag, first_column: start, last_column: scanner.pos - 1)
322
319
  when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?([a-zA-Z_][a-zA-Z0-9_]*)/) # $foo, $expr, $<long>program (named reference without brackets)
323
- tag = scanner[1] ? Lrama::Lexer::Token.new(type: Lrama::Lexer::Token::Tag, s_value: scanner[1]) : nil
324
- return [:dollar, scanner[2], tag, start, scanner.pos - 1]
320
+ tag = scanner[1] ? Lrama::Lexer::Token::Tag.new(s_value: scanner[1]) : nil
321
+ return Reference.new(type: :dollar, value: scanner[2], ex_tag: tag, first_column: start, last_column: scanner.pos - 1)
325
322
  when scanner.scan(/\$(<[a-zA-Z0-9_]+>)?\[([a-zA-Z_.][-a-zA-Z0-9_.]*)\]/) # $expr.right, $expr-right, $<long>program (named reference with brackets)
326
- tag = scanner[1] ? Lrama::Lexer::Token.new(type: Lrama::Lexer::Token::Tag, s_value: scanner[1]) : nil
327
- return [:dollar, scanner[2], tag, start, scanner.pos - 1]
323
+ tag = scanner[1] ? Lrama::Lexer::Token::Tag.new(s_value: scanner[1]) : nil
324
+ return Reference.new(type: :dollar, value: scanner[2], ex_tag: tag, first_column: start, last_column: scanner.pos - 1)
328
325
 
329
326
  # @ references
330
327
  # It need to wrap an identifier with brackets to use ".-" for identifiers
331
328
  when scanner.scan(/@\$/) # @$
332
- return [:at, "$", nil, start, scanner.pos - 1]
329
+ return Reference.new(type: :at, value: "$", first_column: start, last_column: scanner.pos - 1)
333
330
  when scanner.scan(/@(\d+)/) # @1
334
- return [:at, Integer(scanner[1]), nil, start, scanner.pos - 1]
331
+ return Reference.new(type: :at, value: Integer(scanner[1]), first_column: start, last_column: scanner.pos - 1)
335
332
  when scanner.scan(/@([a-zA-Z][a-zA-Z0-9_]*)/) # @foo, @expr (named reference without brackets)
336
- return [:at, scanner[1], nil, start, scanner.pos - 1]
333
+ return Reference.new(type: :at, value: scanner[1], first_column: start, last_column: scanner.pos - 1)
337
334
  when scanner.scan(/@\[([a-zA-Z_.][-a-zA-Z0-9_.]*)\]/) # @expr.right, @expr-right (named reference with brackets)
338
- return [:at, scanner[1], nil, start, scanner.pos - 1]
335
+ return Reference.new(type: :at, value: scanner[1], first_column: start, last_column: scanner.pos - 1)
339
336
  end
340
337
  end
341
338
 
339
+ private
340
+
342
341
  def extract_references
343
342
  unless initial_action.nil?
344
343
  scanner = StringScanner.new(initial_action.s_value)
@@ -353,7 +352,6 @@ module Lrama
353
352
  end
354
353
 
355
354
  initial_action.token_code.references = references
356
- build_references(initial_action.token_code)
357
355
  end
358
356
 
359
357
  @printers.each do |printer|
@@ -369,7 +367,6 @@ module Lrama
369
367
  end
370
368
 
371
369
  printer.code.token_code.references = references
372
- build_references(printer.code.token_code)
373
370
  end
374
371
 
375
372
  @error_tokens.each do |error_token|
@@ -385,12 +382,11 @@ module Lrama
385
382
  end
386
383
 
387
384
  error_token.code.token_code.references = references
388
- build_references(error_token.code.token_code)
389
385
  end
390
386
 
391
387
  @_rules.each do |lhs, rhs, _|
392
388
  rhs.each_with_index do |token, index|
393
- next if token.class == Lrama::Grammar::Symbol || token.type != Lrama::Lexer::Token::User_code
389
+ next unless token.class == Lrama::Lexer::Token::UserCode
394
390
 
395
391
  scanner = StringScanner.new(token.s_value)
396
392
  references = []
@@ -407,14 +403,11 @@ module Lrama
407
403
  end
408
404
 
409
405
  token.references = references
410
- token.numberize_references(lhs, rhs)
411
- build_references(token)
406
+ numberize_references(lhs, rhs, token.references)
412
407
  end
413
408
  end
414
409
  end
415
410
 
416
- private
417
-
418
411
  def find_nterm_by_id!(id)
419
412
  nterms.find do |nterm|
420
413
  nterm.id == id
@@ -428,29 +421,54 @@ module Lrama
428
421
  # @empty_symbol = term
429
422
 
430
423
  # YYEOF
431
- term = add_term(id: Token.new(type: Token::Ident, s_value: "YYEOF"), alias_name: "\"end of file\"", token_id: 0)
424
+ term = add_term(id: Lrama::Lexer::Token::Ident.new(s_value: "YYEOF"), alias_name: "\"end of file\"", token_id: 0)
432
425
  term.number = 0
433
426
  term.eof_symbol = true
434
427
  @eof_symbol = term
435
428
 
436
429
  # YYerror
437
- term = add_term(id: Token.new(type: Token::Ident, s_value: "YYerror"), alias_name: "error")
430
+ term = add_term(id: Lrama::Lexer::Token::Ident.new(s_value: "YYerror"), alias_name: "error")
438
431
  term.number = 1
439
432
  term.error_symbol = true
440
433
  @error_symbol = term
441
434
 
442
435
  # YYUNDEF
443
- term = add_term(id: Token.new(type: Token::Ident, s_value: "YYUNDEF"), alias_name: "\"invalid token\"")
436
+ term = add_term(id: Lrama::Lexer::Token::Ident.new(s_value: "YYUNDEF"), alias_name: "\"invalid token\"")
444
437
  term.number = 2
445
438
  term.undef_symbol = true
446
439
  @undef_symbol = term
447
440
 
448
441
  # $accept
449
- term = add_nterm(id: Token.new(type: Token::Ident, s_value: "$accept"))
442
+ term = add_nterm(id: Lrama::Lexer::Token::Ident.new(s_value: "$accept"))
450
443
  term.accept_symbol = true
451
444
  @accept_symbol = term
452
445
  end
453
446
 
447
+ def numberize_references(lhs, rhs, references)
448
+ references.map! {|ref|
449
+ ref_name = ref.value
450
+ if ref_name.is_a?(::String) && ref_name != '$'
451
+ value =
452
+ if lhs.referred_by?(ref_name)
453
+ '$'
454
+ else
455
+ index = rhs.find_index {|token| token.referred_by?(ref_name) }
456
+
457
+ if index
458
+ index + 1
459
+ else
460
+ raise "'#{ref_name}' is invalid name."
461
+ end
462
+ end
463
+
464
+ ref.value = value
465
+ ref
466
+ else
467
+ ref
468
+ end
469
+ }
470
+ end
471
+
454
472
  # 1. Add $accept rule to the top of rules
455
473
  # 2. Extract precedence and last action
456
474
  # 3. Extract action in the middle of RHS into new Empty rule
@@ -493,7 +511,7 @@ module Lrama
493
511
  case
494
512
  when r.is_a?(Symbol) # precedence_sym
495
513
  precedence_sym = r
496
- when (r.type == Token::User_code) && precedence_sym.nil? && code.nil? && rhs1.empty?
514
+ when r.is_a?(Lrama::Lexer::Token::UserCode) && precedence_sym.nil? && code.nil? && rhs1.empty?
497
515
  code = r
498
516
  else
499
517
  rhs1 << r
@@ -503,7 +521,7 @@ module Lrama
503
521
 
504
522
  # Bison n'th component is 1-origin
505
523
  (rhs1 + [code]).compact.each.with_index(1) do |token, i|
506
- if token.type == Token::User_code
524
+ if token.is_a?(Lrama::Lexer::Token::UserCode)
507
525
  token.references.each do |ref|
508
526
  # Need to keep position_in_rhs for actions in the middle of RHS
509
527
  ref.position_in_rhs = i - 1
@@ -532,9 +550,9 @@ module Lrama
532
550
  end
533
551
 
534
552
  rhs2 = rhs1.map do |token|
535
- if token.type == Token::User_code
553
+ if token.is_a?(Lrama::Lexer::Token::UserCode)
536
554
  prefix = token.referred ? "@" : "$@"
537
- new_token = Token.new(type: Token::Ident, s_value: prefix + extracted_action_number.to_s)
555
+ new_token = Lrama::Lexer::Token::Ident.new(s_value: prefix + extracted_action_number.to_s)
538
556
  extracted_action_number += 1
539
557
  a << [new_token, token]
540
558
  new_token
@@ -550,8 +568,12 @@ module Lrama
550
568
  end
551
569
 
552
570
  c = code ? Code.new(type: :user_code, token_code: code) : nil
553
- @rules << Rule.new(id: @rules.count, lhs: lhs, rhs: rhs2, code: c, precedence_sym: precedence_sym, lineno: lineno)
554
-
571
+ # Expand Parameterizing rules
572
+ if rhs2.any? {|r| r.is_a?(Lrama::Lexer::Token::Parameterizing) }
573
+ expand_parameterizing_rules(lhs, rhs2, c, precedence_sym, lineno)
574
+ else
575
+ @rules << Rule.new(id: @rules.count, lhs: lhs, rhs: rhs2, code: c, precedence_sym: precedence_sym, lineno: lineno)
576
+ end
555
577
  add_nterm(id: lhs)
556
578
  a.each do |new_token, _|
557
579
  add_nterm(id: new_token)
@@ -559,14 +581,37 @@ module Lrama
559
581
  end
560
582
  end
561
583
 
584
+ def expand_parameterizing_rules(lhs, rhs, code, precedence_sym, lineno)
585
+ token = Lrama::Lexer::Token::Ident.new(s_value: rhs[0].s_value)
586
+ if rhs.any? {|r| r.is_a?(Lrama::Lexer::Token::Parameterizing) && r.option? }
587
+ option_token = Lrama::Lexer::Token::Ident.new(s_value: "option_#{rhs[0].s_value}")
588
+ add_term(id: option_token)
589
+ @rules << Rule.new(id: @rules.count, lhs: lhs, rhs: [option_token], code: code, precedence_sym: precedence_sym, lineno: lineno)
590
+ @rules << Rule.new(id: @rules.count, lhs: option_token, rhs: [], code: code, precedence_sym: precedence_sym, lineno: lineno)
591
+ @rules << Rule.new(id: @rules.count, lhs: option_token, rhs: [token], code: code, precedence_sym: precedence_sym, lineno: lineno)
592
+ elsif rhs.any? {|r| r.is_a?(Lrama::Lexer::Token::Parameterizing) && r.nonempty_list? }
593
+ nonempty_list_token = Lrama::Lexer::Token::Ident.new(s_value: "nonempty_list_#{rhs[0].s_value}")
594
+ add_term(id: nonempty_list_token)
595
+ @rules << Rule.new(id: @rules.count, lhs: lhs, rhs: [nonempty_list_token], code: code, precedence_sym: precedence_sym, lineno: lineno)
596
+ @rules << Rule.new(id: @rules.count, lhs: nonempty_list_token, rhs: [token], code: code, precedence_sym: precedence_sym, lineno: lineno)
597
+ @rules << Rule.new(id: @rules.count, lhs: nonempty_list_token, rhs: [nonempty_list_token, token], code: code, precedence_sym: precedence_sym, lineno: lineno)
598
+ elsif rhs.any? {|r| r.is_a?(Lrama::Lexer::Token::Parameterizing) && r.list? }
599
+ list_token = Lrama::Lexer::Token::Ident.new(s_value: "list_#{rhs[0].s_value}")
600
+ add_term(id: list_token)
601
+ @rules << Rule.new(id: @rules.count, lhs: lhs, rhs: [list_token], code: code, precedence_sym: precedence_sym, lineno: lineno)
602
+ @rules << Rule.new(id: @rules.count, lhs: list_token, rhs: [], code: code, precedence_sym: precedence_sym, lineno: lineno)
603
+ @rules << Rule.new(id: @rules.count, lhs: list_token, rhs: [list_token, token], code: code, precedence_sym: precedence_sym, lineno: lineno)
604
+ end
605
+ end
606
+
562
607
  # Collect symbols from rules
563
608
  def collect_symbols
564
609
  @rules.flat_map(&:rhs).each do |s|
565
610
  case s
566
- when Token
567
- if s.type == Token::Char
568
- add_term(id: s)
569
- end
611
+ when Lrama::Lexer::Token::Char
612
+ add_term(id: s)
613
+ when Lrama::Lexer::Token
614
+ # skip
570
615
  when Symbol
571
616
  # skip
572
617
  else
@@ -607,7 +652,7 @@ module Lrama
607
652
 
608
653
  # If id is Token::Char, it uses ASCII code
609
654
  if sym.term? && sym.token_id.nil?
610
- if sym.id.type == Token::Char
655
+ if sym.id.is_a?(Lrama::Lexer::Token::Char)
611
656
  # Ignore ' on the both sides
612
657
  case sym.id.s_value[1..-2]
613
658
  when "\\b"
@@ -660,7 +705,7 @@ module Lrama
660
705
  rule.code.references.each do |ref|
661
706
  next if ref.type == :at
662
707
 
663
- if ref.referring_symbol.type != Token::User_code
708
+ if !ref.referring_symbol.is_a?(Lrama::Lexer::Token::UserCode)
664
709
  ref.referring_symbol = token_to_symbol(ref.referring_symbol)
665
710
  end
666
711
  end
@@ -670,7 +715,7 @@ module Lrama
670
715
 
671
716
  def token_to_symbol(token)
672
717
  case token
673
- when Token
718
+ when Lrama::Lexer::Token
674
719
  find_symbol_by_id!(token)
675
720
  when Symbol
676
721
  token
@@ -716,10 +761,10 @@ module Lrama
716
761
  @symbols.each do |sym|
717
762
  @printers.each do |printer|
718
763
  printer.ident_or_tags.each do |ident_or_tag|
719
- case ident_or_tag.type
720
- when Token::Ident
764
+ case ident_or_tag
765
+ when Lrama::Lexer::Token::Ident
721
766
  sym.printer = printer if sym.id == ident_or_tag
722
- when Token::Tag
767
+ when Lrama::Lexer::Token::Tag
723
768
  sym.printer = printer if sym.tag == ident_or_tag
724
769
  else
725
770
  raise "Unknown token type. #{printer}"
@@ -733,10 +778,10 @@ module Lrama
733
778
  @symbols.each do |sym|
734
779
  @error_tokens.each do |error_token|
735
780
  error_token.ident_or_tags.each do |ident_or_tag|
736
- case ident_or_tag.type
737
- when Token::Ident
781
+ case ident_or_tag
782
+ when Lrama::Lexer::Token::Ident
738
783
  sym.error_token = error_token if sym.id == ident_or_tag
739
- when Token::Tag
784
+ when Lrama::Lexer::Token::Tag
740
785
  sym.error_token = error_token if sym.tag == ident_or_tag
741
786
  else
742
787
  raise "Unknown token type. #{error_token}"
@@ -0,0 +1,8 @@
1
+ module Lrama
2
+ class Lexer
3
+ class Token
4
+ class Char < Token
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module Lrama
2
+ class Lexer
3
+ class Token
4
+ class Ident < Token
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,19 @@
1
+ module Lrama
2
+ class Lexer
3
+ class Token
4
+ class Parameterizing < Token
5
+ def option?
6
+ self.s_value == "?"
7
+ end
8
+
9
+ def nonempty_list?
10
+ self.s_value == "+"
11
+ end
12
+
13
+ def list?
14
+ self.s_value == "*"
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,8 @@
1
+ module Lrama
2
+ class Lexer
3
+ class Token
4
+ class Tag < Token
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,14 @@
1
+ module Lrama
2
+ class Lexer
3
+ class Token
4
+ class UserCode < Token
5
+ attr_accessor :references
6
+
7
+ def initialize(s_value: nil, alias_name: nil)
8
+ super
9
+ self.references = []
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,84 +1,26 @@
1
- require 'lrama/lexer/token/type'
2
-
3
1
  module Lrama
4
2
  class Lexer
5
- class Token
3
+ class Token < Struct.new(:s_value, :alias_name, keyword_init: true)
6
4
 
7
5
  attr_accessor :line, :column, :referred
8
- # For User_code
9
- attr_accessor :references
10
6
 
11
7
  def to_s
12
8
  "#{super} line: #{line}, column: #{column}"
13
9
  end
14
10
 
15
11
  def referred_by?(string)
16
- [self.s_value, self.alias].include?(string)
12
+ [self.s_value, self.alias_name].include?(string)
17
13
  end
18
14
 
19
15
  def ==(other)
20
- self.class == other.class && self.type == other.type && self.s_value == other.s_value
16
+ self.class == other.class && self.s_value == other.s_value
21
17
  end
22
-
23
- def numberize_references(lhs, rhs)
24
- self.references.map! {|ref|
25
- ref_name = ref[1]
26
- if ref_name.is_a?(::String) && ref_name != '$'
27
- value =
28
- if lhs.referred_by?(ref_name)
29
- '$'
30
- else
31
- index = rhs.find_index {|token| token.referred_by?(ref_name) }
32
-
33
- if index
34
- index + 1
35
- else
36
- raise "'#{ref_name}' is invalid name."
37
- end
38
- end
39
- [ref[0], value, ref[2], ref[3], ref[4]]
40
- else
41
- ref
42
- end
43
- }
44
- end
45
-
46
- @i = 0
47
- @types = []
48
-
49
- def self.define_type(name)
50
- type = Type.new(id: @i, name: name.to_s)
51
- const_set(name, type)
52
- @types << type
53
- @i += 1
54
- end
55
-
56
- # Token types
57
- define_type(:P_expect) # %expect
58
- define_type(:P_define) # %define
59
- define_type(:P_printer) # %printer
60
- define_type(:P_error_token) # %error-token
61
- define_type(:P_lex_param) # %lex-param
62
- define_type(:P_parse_param) # %parse-param
63
- define_type(:P_initial_action) # %initial-action
64
- define_type(:P_union) # %union
65
- define_type(:P_token) # %token
66
- define_type(:P_type) # %type
67
- define_type(:P_nonassoc) # %nonassoc
68
- define_type(:P_left) # %left
69
- define_type(:P_right) # %right
70
- define_type(:P_precedence) # %precedence
71
- define_type(:P_prec) # %prec
72
- define_type(:User_code) # { ... }
73
- define_type(:Tag) # <int>
74
- define_type(:Number) # 0
75
- define_type(:Ident_Colon) # k_if:, k_if : (spaces can be there)
76
- define_type(:Ident) # api.pure, tNUMBER
77
- define_type(:Named_Ref) # [foo]
78
- define_type(:Semicolon) # ;
79
- define_type(:Bar) # |
80
- define_type(:String) # "str"
81
- define_type(:Char) # '+'
82
18
  end
83
19
  end
84
20
  end
21
+
22
+ require 'lrama/lexer/token/char'
23
+ require 'lrama/lexer/token/ident'
24
+ require 'lrama/lexer/token/parameterizing'
25
+ require 'lrama/lexer/token/tag'
26
+ require 'lrama/lexer/token/user_code'