depager 0.1.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.
Files changed (53) hide show
  1. data/ChangeLog +4 -0
  2. data/Manifest.txt +52 -0
  3. data/README.en +64 -0
  4. data/README.ja +128 -0
  5. data/bin/depager +47 -0
  6. data/data/depager/misc/depager-mode.el +209 -0
  7. data/data/depager/sample/extension/paction.dr +15 -0
  8. data/data/depager/sample/extension/pactiontest.dr +14 -0
  9. data/data/depager/sample/pl0d/pl0ds.dr +334 -0
  10. data/data/depager/sample/pl0d/pl0test.pl0 +34 -0
  11. data/data/depager/sample/sample_calc/calc.action.dr +33 -0
  12. data/data/depager/sample/sample_calc/calc.astdf.dr +54 -0
  13. data/data/depager/sample/sample_calc/calc.astl.action.dr +66 -0
  14. data/data/depager/sample/sample_calc/calc.astl.dr +55 -0
  15. data/data/depager/sample/sample_calc/calc.atree.dr +43 -0
  16. data/data/depager/sample/sample_calc/calc.cst.dr +45 -0
  17. data/data/depager/sample/sample_calc/calc.dr +43 -0
  18. data/data/depager/sample/sample_calc/calc.lex.dr +29 -0
  19. data/data/depager/sample/sample_calc/calc.nvaction.dr +33 -0
  20. data/data/depager/sample/sample_calc/calc_prec.nvaction.dr +31 -0
  21. data/data/depager/sample/slex_test/slextest1.dr +37 -0
  22. data/data/depager/sample/slex_test/slextest2.dr +33 -0
  23. data/lib/depager.rb +608 -0
  24. data/lib/depager/Rakefile +30 -0
  25. data/lib/depager/action.rb +47 -0
  26. data/lib/depager/ast_base.dr +232 -0
  27. data/lib/depager/ast_base.rb +1249 -0
  28. data/lib/depager/astdf.rb +10 -0
  29. data/lib/depager/astl.rb +14 -0
  30. data/lib/depager/atree.dr +55 -0
  31. data/lib/depager/atree.rb +336 -0
  32. data/lib/depager/cst.dr +182 -0
  33. data/lib/depager/cst.rb +625 -0
  34. data/lib/depager/lex.dr +76 -0
  35. data/lib/depager/lex.rb +306 -0
  36. data/lib/depager/lr.rb +604 -0
  37. data/lib/depager/nvaction.rb +21 -0
  38. data/lib/depager/parse_action.rb +24 -0
  39. data/lib/depager/parser.rb +248 -0
  40. data/lib/depager/psrtmpl.rb +33 -0
  41. data/lib/depager/slex.dr +161 -0
  42. data/lib/depager/slex.rb +646 -0
  43. data/lib/depager/srp.rb +50 -0
  44. data/lib/depager/template/astdf.erbs +57 -0
  45. data/lib/depager/template/astl.erbs +57 -0
  46. data/lib/depager/template/extension_lalr_master.erb +51 -0
  47. data/lib/depager/template/extension_lalr_slave.erb +107 -0
  48. data/lib/depager/template/simple.erb +21 -0
  49. data/lib/depager/template/single_lalr_parser.erb +97 -0
  50. data/lib/depager/utils.rb +355 -0
  51. data/lib/depager/version.rb +9 -0
  52. data/setup.rb +1585 -0
  53. metadata +103 -0
