packcr 0.0.3 → 0.0.6

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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/exe/packcr +3 -0
  3. data/lib/packcr/broadcast.rb +17 -0
  4. data/lib/packcr/cli.rb +25 -0
  5. data/lib/packcr/code_block.rb +2 -3
  6. data/lib/packcr/context.rb +58 -872
  7. data/lib/packcr/generator.rb +13 -10
  8. data/lib/packcr/node/action_node.rb +20 -5
  9. data/lib/packcr/node/alternate_node.rb +27 -14
  10. data/lib/packcr/node/capture_node.rb +22 -8
  11. data/lib/packcr/node/charclass_node.rb +41 -13
  12. data/lib/packcr/node/eof_node.rb +23 -0
  13. data/lib/packcr/node/error_node.rb +29 -11
  14. data/lib/packcr/node/expand_node.rb +14 -4
  15. data/lib/packcr/node/predicate_node.rb +19 -23
  16. data/lib/packcr/node/quantity_node.rb +28 -18
  17. data/lib/packcr/node/reference_node.rb +43 -5
  18. data/lib/packcr/node/root_node.rb +60 -0
  19. data/lib/packcr/node/rule_node.rb +38 -3
  20. data/lib/packcr/node/sequence_node.rb +51 -31
  21. data/lib/packcr/node/string_node.rb +16 -12
  22. data/lib/packcr/node.rb +48 -0
  23. data/lib/packcr/parser.rb +4570 -0
  24. data/lib/packcr/stream.rb +9 -13
  25. data/lib/packcr/templates/context/header.c.erb +29 -0
  26. data/lib/packcr/templates/context/source.c.erb +1292 -0
  27. data/lib/packcr/templates/context/source.rb.erb +406 -0
  28. data/lib/packcr/templates/node/action.c.erb +16 -0
  29. data/lib/packcr/templates/node/action.rb.erb +21 -0
  30. data/lib/packcr/templates/node/alternate.c.erb +34 -0
  31. data/lib/packcr/templates/node/alternate.rb.erb +40 -0
  32. data/lib/packcr/templates/node/capture.c.erb +17 -0
  33. data/lib/packcr/templates/node/capture.rb.erb +14 -0
  34. data/lib/packcr/templates/node/charclass.c.erb +47 -0
  35. data/lib/packcr/templates/node/charclass.rb.erb +49 -0
  36. data/lib/packcr/templates/node/charclass_any.c.erb +5 -0
  37. data/lib/packcr/templates/node/charclass_any.rb.erb +7 -0
  38. data/lib/packcr/templates/node/charclass_fail.c.erb +1 -0
  39. data/lib/packcr/templates/node/charclass_fail.rb.erb +1 -0
  40. data/lib/packcr/templates/node/charclass_one.c.erb +19 -0
  41. data/lib/packcr/templates/node/charclass_one.rb.erb +23 -0
  42. data/lib/packcr/templates/node/charclass_utf8.c.erb +49 -0
  43. data/lib/packcr/templates/node/charclass_utf8.rb.erb +50 -0
  44. data/lib/packcr/templates/node/charclass_utf8_reverse.rb.erb +51 -0
  45. data/lib/packcr/templates/node/eof.c.erb +1 -0
  46. data/lib/packcr/templates/node/eof.rb.erb +3 -0
  47. data/lib/packcr/templates/node/error.c.erb +28 -0
  48. data/lib/packcr/templates/node/error.rb.erb +34 -0
  49. data/lib/packcr/templates/node/expand.c.erb +16 -0
  50. data/lib/packcr/templates/node/expand.rb.erb +16 -0
  51. data/lib/packcr/templates/node/predicate.c.erb +30 -0
  52. data/lib/packcr/templates/node/predicate.rb.erb +28 -0
  53. data/lib/packcr/templates/node/predicate_neg.c.erb +23 -0
  54. data/lib/packcr/templates/node/predicate_neg.rb.erb +22 -0
  55. data/lib/packcr/templates/node/quantify_many.c.erb +45 -0
  56. data/lib/packcr/templates/node/quantify_many.rb.erb +47 -0
  57. data/lib/packcr/templates/node/quantify_one.c.erb +21 -0
  58. data/lib/packcr/templates/node/quantify_one.rb.erb +23 -0
  59. data/lib/packcr/templates/node/reference.c.erb +5 -0
  60. data/lib/packcr/templates/node/reference.rb.erb +9 -0
  61. data/lib/packcr/templates/node/reference_reverse.rb.erb +9 -0
  62. data/lib/packcr/templates/node/rule.c.erb +19 -0
  63. data/lib/packcr/templates/node/rule.rb.erb +23 -0
  64. data/lib/packcr/templates/node/sequence.c.erb +12 -0
  65. data/lib/packcr/templates/node/sequence.rb.erb +12 -0
  66. data/lib/packcr/templates/node/string_many.c.erb +11 -0
  67. data/lib/packcr/templates/node/string_many.rb.erb +10 -0
  68. data/lib/packcr/templates/node/string_one.c.erb +8 -0
  69. data/lib/packcr/templates/node/string_one.rb.erb +10 -0
  70. data/lib/packcr/tokenizer.rb +2948 -0
  71. data/lib/packcr/util.rb +3 -8
  72. data/lib/packcr/version.rb +1 -1
  73. data/lib/packcr.rb +1 -2
  74. metadata +88 -8
  75. data/lib/packcr/buffer.rb +0 -47
