treetop 1.6.6 → 1.6.11

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 (66) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile +18 -0
  3. data/History.txt +18 -0
  4. data/README.md +2 -0
  5. data/Rakefile +10 -43
  6. data/Treetop.tmbundle/Preferences/Comments.tmPreferences +28 -0
  7. data/Treetop.tmbundle/Snippets/grammar ___ end.tmSnippet +20 -0
  8. data/Treetop.tmbundle/Snippets/rule ___ end.tmSnippet +18 -0
  9. data/Treetop.tmbundle/Support/nibs/SyntaxTreeViewer.nib/designable.nib +1524 -0
  10. data/Treetop.tmbundle/Support/nibs/SyntaxTreeViewer.nib/keyedobjects.nib +0 -0
  11. data/Treetop.tmbundle/Support/syntax_tree_viewer.rb +117 -0
  12. data/Treetop.tmbundle/Syntaxes/Treetop Grammar.tmLanguage +358 -0
  13. data/Treetop.tmbundle/info.plist +10 -0
  14. data/doc/pitfalls_and_advanced_techniques.markdown +6 -0
  15. data/doc/syntactic_recognition.markdown +2 -2
  16. data/lib/treetop/compiler/grammar_compiler.rb +6 -3
  17. data/lib/treetop/compiler/metagrammar.rb +97 -77
  18. data/lib/treetop/compiler/metagrammar.treetop +1 -1
  19. data/lib/treetop/compiler/ruby_builder.rb +2 -2
  20. data/lib/treetop/ruby_extensions/string.rb +0 -6
  21. data/lib/treetop/runtime/compiled_parser.rb +15 -2
  22. data/lib/treetop/version.rb +1 -1
  23. data/treetop.gemspec +25 -157
  24. metadata +15 -61
  25. data/doc/site.rb +0 -112
  26. data/doc/sitegen.rb +0 -65
  27. data/spec/compiler/and_predicate_spec.rb +0 -36
  28. data/spec/compiler/anything_symbol_spec.rb +0 -47
  29. data/spec/compiler/character_class_spec.rb +0 -304
  30. data/spec/compiler/choice_spec.rb +0 -89
  31. data/spec/compiler/circular_compilation_spec.rb +0 -30
  32. data/spec/compiler/failure_propagation_functional_spec.rb +0 -21
  33. data/spec/compiler/grammar_compiler_spec.rb +0 -113
  34. data/spec/compiler/grammar_spec.rb +0 -44
  35. data/spec/compiler/multibyte_chars_spec.rb +0 -38
  36. data/spec/compiler/namespace_spec.rb +0 -42
  37. data/spec/compiler/nonterminal_symbol_spec.rb +0 -40
  38. data/spec/compiler/not_predicate_spec.rb +0 -52
  39. data/spec/compiler/occurrence_range_spec.rb +0 -186
  40. data/spec/compiler/one_or_more_spec.rb +0 -35
  41. data/spec/compiler/optional_spec.rb +0 -37
  42. data/spec/compiler/parenthesized_expression_spec.rb +0 -34
  43. data/spec/compiler/parsing_rule_spec.rb +0 -61
  44. data/spec/compiler/repeated_subrule_spec.rb +0 -29
  45. data/spec/compiler/semantic_predicate_spec.rb +0 -176
  46. data/spec/compiler/sequence_spec.rb +0 -129
  47. data/spec/compiler/terminal_spec.rb +0 -177
  48. data/spec/compiler/terminal_symbol_spec.rb +0 -40
  49. data/spec/compiler/test_grammar.treetop +0 -7
  50. data/spec/compiler/test_grammar.tt +0 -7
  51. data/spec/compiler/test_grammar_do.treetop +0 -7
  52. data/spec/compiler/test_grammar_magic_coding.treetop +0 -8
  53. data/spec/compiler/test_grammar_magic_encoding.treetop +0 -8
  54. data/spec/compiler/tt_compiler_spec.rb +0 -224
  55. data/spec/compiler/zero_or_more_spec.rb +0 -58
  56. data/spec/composition/a.treetop +0 -11
  57. data/spec/composition/b.treetop +0 -11
  58. data/spec/composition/c.treetop +0 -10
  59. data/spec/composition/d.treetop +0 -10
  60. data/spec/composition/f.treetop +0 -17
  61. data/spec/composition/grammar_composition_spec.rb +0 -40
  62. data/spec/composition/subfolder/e_includes_c.treetop +0 -15
  63. data/spec/ruby_extensions/string_spec.rb +0 -32
  64. data/spec/runtime/compiled_parser_spec.rb +0 -153
  65. data/spec/runtime/syntax_node_spec.rb +0 -77
  66. data/spec/spec_helper.rb +0 -123
