depager 0.1.9

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