depager 0.1.9 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/ChangeLog +4 -0
  2. data/bin/depager +1 -0
  3. data/data/depager/misc/depager-mode.el +35 -24
  4. data/data/depager/pre-setup.rb +3 -0
  5. data/examples/Rakefile +36 -0
  6. data/examples/c89/c89.dr +496 -0
  7. data/examples/c89/c89.tab.rb +2197 -0
  8. data/examples/c89/test.c89 +10 -0
  9. data/{data/depager/sample → examples}/extension/paction.dr +0 -0
  10. data/{data/depager/sample → examples}/extension/pactiontest.dr +0 -0
  11. data/{data/depager/sample → examples}/pl0d/pl0ds.dr +0 -0
  12. data/examples/pl0d/pl0ds.tab.rb +1702 -0
  13. data/{data/depager/sample/pl0d/pl0test.pl0 → examples/pl0d/test.pl0ds} +0 -0
  14. data/{data/depager/sample → examples}/sample_calc/calc.action.dr +0 -0
  15. data/examples/sample_calc/calc.action.tab.rb +283 -0
  16. data/{data/depager/sample → examples}/sample_calc/calc.astdf.dr +0 -0
  17. data/examples/sample_calc/calc.astdf.tab.rb +476 -0
  18. data/{data/depager/sample → examples}/sample_calc/calc.astl.action.dr +0 -0
  19. data/examples/sample_calc/calc.astl.action.tab.rb +593 -0
  20. data/{data/depager/sample → examples}/sample_calc/calc.astl.dr +0 -0
  21. data/examples/sample_calc/calc.astl.tab.rb +501 -0
  22. data/{data/depager/sample → examples}/sample_calc/calc.atree.dr +0 -0
  23. data/examples/sample_calc/calc.atree.tab.rb +277 -0
  24. data/{data/depager/sample → examples}/sample_calc/calc.cst.dr +0 -0
  25. data/examples/sample_calc/calc.cst.tab.rb +478 -0
  26. data/{data/depager/sample → examples}/sample_calc/calc.dr +0 -0
  27. data/{data/depager/sample → examples}/sample_calc/calc.lex.dr +0 -0
  28. data/examples/sample_calc/calc.lex.tab.rb +192 -0
  29. data/{data/depager/sample → examples}/sample_calc/calc.nvaction.dr +0 -0
  30. data/examples/sample_calc/calc.nvaction.tab.rb +291 -0
  31. data/examples/sample_calc/calc.tab.rb +183 -0
  32. data/{data/depager/sample → examples}/sample_calc/calc_prec.nvaction.dr +0 -0
  33. data/examples/sample_calc/calc_prec.nvaction.tab.rb +257 -0
  34. data/examples/sample_calc/test.calc +1 -0
  35. data/{data/depager/sample/slex_test/slextest1.dr → examples/slex_test/divreg.slex.dr} +3 -11
  36. data/examples/slex_test/divreg.slex.tab.rb +227 -0
  37. data/{data/depager/sample/slex_test/slextest2.dr → examples/slex_test/ljoin.slex.dr} +10 -7
  38. data/examples/slex_test/ljoin.slex.tab.rb +277 -0
  39. data/examples/slex_test/test.divreg +1 -0
  40. data/examples/slex_test/test.ljoin +3 -0
  41. data/lib/depager.rb +194 -127
  42. data/lib/depager/Rakefile +8 -4
  43. data/lib/depager/ast_base.dr +3 -3
  44. data/lib/depager/ast_base.rb +197 -144
  45. data/lib/depager/atree.rb +55 -36
  46. data/lib/depager/cst.dr +6 -4
  47. data/lib/depager/cst.rb +69 -49
  48. data/lib/depager/grammar.rb +136 -0
  49. data/lib/depager/lex.dr +22 -8
  50. data/lib/depager/lex.rb +94 -53
  51. data/lib/depager/lr.rb +101 -167
  52. data/lib/depager/parse_action.rb +1 -1
  53. data/lib/depager/parser.rb +34 -7
  54. data/lib/depager/slex.dr +76 -36
  55. data/lib/depager/slex.rb +345 -151
  56. data/lib/depager/srp.rb +3 -2
  57. data/lib/depager/template/extension_lalr_slave.erb +1 -1
  58. data/lib/depager/template/single_lalr_parser.erb +1 -1
  59. data/lib/depager/utils.rb +2 -1
  60. data/lib/depager/version.rb +2 -2
  61. metadata +42 -28
  62. data/Manifest.txt +0 -52
  63. data/lib/depager/psrtmpl.rb +0 -33
