lrama 0.5.7 → 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.
@@ -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'
data/lib/lrama/lexer.rb CHANGED
@@ -3,6 +3,7 @@ require "lrama/lexer/token"
3
3
 
4
4
  module Lrama
5
5
  class Lexer
6
+ attr_reader :head_line, :head_column
6
7
  attr_accessor :status
7
8
  attr_accessor :end_symbol
8
9
 
@@ -24,6 +25,8 @@ module Lrama
24
25
  %precedence
25
26
  %prec
26
27
  %error-token
28
+ %empty
29
+ %code
27
30
  )
28
31
 
29
32
  def initialize(text)
@@ -63,8 +66,6 @@ module Lrama
63
66
  when @scanner.scan(/\/\//)
64
67
  @scanner.scan_until(/\n/)
65
68
  newline
66
- when @scanner.scan(/%empty/)
67
- # noop
68
69
  else
69
70
  break
70
71
  end
@@ -80,18 +81,20 @@ module Lrama
80
81
  return [@scanner.matched, @scanner.matched]
81
82
  when @scanner.scan(/#{PERCENT_TOKENS.join('|')}/)
82
83
  return [@scanner.matched, @scanner.matched]
84
+ when @scanner.scan(/[\?\+\*]/)
85
+ return [@scanner.matched, @scanner.matched]
83
86
  when @scanner.scan(/<\w+>/)
84
- return [:TAG, build_token(type: Token::Tag, s_value: @scanner.matched)]
87
+ return [:TAG, setup_token(Lrama::Lexer::Token::Tag.new(s_value: @scanner.matched))]
85
88
  when @scanner.scan(/'.'/)
86
- return [:CHARACTER, build_token(type: Token::Char, s_value: @scanner.matched)]
89
+ return [:CHARACTER, setup_token(Lrama::Lexer::Token::Char.new(s_value: @scanner.matched))]
87
90
  when @scanner.scan(/'\\\\'|'\\b'|'\\t'|'\\f'|'\\r'|'\\n'|'\\v'|'\\13'/)
88
- return [:CHARACTER, build_token(type: Token::Char, s_value: @scanner.matched)]
91
+ return [:CHARACTER, setup_token(Lrama::Lexer::Token::Char.new(s_value: @scanner.matched))]
89
92
  when @scanner.scan(/"/)
90
93
  return [:STRING, %Q("#{@scanner.scan_until(/"/)})]
91
94
  when @scanner.scan(/\d+/)
92
95
  return [:INTEGER, Integer(@scanner.matched)]
93
96
  when @scanner.scan(/([a-zA-Z_.][-a-zA-Z0-9_.]*)/)
94
- token = build_token(type: Token::Ident, s_value: @scanner.matched)
97
+ token = setup_token(Lrama::Lexer::Token::Ident.new(s_value: @scanner.matched))
95
98
  type =
96
99
  if @scanner.check(/\s*(\[\s*[a-zA-Z_.][-a-zA-Z0-9_.]*\s*\])?\s*:/)
97
100
  :IDENT_COLON
@@ -100,7 +103,7 @@ module Lrama
100
103
  end
101
104
  return [type, token]
102
105
  else
103
- raise
106
+ raise ParseError, "Unexpected token: #{@scanner.peek(10).chomp}."
104
107
  end
105
108
  end
106
109
 
@@ -115,13 +118,13 @@ module Lrama
115
118
  when @scanner.scan(/}/)
116
119
  if nested == 0 && @end_symbol == '}'
117
120
  @scanner.unscan
118
- return [:C_DECLARATION, build_token(type: Token::User_code, s_value: code, references: [])]
121
+ return [:C_DECLARATION, setup_token(Lrama::Lexer::Token::UserCode.new(s_value: code))]
119
122
  else
120
123
  code += @scanner.matched
121
124
  nested -= 1
122
125
  end