@@ -1,58 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module ZeroOrMoreSpec
4
- class Foo < Treetop::Runtime::SyntaxNode
5
- end
6
-
7
- describe "zero or more of a terminal symbol followed by a node class declaration and a block" do
8
- # testing_expression '("foo" { def b_method; end } )* <ZeroOrMoreSpec::Foo> { def a_method; end }'
9
- # testing_expression '("foo" { def a_method; end } )* <ZeroOrMoreSpec::Foo>'
10
- testing_expression '"foo"* <ZeroOrMoreSpec::Foo> { def a_method; end }'
11
-
12
- it "successfully parses epsilon, returning an instance declared node class and recording a terminal failure" do
13
- parse('') do |result|
14
- result.should_not be_nil
15
- result.should be_an_instance_of(Foo)
16
- result.should respond_to(:a_method)
17
-
18
- terminal_failures = parser.terminal_failures
19
- terminal_failures.size.should == 1
20
- failure = terminal_failures.first
21
- failure.index.should == 0
22
- failure.expected_string.should == '"foo"'
23
- end
24
- end
25
-
26
- it "successfully parses two of that terminal in a row, returning an instance of the declared node class and recording a failure representing the third attempt " do
27
- parse("foofoo") do |result|
28
- result.should_not be_nil
29
- result.should be_an_instance_of(Foo)
30
-
31
- terminal_failures = parser.terminal_failures
32
- terminal_failures.size.should == 1
33
- failure = terminal_failures.first
34
- failure.index.should == 6
35
- failure.expected_string.should == '"foo"'
36
- end
37
- end
38
- end
39
-
40
- describe "Zero or more of a sequence" do
41
- testing_expression '("foo" "bar")*'
42
-
43
- it "resets the index appropriately following partially matcing input" do
44
- parse('foobarfoo', :consume_all_input => false) do |result|
45
- result.should_not be_nil
46
- result.interval.should == (0...6)
47
- end
48
- end
49
- end
50
-
51
- describe "Zero or more of a choice" do
52
- testing_expression '("a" / "bb")*'
53
-
54
- it "successfully parses matching input" do
55
- parse('abba').should_not be_nil
56
- end
57
- end
58
- end
@@ -1,11 +0,0 @@
1
- module Test
2
- grammar A
3
- rule a
4
- 'a'
5
- end
6
-
7
- rule inherit
8
- 'super'
9
- end
10
- end
11
- end
@@ -1,11 +0,0 @@
1
- module Test
2
- grammar B
3
- rule b
4
- 'bb'
5
- end
6
-
7
- rule inherit
8
- super 'keyword'
9
- end
10
- end
11
- end
@@ -1,10 +0,0 @@
1
- module Test
2
- grammar C
3
- include A
4
- include B
5
-
6
- rule c
7
- a b 'c'
8
- end
9
- end
10
- end
@@ -1,10 +0,0 @@
1
- module Test
2
- grammar D
3
- include A
4
- include B
5
-
6
- rule inherit
7
- super 'works'
8
- end
9
- end
10
- end
@@ -1,17 +0,0 @@
1
-
2
- require "a"
3
-
4
- require File.dirname(__FILE__) + "/b"
5
- require File.dirname(__FILE__) + "/subfolder/e_includes_c"
6
-
7
- module Test
8
- grammar F
9
- include A
10
- include B
11
- include E
12
-
13
- rule f
14
- c e 'f'
15
- end
16
- end
17
- end
@@ -1,40 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module GrammarCompositionSpec
4
- describe "several composed grammars" do
5
- before do
6
- dir = File.dirname(__FILE__)
7
- Treetop.load File.join(dir, 'a')
8
- Treetop.load File.join(dir, 'b')
9
- Treetop.load File.join(dir, 'c')
10
- # Check that polyglot finds d.treetop and loads it:
11
- $: << dir
12
- require 'd'
13
-
14
- @c = ::Test::CParser.new
15
- @d = ::Test::DParser.new
16
- end
17
-
18
- specify "rules in C have access to rules defined in A and B" do
19
- @c.parse('abbc').should_not be_nil
20
- end
21
-
22
- specify "rules in C can override rules in A and B with super semantics" do
23
- @d.parse('superkeywordworks').should_not be_nil
24
- end
25
- end
26
-
27
- describe "composed grammar chaining with require" do
28
- before do
29
- # Load f with polyglot without using the load path:
30
- require File.dirname(__FILE__) + '/f'
31
-
32
- @f = ::Test::FParser.new
33
- end
34
-
35
- specify "rules in F have access to rule defined in E" do
36
- @f.parse('abbcef').should_not be_nil
37
- end
38
-
39
- end
40
- end
@@ -1,15 +0,0 @@
1
- require File.dirname(__FILE__) + "/../c"
2
-
3
- module Test
4
- grammar E
5
- include C
6
-
7
- rule e
8
- 'e'
9
- end
10
-
11
- rule inherit
12
- 'super'
13
- end
14
- end
15
- end
@@ -1,32 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe String do
4
- before do
5
- @string = %{
6
- 0123456789
7
- 012345
8
- 01234567
9
- 0123
10
- }.tabto(0).strip
11
- end
12
-
13
- it "can translate indices to column numbers" do
14
- @string.column_of(0).should == 1
15
- @string.column_of(5).should == 6
16
- @string.column_of(10).should == 11
17
- @string.column_of(11).should == 1
18
- @string.column_of(17).should == 7
19
- @string.column_of(18).should == 1
20
- @string.column_of(24).should == 7
21
- end
22
-
23
- it "can translate indices to line numbers" do
24
- @string.line_of(0).should == 1
25
- @string.line_of(5).should == 1
26
- @string.line_of(10).should == 1
27
- @string.line_of(11).should == 2
28
- @string.line_of(17).should == 2
29
- @string.line_of(18).should == 3
30
- @string.line_of(24).should == 3
31
- end
32
- end
@@ -1,153 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module CompiledParserSpec
4
- describe Runtime::CompiledParser, "for a grammar with two rules" do
5
- attr_reader :parser
6
-
7
- testing_grammar %{
8
- grammar TwoRules
9
- rule a
10
- 'a'
11
- end
12
-
13
- rule b
14
- 'bb'
15
- end
16
- end
17
- }
18
-
19
- before do
20
- @parser = parser_class_under_test.new
21
- end
22
-
23
- it "allows its root to be specified" do
24
- parser.parse('a').should_not be_nil
25
- parser.parse('b').should be_nil
26
-
27
- # Check that the temporary-override works:
28
- parser.parse('bb', :root => :b).should_not be_nil
29
- parser.parse('a', :root => :b).should be_nil
30
-
31
- # Check that the temporary-override isn't sticky:
32
- parser.parse('a').should_not be_nil
33
-
34
- # Try a permanent override:
35
- parser.root = :b
36
- parser.parse('bb').should_not be_nil
37
- parser.parse('a').should be_nil
38
- end
39
-
40
- it "allows the requirement that all input be consumed to be disabled" do
41
- parser.parse('ab').should be_nil
42
-
43
- # Try a temporary override, and check it's not sticky:
44
- result = parser.parse('ab', :consume_all_input => false)
45
- result.should_not be_nil
46
- result.interval.should == (0...1)
47
- parser.parse('ab').should be_nil
48
-
49
- # Now a permanent override:
50
- parser.consume_all_input = false
51
- result = parser.parse('ab')
52
- result.should_not be_nil
53
- result.interval.should == (0...1)
54
- end
55
-
56
- it "allows input to be parsed at a given index" do
57
- parser.parse('ba').should be_nil
58
- parser.parse('ba', :index => 1).should_not be_nil
59
- # Check that the index defaults again to zero:
60
- parser.parse('a').should_not be_nil
61
-
62
- result = parser.parse('ba', :consume_all_input => false, :index => 1)
63
- result.should_not be_nil
64
- result.interval.should == (1...2)
65
- end
66
-
67
- end
68
-
69
- describe Runtime::CompiledParser, "for a grammar with a choice between terminals" do
70
- attr_reader :parser
71
-
72
- testing_grammar %{
73
- grammar Choice
74
- rule choice
75
- 'a' / 'b' / 'c'
76
- end
77
- end
78
- }
79
-
80
- before do
81
- @parser = parser_class_under_test.new
82
- end
83
-
84
- it "provides #failure_reason, #failure_column, and #failure_line when there is a parse failure" do
85
- parser.parse('z').should be_nil
86
- parser.failure_reason.should == "Expected one of 'a', 'b', 'c' at line 1, column 1 (byte 1)"
87
- parser.failure_line.should == 1
88
- parser.failure_column.should == 1
89
- end
90
- end
91
-
92
- describe Runtime::CompiledParser, "#terminal_failures" do
93
- attr_reader:parser
94
-
95
- testing_grammar %{
96
- grammar SequenceOfTerminals
97
- rule foo
98
- 'a' 'b' 'c'
99
- end
100
- end
101
- }
102
-
103
- before do
104
- @parser = parser_class_under_test.new
105
- end
106
-
107
- it "is reset between parses" do
108
- parser.parse('ac')
109
- terminal_failures = parser.terminal_failures
110
- terminal_failures.size.should == 1
111
- failure = terminal_failures.first
112
- failure.index.should == 1
113
- failure.expected_string.should == "'b'"
114
-
115
- parser.parse('b')
116
- terminal_failures = parser.terminal_failures
117
- terminal_failures.size.should == 1
118
- failure = terminal_failures.first
119
- failure.index.should == 0
120
- failure.expected_string.should == "'a'"
121
- end
122
- end
123
-
124
- describe "a SyntaxNode" do
125
- attr_reader :parser
126
-
127
- testing_grammar %{
128
- grammar Alternates
129
- rule main
130
- aa &{|s| s[0].elements[0].parent.should == s[0] }
131
- / ab &{|s| s[0].elements[0].parent.should == s[0] }
132
- end
133
-
134
- rule aa
135
- 'a' 'a'
136
- end
137
-
138
- rule ab
139
- 'a' 'b'
140
- end
141
- end
142
- }
143
-
144
- before do
145
- @parser = parser_class_under_test.new
146
- end
147
-
148
- it "should have its parent set and reset" do
149
- parser.parse('ab')
150
- end
151
- end
152
-
153
- end
@@ -1,77 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module SyntaxNodeSpec
4
- describe "A new terminal syntax node" do
5
- attr_reader :node
6
-
7
- before do
8
- @node = Runtime::SyntaxNode.new("input", 0...3)
9
- end
10
-
11
- it "reports itself as terminal" do
12
- node.should be_terminal
13
- node.should_not be_nonterminal
14
- end
15
-
16
- it "has a text value based on the input and the interval" do
17
- node.text_value.should == "inp"
18
- end
19
-
20
- it "has itself as its only element" do
21
- node.elements.should be_nil
22
- end
23
- end
24
-
25
- describe "A new nonterminal syntax node" do
26
- attr_reader :node
27
-
28
- before do
29
- @elements = [Runtime::SyntaxNode.new('input', 0...3)]
30
- @node = Runtime::SyntaxNode.new('input', 0...3, @elements)
31
- end
32
-
33
- it "reports itself as nonterminal" do
34
- node.should be_nonterminal
35
- node.should_not be_terminal
36
- end
37
-
38
- it "has a text value based on the input and the interval" do
39
- node.text_value.should == "inp"
40
- end
41
-
42
- it "has the elements with which it was instantiated" do
43
- node.elements.should == @elements
44
- end
45
-
46
- it "sets itself as the parent of its elements" do
47
- node.elements.each do |element|
48
- element.parent.should == node
49
- end
50
- end
51
- end
52
-
53
- describe "A new nonterminal syntax node with all children lazily instantiated" do
54
- attr_reader :node
55
-
56
- it "should lazily instantiate its child nodes" do
57
- @node = Runtime::SyntaxNode.new('input', 0...3, [true, true, true])
58
- node.elements.size.should == 3
59
- node.elements.first.interval.should == (0...1)
60
- node.elements.first.parent.should == node
61
- end
62
-
63
- it "should lazily replace stand-in child nodes around real ones" do
64
- @input = "input"
65
- child1 = Runtime::SyntaxNode.new(@input, 1...2)
66
- child2 = Runtime::SyntaxNode.new(@input, 3...4)
67
- @node = Runtime::SyntaxNode.new(@input, 0...5, [true, child1, true, child2, true])
68
- node.elements.size.should == 5
69
-
70
- node.elements[0].interval.should == (0...1)
71
- node.elements[0].parent.should == node
72
- 0.upto(4) do |index|
73
- node.elements[index].text_value.should == @input[index, 1]
74
- end
75
- end
76
- end
77
- end