@@ -0,0 +1,21 @@
1
+ require 'depager/action.rb'
2
+ require 'depager/parser.rb'
3
+ require 'depager/parse_action.rb'
4
+
5
+ class NVActionExtension < ActionExtension #:nodoc:all
6
+ def modify_action_code code
7
+ let_code = ""
8
+ if @g_parser.rhsni.size > 0
9
+ rhs = @g_parser.rhsni.sort_by{|k,v| v}
10
+ let_code = rhs.map do |name, _|
11
+ if name =~ /[a-zA-Z][a-zA-Z0-9_]*/
12
+ "_#{name}"
13
+ else
14
+ '_'
15
+ end
16
+ end
17
+ let_code = " #{let_code.join(', ')} = *val \n"
18
+ end
19
+ return let_code << code, 1
20
+ end
21
+ end
@@ -0,0 +1,24 @@
1
+ module Depager::ActionParser
2
+ require 'pp'
3
+ def parse_action
4
+ val = ''
5
+ start_lineno = lineno
6
+ if @line =~ /\A\{(.*)\}\s*(#.*)?\Z/
7
+ val = " #{$1}\n"
8
+ else
9
+ val.concat @line.sub(/\A\s*\{/, '')
10
+ ind = @line0.match(/\A([ \t]*)/)[1]
11
+ until file.eof?
12
+ getline
13
+ break if line =~ /\A#{ind}\}\s*(#.*)?\Z/
14
+ val.concat line
15
+ end
16
+ if file.eof?
17
+ error_exit 'syntax error(parse_action).', start_lineno
18
+ end
19
+ end
20
+ @line = $'
21
+ #warn val
22
+ return val
23
+ end
24
+ end
@@ -0,0 +1,248 @@
1
+ require "depager/utils.rb"
2
+ module Depager
3
+ #
4
+ # Token
5
+ #
6
+ Token = Struct.new(:value, :lineno, :filename)
7
+
8
+ # = Parser Runtime
9
+ # == Stack
10
+ # s:: state
11
+ # la:: look ahead
12
+ # v:: value
13
+ # stack top->
14
+ # [0, [la0, v0], s0, [la1, v1], s1, .....]
15
+ #
16
+ class Parser
17
+ def initialize
18
+ end
19
+
20
+ ACC = 0x03ffffff
21
+
22
+ #
23
+ # lexer
24
+ #
25
+ def lex
26
+ end
27
+
28
+ # parse method
29
+ def yyparse f
30
+ @basis.file = f
31
+ @basis.la = [0, nil]
32
+ @basis.lex do |sym, val|
33
+ @basis.la = [@basis.t2i[sym] || @basis.t2i[false], val]
34
+ break if driver
35
+ end
36
+ @basis.stack[1][2..(@basis.params.size+1)]
37
+ end
38
+
39
+ protected
40
+ def init_parser
41
+ end
42
+
43
+ # driver method
44
+ def driver
45
+ while true
46
+ @basis.val = @basis.action_table[@basis.stack.last][@basis.la[0]]
47
+ @basis.val ||= @basis.defred_table[@basis.stack.last]
48
+
49
+ if @basis.val == nil
50
+ #warn "#{@basis.stack}#{@basis.la[0]}"
51
+ error
52
+ exit 1
53
+ elsif @basis.val == ACC
54
+ if @i2t[@basis.la[0]] == nil
55
+ accept
56
+ else
57
+ error
58
+ end
59
+ return true
60
+ elsif @basis.val > 0
61
+ shift
62
+ while val = @basis.defred_after_shift_table[@basis.stack.last]
63
+ @basis.val = val
64
+ reduce
65
+ end
66
+ return false
67
+ else
68
+ reduce
69
+ end
70
+ end
71
+ end
72
+ def accept
73
+ end
74
+ def error
75
+ end
76
+ def shift
77
+ end
78
+ def reduce
79
+ end
80
+ end
81
+
82
+ class Basis < Parser
83
+ attr_accessor :state, :stack, :laq, :la, :val, :basis, :params
84
+ attr_accessor :file, :oldline, :lineno, :line, :line0
85
+ attr_reader :action_table, :defred_table, :defred_after_shift_table
86
+ attr_reader :goto_table, :reduce_table
87
+ attr_reader :i2t, :t2i, :nt2i, :i2nt
88
+
89
+ private
90
+ def __init_parser__
91
+ @state = 0
92
+ @stack = [@state]
93
+ @laq = []
94
+ @la = nil
95
+ @val = nil
96
+ @line0 = @line = ''
97
+ end
98
+
99
+ def initialize
100
+ __init_parser__
101
+ @file = nil
102
+ @basis = self
103
+ @reduce_table, @params, @action_table,
104
+ @defred_table, @defred_after_shift_table, @goto_table,
105
+ @t2i, @i2t, @nt2i, @i2nt = self.class::Tables
106
+ end
107
+
108
+ def _Token sym, val=nil, lineno=nil
109
+ lineno ||= file.lineno
110
+ return sym, Token[val, lineno, file.path]
111
+ end
112
+
113
+ public
114
+ def banner
115
+ self.class.name
116
+ end
117
+
118
+ def getline
119
+ @file.gets unless @file.eof?
120
+ end
121
+
122
+ def accept
123
+ #warn "acc."
124
+ end
125
+ def error
126
+ fname = @file.respond_to?(:path) ? @file.path : '-'
127
+ exp = []
128
+ @action_table[@stack.last].each_with_index do |i, x|
129
+ exp << @i2t[x] if i
130
+ end
131
+ la = @la[1].value rescue @la[1]
132
+ la = (@i2t[@la[0]] || la).inspect
133
+ exp = exp.map{|i| i ? i.inspect : '$' }.join(', ')
134
+ warn "#{fname}:#{@file.lineno}: syntax error(#{self.banner}), " <<
135
+ "unexpected #{la}, expecting #{exp}."
136
+ warn @stack.pretty_inspect if $MP_DEBUG
137
+ end
138
+ def shift
139
+ @stack.push(@la).push(@val)
140
+ end
141
+ def reduce
142
+ (@reduce_table[-@val][1] * 2).times{@stack.pop}
143
+ r = @reduce_table[-@val][0]
144
+ cs = @goto_table[@stack.last][r]
145
+ @stack.push([r, :NT]).push(cs)
146
+ end
147
+ end
148
+
149
+ #
150
+ # Decorator Base class
151
+ #
152
+ class AdvancedParser < Parser
153
+ attr_reader :basis
154
+ attr_reader :action_table, :goto_table, :reduce_table
155
+ attr_reader :i2t, :t2i, :nt2i, :i2nt
156
+ def initialize inside, paramkey = nil
157
+ @inside = inside
158
+ @basis = @inside.basis
159
+ @reduce_table, @params, @action_table, @defred_table, @goto_table,
160
+ @t2i, @i2t, @nt2i, @i2nt = @basis.class::Tables
161
+ @nparam = @params[paramkey]
162
+ end
163
+
164
+ protected
165
+ def _state
166
+ @basis.state
167
+ end
168
+ def _stack
169
+ @basis.stack
170
+ end
171
+ def _lookaheadque
172
+ @basis.laq
173
+ end
174
+ def _lookahead
175
+ @basis.la
176
+ end
177
+ def _actvalue
178
+ @basis.val
179
+ end
180
+
181
+ def accept
182
+ beforeAccept
183
+ @inside.accept
184
+ afterAccept
185
+ end
186
+ def error
187
+ beforeError
188
+ @inside.error
189
+ afterError
190
+ end
191
+ def shift
192
+ beforeShift
193
+ @inside.shift
194
+ afterShift
195
+ end
196
+ def reduce
197
+ beforeReduce
198
+ @inside.reduce
199
+ afterReduce
200
+ end
201
+
202
+ def beforeAccept
203
+ end
204
+ def afterAccept
205
+ end
206
+ def beforeError
207
+ end
208
+ def afterError
209
+ end
210
+ def beforeShift
211
+ end
212
+ def afterShift
213
+ end
214
+ def beforeReduce
215
+ end
216
+ def afterReduce
217
+ end
218
+ end
219
+
220
+ #
221
+ # Action Decorator Base class
222
+ #
223
+ class Action < AdvancedParser
224
+ def initialize inside, nparamkey=nil
225
+ super inside, nparamkey
226
+ @_yy_val_ = []
227
+ end
228
+ def beforeReduce
229
+ @_yy_val_ = []
230
+ n = @reduce_table[-_actvalue][1]
231
+ n.times do |i|
232
+ x = _stack[_stack.size-2*(i+1)]
233
+ @_yy_val_[n-i-1] = x[1] == :NT ? x[@nparam] : x[1]
234
+ end
235
+ end
236
+ def afterReduce
237
+ mes = @on_reduce[-_actvalue]
238
+ r = mes ? self.send(mes, @_yy_val_) : nil
239
+ _stack[_stack.size-2][@nparam] = r
240
+ end
241
+ end
242
+ end
243
+
244
+ class IO
245
+ def path
246
+ self.to_s
247
+ end
248
+ end
@@ -0,0 +1,33 @@
1
+ class ShiftReducePrinter < AdvancedParser
2
+ def initialize inside
3
+ super
4
+ end
5
+ def beforeAccept
6
+ end
7
+ def afterAccept
8
+ end
9
+ def beforeError
10
+ end
11
+ def afterError
12
+ end
13
+ def beforeShift
14
+ end
15
+ def afterShift
16
+ super
17
+ st = _stack.last
18
+ sh = @i2t[_stack[_stack.size-2]]
19
+ la = @i2t[_lookahead]
20
+ warn "shift:<#{sh}> #{st} lookahead:<#{la}>"
21
+ warn _stack
22
+ end
23
+ def beforeReduce
24
+ end
25
+ def afterReduce
26
+ super
27
+ st = _stack.last
28
+ re = @i2nt[_stack[_stack.size-2]]
29
+ la = @i2t[_lookahead]
30
+ warn "reduse:<#{re}> #{st} lookahead:<#{la}>"
31
+ warn _stack
32
+ end
33
+ end
@@ -0,0 +1,161 @@
1
+ %defext StatefulLexerExtension
2
+ %extend Lexer ('depager/lex.rb')
3
+ %extend NVAction ('depager/nvaction.rb')
4
+ %decorate @NVAction
5
+ #%decorate ShiftReducePrinter ('depager/srp.rb')
6
+ %inner{
7
+ attr_accessor :ins, :code, :optval
8
+ def init_parser
9
+ super
10
+ @ins = []
11
+ @optouter = []
12
+ @on_reduce = []
13
+ @addition = []
14
+ end
15
+ def postRuleList
16
+ @optouter << %{
17
+ def afterError
18
+ warn "StatefulLex: lex_state==\#{@basis.lex_state}" if $MP_DEBUG
19
+ end
20
+ }
21
+ g_parser.optouter <<
22
+ gen_action_decorator_code(target_name, paramkey,
23
+ @on_reduce, @optouter)
24
+ end
25
+ def postRhs
26
+ j = 0
27
+ rhs = g_parser.rhs
28
+ @ins.each do |i, m|
29
+ state_name = "#{lhs_name}_#{nrhs}_#{i}"
30
+ if i != rhs.size
31
+ isym = g_parser.add_nonterm("__#{state_name}__".intern)
32
+ new_rule = Rule[isym, []]
33
+ val = ( ":_lex_#{state_name}" )
34
+ @addition << [ new_rule, rhs, val, i+j, isym ]
35
+ j += 1
36
+ else
37
+ @on_reduce[nrules] = ( ":_lex_#{state_name}" )
38
+ end
39
+ @optouter.push << %{
40
+ def _lex_#{lhs_name}_#{nrhs}_#{i} val
41
+ @basis.lex_state = #{m}
42
+ end
43
+ }
44
+ end
45
+ @ins.clear
46
+ end
47
+ def postRhsList
48
+ @addition.each do |new_rule, rhs, val, pos, isym|
49
+ g_parser.g << new_rule
50
+ rhs.insert(pos, isym)
51
+ @on_reduce[nrules] = val
52
+ end
53
+ @addition.clear
54
+ end
55
+ %}
56
+ ######################################################################
57
+ # Define Tokens
58
+ ######################################################################
59
+ %hook prerulelist /%LEX\{\s*\Z/ skip
60
+ %mixin ActionParser ('depager/parse_action')
61
+ %banner '%LEX{ ... }'
62
+ %%
63
+ %LEX{
64
+ /\s+/, /#.*\Z/ { }
65
+ /[A-Z]+/ { yield _Token(:ID, $&) }
66
+ /\%\}\s*\Z/ { @line = $'; yield nil,nil }
67
+ /\/(([^\/\\]+|\\.)*)\//,
68
+ /'([^'\\]+|\\.)*\'/ { yield _Token(:LEX, "/\\A#{$1}/") }
69
+ /\{/ { ln = lineno; yield :ACTION, Token[parse_action, ln]; //=~'' }
70
+ /./ { yield _Token($&, $&) }
71
+ %}
72
+ #begin-rule
73
+ start:
74
+ mode_list
75
+ {
76
+ ll = ''
77
+ _mode_list.each do |m, s, l|
78
+ elsec = if s
79
+ "_rest = lex_#{s}(&block)"
80
+ else
81
+ %!raise RuntimeError, "must not happen \#{@line}"!
82
+ end
83
+ ll << %{
84
+ def lex_#{m}(&block)
85
+ _rest = ''
86
+ case @line
87
+ #{l.map{|i| ' '*4+i}}
88
+ else
89
+ #{elsec}
90
+ end
91
+ return _rest
92
+ end
93
+ }; #code
94
+ end
95
+ g_parser.optinner << ll << %{
96
+ attr_accessor :lex_state
97
+ def lex(&block)
98
+ @lex_state ||= :START
99
+ begin
100
+ until @line.empty?
101
+ @line = self.send "lex_\#{@lex_state}", &block
102
+ end
103
+ end while @line = getline
104
+ yield nil, nil
105
+ end
106
+ }; #code
107
+ }
108
+ ;
109
+ mode_list:
110
+ { [ ] }
111
+ | mode_list mode lexactlist { _mode_list << [_mode[0], _mode[1], _lexactlist] }
112
+ ;
113
+ mode:
114
+ '<' ID opt_super '>' { [ _ID.value, _opt_super ] }
115
+ ;
116
+ opt_super:
117
+ { nil }
118
+ | ':' ID { _ID.value }
119
+ ;
120
+ lexactlist:
121
+ lexact { [ _lexact ] }
122
+ | lexactlist lexact { _lexactlist << _lexact }
123
+ ;
124
+ lexact:
125
+ lexlist ACTION
126
+ {
127
+ %{
128
+ when #{_lexlist.join(', ')}
129
+ _rest = $'
130
+ #{ _ACTION.value }
131
+ }; #code
132
+ }
133
+ ;
134
+ lexlist:
135
+ LEX { [ _LEX.value ] }
136
+ | lexlist ',' LEX { _lexlist.push _LEX }
137
+ ;
138
+ #end-rule
139
+ %%
140
+ ######################################################################
141
+ # Change State
142
+ ######################################################################
143
+ %hook prerhs postsymbol /\[/
144
+ %banner '[> ...]'
145
+ %%
146
+ %LEX{
147
+ /\s+/ { }
148
+ /:[a-zA-Z_]+/ { yield _Token(:SYMBOL, $&) }
149
+ /\]/ { yield _Token($&, $&); @line = $'; yield nil, nil }
150
+ /./ { yield _Token($&, $&) }
151
+ %}
152
+
153
+ #begin-rule
154
+ start:
155
+ '[' '>' SYMBOL ']'
156
+ {
157
+ master.ins.push [g_parser.rhs.size, _SYMBOL.value]
158
+ }
159
+ ;
160
+ #end-rule
161
+ %%