@@ -0,0 +1,60 @@
1
+ class Packcr
2
+ class Node
3
+ class RootNode < Packcr::Node
4
+ attr_accessor :rules
5
+ attr_reader :rulehash
6
+
7
+ def initialize
8
+ @rules = []
9
+ @rulehash = {}
10
+ @implicit_rules = []
11
+ end
12
+
13
+ def debug_dump
14
+ @rules.each(&:debug_dump)
15
+ end
16
+
17
+ def make_rulehash(ctx)
18
+ @rules.each do |rule|
19
+ if @rulehash[rule.name]
20
+ ctx.error rule.line + 1, rule.col + 1, "Multiple definition of rule '#{rule.name}'"
21
+ else
22
+ @rulehash[rule.name] = rule
23
+ end
24
+ end
25
+ end
26
+
27
+ def setup(ctx)
28
+ make_rulehash(ctx)
29
+ @rules.first&.top = true
30
+ @rules.each do |rule|
31
+ rule.setup(ctx)
32
+ end
33
+ @rules.each do |rule|
34
+ rule.verify(ctx)
35
+ end
36
+ end
37
+
38
+ def rule(name)
39
+ rule = @rulehash[name]
40
+ return rule if rule
41
+ case name
42
+ when "EOF"
43
+ expr = Packcr::Node::EofNode.new
44
+ else
45
+ return nil
46
+ end
47
+ rule = Packcr::Node::RuleNode.new(expr, name)
48
+ @rules << rule
49
+ @rulehash[name] = rule
50
+ end
51
+
52
+ def to_h
53
+ {
54
+ type: :root,
55
+ rules: rules.map(&:to_h),
56
+ }
57
+ end
58
+ end
59
+ end
60
+ end
@@ -1,14 +1,18 @@
1
1
  class Packcr
2
2
  class Node
3
3
  class RuleNode < Packcr::Node
4
- attr_accessor :codes, :name, :expr, :ref, :vars, :capts, :line, :col
4
+ attr_accessor :codes, :name, :expr, :ref, :vars, :capts, :line, :col, :top
5
5
 
6
- def initialize
7
- super
6
+ def initialize(expr = nil, name = nil, line = nil, col = nil)
7
+ super()
8
8
  self.ref = 0
9
9
  self.vars = []
10
10
  self.capts = []
11
11
  self.codes = []
12
+ @expr = expr
13
+ @name = name
14
+ @line = line
15
+ @col = col
12
16
  end
13
17
 
14
18
  def debug_dump(indent = 0)
@@ -17,14 +21,45 @@ class Packcr
17
21
  $stdout.print "#{" " * indent}}\n"
18
22
  end
19
23
 