@@ -0,0 +1 @@
1
+ /aaa/ / /bbb/
@@ -0,0 +1,3 @@
1
+ x +
2
+ y +
3
+ z
data/lib/depager.rb CHANGED
@@ -1,10 +1,11 @@
1
1
  require 'erb'
2
- require "depager/lr.rb"
3
2
  require "depager/parser.rb"
3
+ require "depager/grammar.rb"
4
4
  require "depager/utils.rb"
5
5
 
6
6
  module Depager
7
- Tmpldir = "#{File.dirname(__FILE__)}/depager/template"
7
+ Tmpldir = File.expand_path "#{File.dirname(__FILE__)}/depager/template"
8
+
8
9
  #
9
10
  # file manager
10
11
  #
@@ -60,17 +61,23 @@ module Depager
60
61
  case line = files.getline
61
62
  when /^\s*(#.*)?$/
62
63
  #skip space and comment.
63
- when /^%class\s*(\S+)\s*::\s*(\S+)\s*$/
64
+ when /^%class\s+(\S+)\s+based_on\s+(\S+)\s+\(\s*'(.+)'\s*\)\s*$/
64
65
  @target_name = $1
65
- @generator = Object.const_get("#{$2}Generator").new(self)
66
+ require $3
67
+ ns = $2.split(/::/)
68
+ ge = ns.pop
69
+ m = ns.inject(Object){|c,name| c.const_get(name) }
70
+ @generator = m.const_get("#{ge}Generator").new(self)
66
71
  break
67
- when /^%class\s*(.*?)\s*$/
72
+ when /^%class\s+(\S+)\s*$/
73
+ require 'depager/lr.rb'
68
74
  @target_name = $1
69
- @generator = SingleLALRParserGenerator.new(self)
75
+ @generator = LALR::SingleParserGenerator.new(self)
70
76
  break
71
- when /^%defext\s*(.*?)\s*$/
77
+ when /^%defext\s+(\S+)\s*$/
78
+ require 'depager/lr.rb'
72
79
  @target_name = $1
73
- @generator = ExtensionLALRParserGenerator.new(self)
80
+ @generator = LALR::ExtensionParserGenerator.new(self)
74
81
  break
75
82
  else
76
83
  error_exit "%class not found."
@@ -78,6 +85,9 @@ module Depager
78
85
  end
79
86
  @generator.parse_decl
80
87
  end
88
+ def parsing_method
89
+ @generator.parsing_method
90
+ end
81
91
  def error_exit msg, lineno=nil
82
92
  lineno ||= files.lineno
83
93
  warn "#{files.path}:#{lineno}: #{msg}"
@@ -126,7 +136,8 @@ module Depager
126
136
  end
127
137
  def parse_rule
128
138
  if @token[0] == :NT
129
- @r = @token.value
139
+ @lhs = @token.value
140
+
130
141
  gettoken
131
142
  postLhs
132
143
 
@@ -153,7 +164,7 @@ module Depager
153
164
  @optval = Array.new(@nparam)
154
165
  preRhs
155
166
  parse_syms
156
- @g.push Rule[@r, @rhs, @prec]
167
+ add_rule(@lhs, @rhs, @prec)
157
168
  postRhs
158
169
  @nrhs += 1
159
170
 
@@ -164,9 +175,7 @@ module Depager
164
175
  end
165
176
  def parse_syms
166
177
  if @token.tag == :NT || @token.tag == :T
167
- @rhs.push @token.value
168
- @rhsni[@token.name] = @rhs.size - 1
169
-
178
+ rhs_insert_sym(-1, @token.value, @token.name)
170
179
  gettoken
171
180
 
172
181
  postSymbol
@@ -266,11 +275,22 @@ module Depager
266
275
  # add nonterm
267
276
  # sym:: symbol
268
277
  def add_nonterm sym
278
+ sym = sym.to_s.intern
269
279
  isym = @nonterms[sym] = @nonterms.size
270
280
  @i2s[isym] = sym
271
281
  return isym
272
282
  end
273
283
 
284
+ #
285
+ # add rule
286
+ #
287
+ def add_rule lhs, rhs, prec=nil
288
+ @lhs_syms[lhs] = true
289
+ rule = @parsing_method::Rule[lhs, rhs, prec]
290
+ @g.push rule
291
+ return rule
292
+ end
293
+
274
294
  # get rhs index by name
275
295
  # name :: name
276
296
  def name_to_rhs_index name
@@ -278,41 +298,60 @@ module Depager
278
298
  end
279
299
  alias n2ri name_to_rhs_index
280
300
 
281
- # lhs value
282
- def lhs
283
- @r
301
+ # insert sym into rhs
302
+ def rhs_insert_sym pos, token_value, token_name
303
+ if pos < 0
304
+ @rhs.push token_value
305
+ @rhsni[token_name] = @rhs.size - 1
306
+ @rhs_syms[token_value] = true
307
+ else
308
+ @rhsni.each{|k, v| @rhsni[k] += 1 if v >= pos }
309
+ @rhs.insert(pos, token_value)
310
+ @rhsni[token_name] = pos
311
+ @rhs_syms[token_value] = true
312
+ end
284
313
  end
285
314
 
286
315
  attr_accessor :g, :terms, :nonterms, :precs
287
316
  attr_accessor :line, :line0, :oldline, :token
288
317
  attr_accessor :optouter, :optinner, :optmain, :mixin
289
- attr_accessor :nparams, :rhs, :nrhs, :rhsni, :nparam, :r, :nrules
318
+ attr_accessor :nparams, :lhs, :rhs, :nrhs, :rhsni, :nparam, :nrules
290
319
  attr_accessor :prerulelist, :postrulelist, :prerule, :postrule
291
320
  attr_accessor :postlhs, :prerhslist, :postrhslist
292
321
  attr_accessor :prerhs, :postrhs, :postsymbol
293
- attr_reader :d_parser, :target_name, :table
322
+ attr_reader :d_parser, :target_name, :table, :parsing_method
294
323
 
295
324
  def initialize d_parser
296
325
  @yydebug = true
297
326
  @d_parser = d_parser
298
327
 
299
- @i2s = {}
300
-
301
- @g = [Rule[0 , [1]]]
302
- @terms = { nil => -1, false => -2 }
303
- @nonterms = {'$start' => 0}
304
-
305
328
  @optinner = []
306
329
  @optouter = []
307
330
  @optmain = []
308
-
309
331
  @nparams = {}
310
332
  @nparam = 1
311
-
312
333
  init_hook
313
334
  end
314
335
 
315
336
  private
337
+ # check grammar
338
+ def check_grammar
339
+ lhs_warns = []
340
+ @lhs_syms.each do |s, _|
341
+ lhs_warns << s if s != 1 and !@rhs_syms[s]
342
+ end
343
+ rhs_warns = []
344
+ @rhs_syms.each do |s, _|
345
+ rhs_warns << s if s > 0 and !@lhs_syms[s]
346
+ end
347
+ lhs_warns.uniq.each do |s|
348
+ warning "the lhs '#{@i2s[s]}' is not used"
349
+ end
350
+ rhs_warns.uniq.each do |s|
351
+ warning "the symbol '#{@i2s[s]}' is undefined"
352
+ end
353
+ end
354
+
316
355
  # make grammar object
317
356
  # precs:: prec infos
318
357
  def make_grammar precs
@@ -356,6 +395,15 @@ module Depager
356
395
  @postsymbol = []
357
396
  end
358
397
 
398
+ def init_grammar
399
+ @g = [@parsing_method::Rule[0 , [1]]]
400
+ @terms = { nil => -1, false => -2 }
401
+ @nonterms = {'$start' => 0}
402
+ @i2s = {}
403
+ @rhs_syms = {}
404
+ @lhs_syms = {}
405
+ end
406
+
359
407
  public
360
408
  # extend paser
361
409
  # ext:: extension name
@@ -378,18 +426,29 @@ module Depager
378
426
  # mixin:: mixin modules
379
427
  # precs:: prec infos
380
428
  # return:: LALRTable
381
- def parse(target_name = nil, mixin = [], precs = [])
429
+ def parse(target_name = nil, mixin = [], precs = [], pm=nil)
382
430
  @line = @line0 = ''
383
431
  @oldline = nil
384
432
  @target_name = target_name
385
433
  @mixin = mixin
434
+ @parsing_method = pm || @d_parser.generator.parsing_method
386
435
 
436
+ init_grammar
387
437
  parse_grammar
438
+ check_grammar
388
439
  make_grammar precs
389
- @table = LALRTable.new(G.new(@g, @terms, @nonterms, @precs))
440
+ @table = @parsing_method::Table.new(
441
+ @parsing_method::Grammar.new(@g, @terms, @nonterms, @precs))
442
+ @table.check_table @d_parser
443
+ @table
390
444
  end
391
445
  end
392
446
 
447
+ #
448
+ # generators
449
+ #
450
+
451
+ # Generator base
393
452
  class Generator
394
453
  include FileUtils
395
454
  def files
@@ -403,11 +462,12 @@ module Depager
403
462
  def tmplf
404
463
  self.class::Tmplfile
405
464
  end
406
- attr_reader :d_parser
465
+ attr_reader :d_parser, :parsing_method
407
466
  attr_accessor :optouter, :optinner, :optmain
408
467
  attr_accessor :basis_name, :deco, :req
409
468
  def initialize d_parser
410
469
  @d_parser = d_parser
470
+ @parsing_method = nil
411
471
  @basis_name = nil
412
472
 
413
473
  @deco = []
@@ -488,121 +548,128 @@ module Depager
488
548
  end
489
549
  end
490
550
 
491
- class SimpleGenerator < Generator
492
- Tmplfile = 'simple.erb'
493
- def initialize d_parser
494
- super
551
+
552
+ module Simple
553
+ class G
554
+ def initialize *args
555
+ end
495
556
  end
496
- def out_code g_parser
497
- ERB.new(File.read("#{tmpldir}/#{tmplf}")).result(binding)
557
+ class Table
558
+ def initialize *args
559
+ end
498
560
  end
499
- def parse_decl
500
- until eof?
501
- line = getline
502
- case line
503
- when /^%%\s*$/
504
- g_parser = GrammarParser.new(@d_parser)
505
- g_parser.extend_paser @ext
506
- g_parser.parse(@d_parser.target_name, @mixin, @precs)
507
- @optmain.push parse_block
508
- return out_code(g_parser)
509
- else
510
- parse_common(line)
561
+ class SingleGenerator < Generator
562
+ Tmplfile = 'simple.erb'
563
+ def initialize d_parser
564
+ super
565
+ @parsing_method = Simple
566
+ end
567
+ def out_code g_parser
568
+ ERB.new(File.read("#{tmpldir}/#{tmplf}")).result(binding)
569
+ end
570
+ def parse_decl
571
+ until eof?
572
+ line = getline
573
+ case line
574
+ when /^%%\s*$/
575
+ g_parser = GrammarParser.new(@d_parser)
576
+ g_parser.extend_paser @ext
577
+ g_parser.parse(@d_parser.target_name, @mixin, @precs)
578
+ @optmain.push parse_block
579
+ return out_code(g_parser)
580
+ else
581
+ parse_common(line)
582
+ end
511
583
  end
584
+ return nil
512
585
  end
513
- return nil
514
586
  end
515
- end
516
587
 
517
- class SingleLALRParserGenerator < SimpleGenerator
518
- Tmplfile = 'single_lalr_parser.erb'
519
- def initialize d_parser
520
- super
521
- @basis_name = @d_parser.target_name + '.new()'
522
- end
523
- end
524
-
525
- class ExtensionLALRParserGenerator < Generator
526
- attr_accessor :regs, :paramkey
527
- def initialize d_parser
528
- super
529
- @basis_name = 'self'
530
- @paramkey = nil
531
- @regs = {
532
- "prerulelist" => nil,
533
- "postrulelist" => nil,
588
+ class ExtensionGenerator < Generator
589
+ TmplfileMaster = '**NOTHING**'
590
+ TmplfileSlave = '**NOTHING**'
591
+ attr_accessor :regs, :paramkey
592
+ def initialize d_parser
593
+ super
594
+ @parsing_method = Simple
595
+ @basis_name = 'self'
596
+ @paramkey = nil
597
+ @regs = {
598
+ "prerulelist" => nil,
599
+ "postrulelist" => nil,
534
600
 
535
- "prerule" => nil,
536
- "postrule" => nil,
601
+ "prerule" => nil,
602
+ "postrule" => nil,
537
603
 
538
- "postlhs" => nil,
604
+ "postlhs" => nil,
539
605
 
540
- "postrhslist" => nil,
541
- "prerhslist" => nil,
606
+ "postrhslist" => nil,
607
+ "prerhslist" => nil,
542
608
 
543
- "prerhs" => nil,
544
- "postrhs" => nil,
545
- }
546
- end
609
+ "prerhs" => nil,
610
+ "postrhs" => nil,
611
+ }
612
+ end
547
613
 
548
- def parse_decl
549
- until eof?
550
- line = getline
551
- case line
552
- when /^%hook\s*(.*?)\s*$/
553
- hs = $1
554
- mtsk = if hs =~ /\/(([^\/\\]+|\\.)*)\/\s*(skip)?$/
555
- hs = $`
556
- [$1, $3 ? true : false]
557
- end
558
- hook = hs.split(' ')
559
- hookname = hook.join('_')
560
- hook.each{|i| @regs[i] = [i, "#{@d_parser.target_name}_#{hookname}"]}
561
- @optouter.push(parse_hook(hookname, mtsk))
562
- when /^%param\s*(.*)\s*$/
563
- @paramkey = $1
564
- else
565
- parse_common(line)
614
+ def parse_decl
615
+ until eof?
616
+ line = getline
617
+ case line
618
+ when /^%hook\s*(.*?)\s*$/
619
+ hs = $1
620
+ mtsk = if hs =~ /\/(([^\/\\]+|\\.)*)\/\s*(skip)?$/
621
+ hs = $`
622
+ [$1, $3 ? true : false]
623
+ end
624
+ hook = hs.split(' ')
625
+ hookname = hook.join('_')
626
+ hook.each{|i| @regs[i] = [i, "#{@d_parser.target_name}_#{hookname}"]}
627
+ @optouter.push(parse_hook(hookname, mtsk))
628
+ when /^%param\s*(.*)\s*$/
629
+ @paramkey = $1
630
+ else
631
+ parse_common(line)
632
+ end
566
633
  end
634
+ return out_master_code
567
635
  end
568
- return out_master_code
569
- end
570
636
 
571
- def parse_hook hookname, mtsk
572
- inner = ''
573
- precs = []
574
- banner = nil
575
- mixin = [].concat(@mixin)
576
- target_name = "#{@d_parser.target_name}_#{hookname}"
577
- until eof?
578
- line = getline
579
- case line
580
- when /^%banner\s*'(([^'\\]+|\\.)*)'\s*$/
581
- banner = $1
582
- when /^%inner\s*\{\s*$/
583
- inner = parse_block
584
- when /^%mixin\s*(.+?)\s*(\((.+)\)\s*)?$/
585
- mixin.push $1
586
- @req.push $3 if $3
587
- when /^%prec\s*(.*?)\s*$/
588
- precs = parse_prec
589
- when /^%%\s*$/
590
- g_parser = GrammarParser.new(@d_parser)
591
- g_parser.extend_paser @ext
592
- g_parser.parse(target_name, mixin, precs)
593
- g_parser.optinner.push inner
594
- return out_slave_code(g_parser, mixin, mtsk, banner)
595
- else
596
- warning "syntax error(declaration).\n> #{line}", lineno
637
+ def parse_hook hookname, mtsk
638
+ inner = ''
639
+ precs = []
640
+ banner = nil
641
+ mixin = [].concat(@mixin)
642
+ target_name = "#{@d_parser.target_name}_#{hookname}"
643
+ until eof?
644
+ line = getline
645
+ case line
646
+ when /^%banner\s*'(([^'\\]+|\\.)*)'\s*$/
647
+ banner = $1
648
+ when /^%inner\s*\{\s*$/
649
+ inner = parse_block
650
+ when /^%mixin\s*(.+?)\s*(\((.+)\)\s*)?$/
651
+ mixin.push $1
652
+ @req.push $3 if $3
653
+ when /^%prec\s*(.*?)\s*$/
654
+ precs = parse_prec
655
+ when /^%%\s*$/
656
+ g_parser = GrammarParser.new(@d_parser)
657
+ g_parser.extend_paser @ext
658
+ g_parser.parse(target_name, mixin, precs)
659
+ g_parser.optinner.push inner
660
+ return out_slave_code(g_parser, mixin, mtsk, banner)
661
+ else
662
+ warning "syntax error(declaration).\n> #{line}", lineno
663
+ end
597
664
  end
598
665
  end
599
- end
600
666
 
601
- def out_slave_code g_parser, mixin, mtsk, banner
602
- ERB.new(File.read("#{tmpldir}/extension_lalr_slave.erb")).result(binding)
603
- end
604
- def out_master_code
605
- ERB.new(File.read("#{tmpldir}/extension_lalr_master.erb")).result(binding)
667
+ def out_slave_code g_parser, mixin, mtsk, banner
668
+ ERB.new(File.read(self.class::TmplfileSlave)).result(binding)
669
+ end
670
+ def out_master_code
671
+ ERB.new(File.read(self.class::TmplfileMaster)).result(binding)
672
+ end
606
673
  end
607
674
  end
608
675
  end