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.
- checksums.yaml +5 -5
- data/Gemfile +18 -0
- data/History.txt +18 -0
- data/README.md +2 -0
- data/Rakefile +10 -43
- data/Treetop.tmbundle/Preferences/Comments.tmPreferences +28 -0
- data/Treetop.tmbundle/Snippets/grammar ___ end.tmSnippet +20 -0
- data/Treetop.tmbundle/Snippets/rule ___ end.tmSnippet +18 -0
- data/Treetop.tmbundle/Support/nibs/SyntaxTreeViewer.nib/designable.nib +1524 -0
- data/Treetop.tmbundle/Support/nibs/SyntaxTreeViewer.nib/keyedobjects.nib +0 -0
- data/Treetop.tmbundle/Support/syntax_tree_viewer.rb +117 -0
- data/Treetop.tmbundle/Syntaxes/Treetop Grammar.tmLanguage +358 -0
- data/Treetop.tmbundle/info.plist +10 -0
- data/doc/pitfalls_and_advanced_techniques.markdown +6 -0
- data/doc/syntactic_recognition.markdown +2 -2
- data/lib/treetop/compiler/grammar_compiler.rb +6 -3
- data/lib/treetop/compiler/metagrammar.rb +97 -77
- data/lib/treetop/compiler/metagrammar.treetop +1 -1
- data/lib/treetop/compiler/ruby_builder.rb +2 -2
- data/lib/treetop/ruby_extensions/string.rb +0 -6
- data/lib/treetop/runtime/compiled_parser.rb +15 -2
- data/lib/treetop/version.rb +1 -1
- data/treetop.gemspec +25 -157
- metadata +15 -61
- data/doc/site.rb +0 -112
- data/doc/sitegen.rb +0 -65
- data/spec/compiler/and_predicate_spec.rb +0 -36
- data/spec/compiler/anything_symbol_spec.rb +0 -47
- data/spec/compiler/character_class_spec.rb +0 -304
- data/spec/compiler/choice_spec.rb +0 -89
- data/spec/compiler/circular_compilation_spec.rb +0 -30
- data/spec/compiler/failure_propagation_functional_spec.rb +0 -21
- data/spec/compiler/grammar_compiler_spec.rb +0 -113
- data/spec/compiler/grammar_spec.rb +0 -44
- data/spec/compiler/multibyte_chars_spec.rb +0 -38
- data/spec/compiler/namespace_spec.rb +0 -42
- data/spec/compiler/nonterminal_symbol_spec.rb +0 -40
- data/spec/compiler/not_predicate_spec.rb +0 -52
- data/spec/compiler/occurrence_range_spec.rb +0 -186
- data/spec/compiler/one_or_more_spec.rb +0 -35
- data/spec/compiler/optional_spec.rb +0 -37
- data/spec/compiler/parenthesized_expression_spec.rb +0 -34
- data/spec/compiler/parsing_rule_spec.rb +0 -61
- data/spec/compiler/repeated_subrule_spec.rb +0 -29
- data/spec/compiler/semantic_predicate_spec.rb +0 -176
- data/spec/compiler/sequence_spec.rb +0 -129
- data/spec/compiler/terminal_spec.rb +0 -177
- data/spec/compiler/terminal_symbol_spec.rb +0 -40
- data/spec/compiler/test_grammar.treetop +0 -7
- data/spec/compiler/test_grammar.tt +0 -7
- data/spec/compiler/test_grammar_do.treetop +0 -7
- data/spec/compiler/test_grammar_magic_coding.treetop +0 -8
- data/spec/compiler/test_grammar_magic_encoding.treetop +0 -8
- data/spec/compiler/tt_compiler_spec.rb +0 -224
- data/spec/compiler/zero_or_more_spec.rb +0 -58
- data/spec/composition/a.treetop +0 -11
- data/spec/composition/b.treetop +0 -11
- data/spec/composition/c.treetop +0 -10
- data/spec/composition/d.treetop +0 -10
- data/spec/composition/f.treetop +0 -17
- data/spec/composition/grammar_composition_spec.rb +0 -40
- data/spec/composition/subfolder/e_includes_c.treetop +0 -15
- data/spec/ruby_extensions/string_spec.rb +0 -32
- data/spec/runtime/compiled_parser_spec.rb +0 -153
- data/spec/runtime/syntax_node_spec.rb +0 -77
- 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
|
data/spec/composition/a.treetop
DELETED
data/spec/composition/b.treetop
DELETED
data/spec/composition/c.treetop
DELETED
data/spec/composition/d.treetop
DELETED
data/spec/composition/f.treetop
DELETED
@@ -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,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
|