lrama 0.5.7 → 0.5.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -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)