123
126
  when @scanner.check(/#{@end_symbol}/)
124
- return [:C_DECLARATION, build_token(type: Token::User_code, s_value: code, references: [])]
127
+ return [:C_DECLARATION, setup_token(Lrama::Lexer::Token::UserCode.new(s_value: code))]
125
128
  when @scanner.scan(/\n/)
126
129
  code += @scanner.matched
127
130
  newline
@@ -136,7 +139,7 @@ module Lrama
136
139
  code += @scanner.getch
137
140
  end
138
141
  end
139
- raise
142
+ raise ParseError, "Unexpected code: #{code}."
140
143
  end
141
144
 
142
145
  private
@@ -155,13 +158,9 @@ module Lrama
155
158
  end
156
159
  end
157
160
 
158
- def build_token(type:, s_value:, **options)
159
- token = Token.new(type: type, s_value: s_value)
161
+ def setup_token(token)
160
162
  token.line = @head_line
161
163
  token.column = @head_column
162
- options.each do |attr, value|
163
- token.public_send("#{attr}=", value)
164
- end
165
164
 
166
165
  token
167
166
  end
@@ -58,10 +58,10 @@ module Lrama
58
58
  o.separator 'Tuning the Parser:'
59
59
  o.on('-S', '--skeleton=FILE', 'specify the skeleton to use') {|v| @options.skeleton = v }
60
60
  o.on('-t', 'reserved, do nothing') { }
61
+ o.on('--debug', 'display debugging outputs of internal parser') {|v| @options.debug = true }
61
62
  o.separator ''
62
63
  o.separator 'Output:'
63
64
  o.on('-H', '--header=[FILE]', 'also produce a header file named FILE') {|v| @options.header = true; @options.header_file = v }
64
- o.on('-h=[FILE]', 'also produce a header file named FILE (deprecated)') {|v| @options.header = true; @options.header_file = v }
65
65
  o.on('-d', 'also produce a header file') { @options.header = true }
66
66
  o.on('-r', '--report=THINGS', Array, 'also produce details on the automaton') {|v| @report = v }
67
67
  o.on('--report-file=FILE', 'also produce details on the automaton output to a file named FILE') {|v| @options.report_file = v }
@@ -74,7 +74,7 @@ module Lrama
74
74
  o.separator ''
75
75
  o.separator 'Other options:'
76
76
  o.on('-V', '--version', "output version information and exit") {|v| puts "lrama #{Lrama::VERSION}"; exit 0 }
77
- o.on('--help', "display this help and exit") {|v| puts o; exit 0 }
77
+ o.on('-h', '--help', "display this help and exit") {|v| puts o; exit 0 }
78
78
  o.separator ''
79
79
  o.parse!(argv)
80
80
  end
@@ -109,7 +109,7 @@ module Lrama
109
109
  def validate_trace(trace)
110
110
  list = %w[
111
111
  none locations scan parse automaton bitsets
112
- closure grammar resource sets muscles tools
112
+ closure grammar rules resource sets muscles tools
113
113
  m4-early m4 skeleton time ielr cex all
114
114
  ]
115
115
  h = {}
data/lib/lrama/options.rb CHANGED
@@ -4,7 +4,8 @@ module Lrama
4
4
  attr_accessor :skeleton, :header, :header_file,
5
5
  :report_file, :outfile,
6
6
  :error_recovery, :grammar_file,
7
- :report_file, :trace_opts, :report_opts, :y
7
+ :report_file, :trace_opts, :report_opts, :y,
8
+ :debug
8
9
 
9
10
  def initialize
10
11
  @skeleton = "bison/yacc.c"
data/lib/lrama/output.rb CHANGED
@@ -349,6 +349,15 @@ module Lrama
349
349
  end
350
350
  end
351
351
 
352
+ # b4_percent_code_get
353
+ def percent_code(name)
354
+ @grammar.percent_codes.select do |percent_code|
355
+ percent_code.id.s_value == name
356
+ end.map do |percent_code|
357
+ percent_code.code.s_value
358
+ end.join
359
+ end
360
+
352
361
  private
353
362
 
354
363
  def eval_template(file, path)