24
+ def generate_code(gen, onfail, indent, bare, oncut: nil)
25
+ gen.write Packcr.template("node/rule.#{gen.lang}.erb", binding, indent: indent, unwrap: bare)
26
+ end
27
+
28
+ def reachability
29
+ expr.reachability
30
+ end
31
+
20
32
  def verify(ctx)
21
33
  expr.verify_variables([])
22
34
  expr.verify_captures(ctx, [])
35
+ verify_rule_reference(ctx)
36
+ end
37
+
38
+ def verify_rule_reference(ctx)
39
+ return if top
40
+ if ref == 0
41
+ ctx.error line + 1, col + 1, "Never used rule '#{name}'"
42
+ end
23
43
  end
24
44
 
25
45
  def add_ref
26
46
  @ref += 1
27
47
  end
48
+
49
+ def setup(ctx)
50
+ super(ctx, self)
51
+ end
52
+
53
+ def nodes
54
+ [expr]
55
+ end
56
+
57
+ def to_h
58
+ {
59
+ type: :rule,
60
+ expr: expr&.to_h,
61
+ }
62
+ end
28
63
  end
29
64
  end
30
65
  end
@@ -3,13 +3,44 @@ class Packcr
3
3
  class SequenceNode < Packcr::Node
4
4
  attr_accessor :nodes
5
5
 
6
- def initialize
7
- super
8
- self.nodes = []
6
+ def initialize(*nodes, cut: false)
7
+ super()
8
+ self.nodes = nodes
9
+ @cut = cut
10
+ end
11
+
12
+ def sequence?
13
+ true
14
+ end
15
+
16
+ def seq(node, cut: false)
17
+ if node&.sequence?
18
+ node.nodes.each do |child|
19
+ seq(child, cut: cut)
20
+ cut = false
21
+ end
22
+ return self
23
+ end
24
+
25
+ if cut
26
+ if node
27
+ node = Packcr::Node::SequenceNode.new(node, cut: true)
28
+ else
29
+ node = Packcr::Node::SequenceNode.new(cut: true)
30
+ end
31
+ end
32
+ if node
33
+ if @nodes.last.sequence?
34
+ @nodes.last.seq(node)
35
+ else
36
+ @nodes << node
37
+ end
38
+ end
39
+ self
9
40
  end
10
41
 
11
42
  def debug_dump(indent = 0)
12
- $stdout.print "#{" " * indent}Sequence(max:#{max}, len:#{nodes.length}) {\n"
43
+ $stdout.print "#{" " * indent}Sequence(max:#{max}, len:#{nodes.length}#{@cut ? ", cut: true" : ""}) {\n"
13
44
  nodes.each do |child_node|
14
45
  child_node.debug_dump(indent + 2)
15
46
  end
@@ -22,39 +53,28 @@ class Packcr
22
53
  m
23
54
  end
24
55
 
25
- def generate_code(gen, onfail, indent, bare)
26
- b = false
27
- nodes.each_with_index do |expr, i|
28
- case gen.generate_code(expr, onfail, indent, false)
56
+ def generate_code(gen, onfail, indent, bare, oncut: nil)
57
+ gen.write Packcr.template("node/sequence.#{gen.lang}.erb", binding, indent: indent)
58
+ end
59
+
60
+ def reachability
61
+ r = Packcr::CODE_REACH__ALWAYS_SUCCEED
62
+ nodes.each do |expr|
63
+ case expr.reachability
29
64
  when Packcr::CODE_REACH__ALWAYS_FAIL
30
- if i + 1 < nodes.length
31
- gen.write Packcr.template("node/sequence_unreachable.#{gen.lang}.erb", binding, indent: indent)
32
- end
33
65
  return Packcr::CODE_REACH__ALWAYS_FAIL
34
- when Packcr::CODE_REACH__ALWAYS_SUCCEED
35
- else
36
- b = true
66
+ when Packcr::CODE_REACH__BOTH
67
+ r = Packcr::CODE_REACH__BOTH
37
68
  end
38
69
  end
39
- return b ? Packcr::CODE_REACH__BOTH : Packcr::CODE_REACH__ALWAYS_SUCCEED
70
+ r
40
71
  end
41
72
 
42
- def verify_variables(vars)
43
- nodes.each do |node|
44
- node.verify_variables(vars)
45
- end
46
- end
47
-
48
- def verify_captures(ctx, capts)
49
- nodes.each do |node|
50
- node.verify_captures(ctx, capts)
51
- end
52
- end
53
-
54
- def link_references(ctx)
55
- nodes.each do |node|
56
- node.link_references(ctx)
57
- end
73
+ def to_h
74
+ {
75
+ type: :sequence,
76
+ nodes: nodes.map(&:to_h),
77
+ }
58
78
  end
59
79
  end
60
80
  end
@@ -3,6 +3,10 @@ class Packcr
3
3
  class StringNode < Packcr::Node
4
4
  attr_accessor :value
5
5
 
6
+ def initialize(value = nil)
7
+ self.value = value
8
+ end
9
+
6
10
  def value=(value)
7
11
  @value = value&.b
8
12
  end
@@ -13,30 +17,30 @@ class Packcr
13
17
  $stdout.print "')\n"
14
18
  end
15
19
 
16
- def generate_code(gen, onfail, indent, bare)
20
+ def generate_code(gen, onfail, indent, bare, oncut: nil)
17
21
  n = value&.length || 0
18
22
  if n > 0
19
23
  if n > 1
20
24
  gen.write Packcr.template("node/string_many.#{gen.lang}.erb", binding, indent: indent)
21
- return Packcr::CODE_REACH__BOTH
22
25
  else
23
26
  gen.write Packcr.template("node/string_one.#{gen.lang}.erb", binding, indent: indent)
24
- return Packcr::CODE_REACH__BOTH
25
27
  end
26
- else
27
- # no code to generate
28
- return Packcr::CODE_REACH__ALWAYS_SUCCEED
29
28
  end
30
- Packcr::CODE_REACH__BOTH
31
- end
32
-
33
- def verify_variables(vars)
34
29
  end
35
30
 
36
- def verify_captures(ctx, capts)
31
+ def reachability
32
+ n = value&.length || 0
33
+ if n <= 0
34
+ return Packcr::CODE_REACH__ALWAYS_SUCCEED
35
+ end
36
+ Packcr::CODE_REACH__BOTH
37
37
  end
38
38
 
39
- def link_references(ctx)
39
+ def to_h
40
+ {
41
+ type: :string,
42
+ value: value,
43
+ }
40
44
  end
41
45
  end
42
46
  end
data/lib/packcr/node.rb CHANGED
@@ -1,8 +1,55 @@
1
1
  class Packcr
2
2
  class Node
3
+ def seq(expr, cut: false)
4
+ SequenceNode.new(self).seq(expr, cut: cut)
5
+ end
6
+
7
+ def alt(expr)
8
+ AlternateNode.new(self).alt(expr)
9
+ end
10
+
11
+ def verify_variables(vars)
12
+ nodes.each do |node|
13
+ node.verify_variables(vars)
14
+ end
15
+ end
16
+
17
+ def verify_captures(ctx, capts)
18
+ nodes.each do |node|
19
+ node.verify_captures(ctx, capts)
20
+ end
21
+ end
22
+
23
+ def link_references(ctx)
24
+ end
25
+
26
+ def setup_rule(rule)
27
+ end
28
+
29
+ def setup(ctx, rule)
30
+ setup_rule(rule)
31
+ link_references(ctx)
32
+
33
+ nodes.each do |node|
34
+ node.setup(ctx, rule)
35
+ end
36
+ end
37
+
38
+ def nodes
39
+ []
40
+ end
41
+
42
+ def reversible?(gen)
43
+ false
44
+ end
45
+
46
+ def sequence?
47
+ false
48
+ end
3
49
  end
4
50
  end
5
51
 
52
+ require "packcr/node/root_node"
6
53
  require "packcr/node/rule_node"
7
54
  require "packcr/node/reference_node"
8
55
  require "packcr/node/string_node"
@@ -15,3 +62,4 @@ require "packcr/node/capture_node"
15
62
  require "packcr/node/expand_node"
16
63
  require "packcr/node/action_node"
17
64
  require "packcr/node/error_node"
65
+ require "packcr/node/eof_node"