nirvdrum-less 1.1.4
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.
- data/.gitignore +4 -0
- data/LICENSE +179 -0
- data/README.md +39 -0
- data/Rakefile +90 -0
- data/VERSION +1 -0
- data/bin/lessc +86 -0
- data/less.gemspec +205 -0
- data/lib/ext.rb +62 -0
- data/lib/less.rb +33 -0
- data/lib/less/command.rb +106 -0
- data/lib/less/engine.rb +54 -0
- data/lib/less/engine/builder.rb +8 -0
- data/lib/less/engine/grammar/common.tt +29 -0
- data/lib/less/engine/grammar/entity.tt +139 -0
- data/lib/less/engine/grammar/less.tt +271 -0
- data/lib/less/engine/nodes.rb +9 -0
- data/lib/less/engine/nodes/element.rb +186 -0
- data/lib/less/engine/nodes/entity.rb +79 -0
- data/lib/less/engine/nodes/function.rb +79 -0
- data/lib/less/engine/nodes/literal.rb +167 -0
- data/lib/less/engine/nodes/property.rb +156 -0
- data/lib/less/engine/nodes/ruleset.rb +12 -0
- data/lib/less/engine/nodes/selector.rb +39 -0
- data/lib/vendor/treetop/.gitignore +7 -0
- data/lib/vendor/treetop/LICENSE +19 -0
- data/lib/vendor/treetop/README +164 -0
- data/lib/vendor/treetop/Rakefile +19 -0
- data/lib/vendor/treetop/benchmark/seqpar.gnuplot +15 -0
- data/lib/vendor/treetop/benchmark/seqpar.treetop +16 -0
- data/lib/vendor/treetop/benchmark/seqpar_benchmark.rb +107 -0
- data/lib/vendor/treetop/bin/tt +28 -0
- data/lib/vendor/treetop/lib/treetop.rb +8 -0
- data/lib/vendor/treetop/lib/treetop/bootstrap_gen_1_metagrammar.rb +45 -0
- data/lib/vendor/treetop/lib/treetop/compiler.rb +6 -0
- data/lib/vendor/treetop/lib/treetop/compiler/grammar_compiler.rb +42 -0
- data/lib/vendor/treetop/lib/treetop/compiler/lexical_address_space.rb +17 -0
- data/lib/vendor/treetop/lib/treetop/compiler/metagrammar.rb +3097 -0
- data/lib/vendor/treetop/lib/treetop/compiler/metagrammar.treetop +408 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes.rb +19 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/anything_symbol.rb +18 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/atomic_expression.rb +14 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/character_class.rb +24 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/choice.rb +31 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/declaration_sequence.rb +24 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/grammar.rb +28 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/inline_module.rb +27 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/nonterminal.rb +13 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/optional.rb +19 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/parenthesized_expression.rb +9 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/parsing_expression.rb +138 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/parsing_rule.rb +55 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/predicate.rb +45 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/repetition.rb +55 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/sequence.rb +68 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/terminal.rb +20 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/transient_prefix.rb +9 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/treetop_file.rb +9 -0
- data/lib/vendor/treetop/lib/treetop/compiler/ruby_builder.rb +113 -0
- data/lib/vendor/treetop/lib/treetop/ruby_extensions.rb +2 -0
- data/lib/vendor/treetop/lib/treetop/ruby_extensions/string.rb +42 -0
- data/lib/vendor/treetop/lib/treetop/runtime.rb +5 -0
- data/lib/vendor/treetop/lib/treetop/runtime/compiled_parser.rb +105 -0
- data/lib/vendor/treetop/lib/treetop/runtime/interval_skip_list.rb +4 -0
- data/lib/vendor/treetop/lib/treetop/runtime/interval_skip_list/head_node.rb +15 -0
- data/lib/vendor/treetop/lib/treetop/runtime/interval_skip_list/interval_skip_list.rb +200 -0
- data/lib/vendor/treetop/lib/treetop/runtime/interval_skip_list/node.rb +164 -0
- data/lib/vendor/treetop/lib/treetop/runtime/syntax_node.rb +72 -0
- data/lib/vendor/treetop/lib/treetop/runtime/terminal_parse_failure.rb +16 -0
- data/lib/vendor/treetop/lib/treetop/runtime/terminal_syntax_node.rb +17 -0
- data/lib/vendor/treetop/lib/treetop/version.rb +9 -0
- data/lib/vendor/treetop/spec/compiler/and_predicate_spec.rb +36 -0
- data/lib/vendor/treetop/spec/compiler/anything_symbol_spec.rb +44 -0
- data/lib/vendor/treetop/spec/compiler/character_class_spec.rb +182 -0
- data/lib/vendor/treetop/spec/compiler/choice_spec.rb +80 -0
- data/lib/vendor/treetop/spec/compiler/circular_compilation_spec.rb +28 -0
- data/lib/vendor/treetop/spec/compiler/failure_propagation_functional_spec.rb +21 -0
- data/lib/vendor/treetop/spec/compiler/grammar_compiler_spec.rb +84 -0
- data/lib/vendor/treetop/spec/compiler/grammar_spec.rb +41 -0
- data/lib/vendor/treetop/spec/compiler/nonterminal_symbol_spec.rb +40 -0
- data/lib/vendor/treetop/spec/compiler/not_predicate_spec.rb +38 -0
- data/lib/vendor/treetop/spec/compiler/one_or_more_spec.rb +35 -0
- data/lib/vendor/treetop/spec/compiler/optional_spec.rb +37 -0
- data/lib/vendor/treetop/spec/compiler/parenthesized_expression_spec.rb +19 -0
- data/lib/vendor/treetop/spec/compiler/parsing_rule_spec.rb +32 -0
- data/lib/vendor/treetop/spec/compiler/sequence_spec.rb +115 -0
- data/lib/vendor/treetop/spec/compiler/terminal_spec.rb +81 -0
- data/lib/vendor/treetop/spec/compiler/terminal_symbol_spec.rb +37 -0
- data/lib/vendor/treetop/spec/compiler/test_grammar.treetop +7 -0
- data/lib/vendor/treetop/spec/compiler/test_grammar.tt +7 -0
- data/lib/vendor/treetop/spec/compiler/test_grammar_do.treetop +7 -0
- data/lib/vendor/treetop/spec/compiler/zero_or_more_spec.rb +56 -0
- data/lib/vendor/treetop/spec/composition/a.treetop +11 -0
- data/lib/vendor/treetop/spec/composition/b.treetop +11 -0
- data/lib/vendor/treetop/spec/composition/c.treetop +10 -0
- data/lib/vendor/treetop/spec/composition/d.treetop +10 -0
- data/lib/vendor/treetop/spec/composition/f.treetop +17 -0
- data/lib/vendor/treetop/spec/composition/grammar_composition_spec.rb +40 -0
- data/lib/vendor/treetop/spec/composition/subfolder/e_includes_c.treetop +15 -0
- data/lib/vendor/treetop/spec/ruby_extensions/string_spec.rb +32 -0
- data/lib/vendor/treetop/spec/runtime/compiled_parser_spec.rb +101 -0
- data/lib/vendor/treetop/spec/runtime/interval_skip_list/delete_spec.rb +147 -0
- data/lib/vendor/treetop/spec/runtime/interval_skip_list/expire_range_spec.rb +349 -0
- data/lib/vendor/treetop/spec/runtime/interval_skip_list/insert_and_delete_node.rb +385 -0
- data/lib/vendor/treetop/spec/runtime/interval_skip_list/insert_spec.rb +660 -0
- data/lib/vendor/treetop/spec/runtime/interval_skip_list/interval_skip_list_spec.graffle +6175 -0
- data/lib/vendor/treetop/spec/runtime/interval_skip_list/interval_skip_list_spec.rb +58 -0
- data/lib/vendor/treetop/spec/runtime/interval_skip_list/palindromic_fixture.rb +23 -0
- data/lib/vendor/treetop/spec/runtime/interval_skip_list/palindromic_fixture_spec.rb +164 -0
- data/lib/vendor/treetop/spec/runtime/interval_skip_list/spec_helper.rb +84 -0
- data/lib/vendor/treetop/spec/runtime/syntax_node_spec.rb +53 -0
- data/lib/vendor/treetop/spec/spec_helper.rb +106 -0
- data/lib/vendor/treetop/spec/spec_suite.rb +4 -0
- data/lib/vendor/treetop/treetop.gemspec +17 -0
- data/spec/command_spec.rb +102 -0
- data/spec/css/accessors.css +18 -0
- data/spec/css/big.css +3768 -0
- data/spec/css/colors.css +11 -0
- data/spec/css/comments.css +9 -0
- data/spec/css/css-3.css +2 -0
- data/spec/css/css.css +45 -0
- data/spec/css/functions.css +6 -0
- data/spec/css/import.css +12 -0
- data/spec/css/lazy-eval.css +1 -0
- data/spec/css/mixins-args.css +0 -0
- data/spec/css/mixins.css +28 -0
- data/spec/css/operations.css +28 -0
- data/spec/css/parens.css +16 -0
- data/spec/css/rulesets.css +17 -0
- data/spec/css/scope.css +11 -0
- data/spec/css/selectors.css +8 -0
- data/spec/css/strings.css +12 -0
- data/spec/css/variables.css +6 -0
- data/spec/css/whitespace.css +11 -0
- data/spec/engine_spec.rb +111 -0
- data/spec/less/accessors.less +20 -0
- data/spec/less/big.less +4810 -0
- data/spec/less/colors.less +34 -0
- data/spec/less/comments.less +46 -0
- data/spec/less/css-3.less +11 -0
- data/spec/less/css.less +98 -0
- data/spec/less/exceptions/mixed-units-error.less +3 -0
- data/spec/less/exceptions/name-error-1.0.less +3 -0
- data/spec/less/exceptions/syntax-error-1.0.less +3 -0
- data/spec/less/functions.less +6 -0
- data/spec/less/import.less +7 -0
- data/spec/less/import/import-test-a.less +2 -0
- data/spec/less/import/import-test-b.less +8 -0
- data/spec/less/import/import-test-c.less +6 -0
- data/spec/less/import/import-test-d.css +1 -0
- data/spec/less/lazy-eval.less +6 -0
- data/spec/less/mixins-args.less +0 -0
- data/spec/less/mixins.less +43 -0
- data/spec/less/operations.less +39 -0
- data/spec/less/parens.less +21 -0
- data/spec/less/rulesets.less +30 -0
- data/spec/less/scope.less +32 -0
- data/spec/less/selectors.less +15 -0
- data/spec/less/strings.less +14 -0
- data/spec/less/variables.less +18 -0
- data/spec/less/whitespace.less +30 -0
- data/spec/spec.css +82 -0
- data/spec/spec.less +148 -0
- data/spec/spec_helper.rb +8 -0
- metadata +219 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
class IntervalSkipList
|
|
2
|
+
class Node < HeadNode
|
|
3
|
+
attr_accessor :key
|
|
4
|
+
attr_reader :markers, :endpoint_of
|
|
5
|
+
|
|
6
|
+
def initialize(key, height, path)
|
|
7
|
+
super(height)
|
|
8
|
+
@key = key
|
|
9
|
+
@markers = []
|
|
10
|
+
@endpoint_of = []
|
|
11
|
+
update_forward_pointers(path)
|
|
12
|
+
promote_markers(path)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def all_forward_markers
|
|
16
|
+
markers.flatten
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def delete(path)
|
|
20
|
+
0.upto(top_level) do |i|
|
|
21
|
+
path[i].forward[i] = forward[i]
|
|
22
|
+
end
|
|
23
|
+
demote_markers(path)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def propagate_length_change(length_change)
|
|
27
|
+
cur_node = self
|
|
28
|
+
while cur_node do
|
|
29
|
+
cur_node.key += length_change
|
|
30
|
+
cur_node = cur_node.forward[0]
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
protected
|
|
35
|
+
|
|
36
|
+
def update_forward_pointers(path)
|
|
37
|
+
0.upto(top_level) do |i|
|
|
38
|
+
forward[i] = path[i].forward[i]
|
|
39
|
+
path[i].forward[i] = self
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def promote_markers(path)
|
|
44
|
+
promoted = []
|
|
45
|
+
new_promoted = []
|
|
46
|
+
0.upto(top_level) do |i|
|
|
47
|
+
incoming_markers = path[i].forward_markers[i]
|
|
48
|
+
markers.concat(incoming_markers)
|
|
49
|
+
|
|
50
|
+
incoming_markers.each do |marker|
|
|
51
|
+
if can_be_promoted_higher?(marker, i)
|
|
52
|
+
new_promoted.push(marker)
|
|
53
|
+
forward[i].delete_marker_from_path(marker, i, forward[i+1])
|
|
54
|
+
else
|
|
55
|
+
forward_markers[i].push(marker)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
promoted.each do |marker|
|
|
60
|
+
if can_be_promoted_higher?(marker, i)
|
|
61
|
+
new_promoted.push(marker)
|
|
62
|
+
forward[i].delete_marker_from_path(marker, i, forward[i+1])
|
|
63
|
+
else
|
|
64
|
+
forward_markers[i].push(marker)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
promoted = new_promoted
|
|
69
|
+
new_promoted = []
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def can_be_promoted_higher?(marker, level)
|
|
75
|
+
level < top_level && forward[level + 1] && forward[level + 1].markers.include?(marker)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def delete_marker_from_path(marker, level, terminus)
|
|
79
|
+
cur_node = self
|
|
80
|
+
until cur_node == terminus
|
|
81
|
+
cur_node.forward_markers[level].delete(marker)
|
|
82
|
+
cur_node.markers.delete(marker)
|
|
83
|
+
cur_node = cur_node.forward[level]
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def demote_markers(path)
|
|
88
|
+
demote_inbound_markers(path)
|
|
89
|
+
demote_outbound_markers(path)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def demote_inbound_markers(path)
|
|
93
|
+
demoted = []
|
|
94
|
+
new_demoted = []
|
|
95
|
+
|
|
96
|
+
top_level.downto(0) do |i|
|
|
97
|
+
incoming_markers = path[i].forward_markers[i].dup
|
|
98
|
+
incoming_markers.each do |marker|
|
|
99
|
+
unless forward_node_with_marker_at_or_above_level?(marker, i)
|
|
100
|
+
path[i].forward_markers[i].delete(marker)
|
|
101
|
+
new_demoted.push(marker)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
demoted.each do |marker|
|
|
106
|
+
path[i + 1].place_marker_on_inbound_path(marker, i, path[i])
|
|
107
|
+
|
|
108
|
+
if forward[i].markers.include?(marker)
|
|
109
|
+
path[i].forward_markers[i].push(marker)
|
|
110
|
+
else
|
|
111
|
+
new_demoted.push(marker)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
demoted = new_demoted
|
|
116
|
+
new_demoted = []
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def demote_outbound_markers(path)
|
|
121
|
+
demoted = []
|
|
122
|
+
new_demoted = []
|
|
123
|
+
|
|
124
|
+
top_level.downto(0) do |i|
|
|
125
|
+
forward_markers[i].each do |marker|
|
|
126
|
+
new_demoted.push(marker) unless path[i].forward_markers[i].include?(marker)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
demoted.each do |marker|
|
|
130
|
+
forward[i].place_marker_on_outbound_path(marker, i, forward[i + 1])
|
|
131
|
+
new_demoted.push(marker) unless path[i].forward_markers[i].include?(marker)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
demoted = new_demoted
|
|
135
|
+
new_demoted = []
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def forward_node_with_marker_at_or_above_level?(marker, level)
|
|
140
|
+
level.upto(top_level) do |i|
|
|
141
|
+
return true if forward[i].markers.include?(marker)
|
|
142
|
+
end
|
|
143
|
+
false
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def place_marker_on_outbound_path(marker, level, terminus)
|
|
147
|
+
cur_node = self
|
|
148
|
+
until cur_node == terminus
|
|
149
|
+
cur_node.forward_markers[level].push(marker)
|
|
150
|
+
cur_node.markers.push(marker)
|
|
151
|
+
cur_node = cur_node.forward[level]
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def place_marker_on_inbound_path(marker, level, terminus)
|
|
156
|
+
cur_node = self
|
|
157
|
+
until cur_node == terminus
|
|
158
|
+
cur_node.forward_markers[level].push(marker)
|
|
159
|
+
cur_node = cur_node.forward[level]
|
|
160
|
+
cur_node.markers.push(marker)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
module Treetop
|
|
2
|
+
module Runtime
|
|
3
|
+
class SyntaxNode
|
|
4
|
+
attr_reader :input, :interval, :elements
|
|
5
|
+
attr_accessor :parent
|
|
6
|
+
|
|
7
|
+
def initialize(input, interval, elements = nil)
|
|
8
|
+
@input = input
|
|
9
|
+
@interval = interval
|
|
10
|
+
if @elements = elements
|
|
11
|
+
elements.each do |element|
|
|
12
|
+
element.parent = self
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def terminal?
|
|
18
|
+
@elements.nil?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def nonterminal?
|
|
22
|
+
!terminal?
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def text_value
|
|
26
|
+
input[interval]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def empty?
|
|
30
|
+
interval.first == interval.last && interval.exclude_end?
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def extension_modules
|
|
34
|
+
local_extensions =
|
|
35
|
+
class <<self
|
|
36
|
+
included_modules-Object.included_modules
|
|
37
|
+
end
|
|
38
|
+
if local_extensions.size > 0
|
|
39
|
+
local_extensions
|
|
40
|
+
else
|
|
41
|
+
[] # There weren't any; must be a literal node
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def inspect(indent="")
|
|
46
|
+
em = extension_modules
|
|
47
|
+
interesting_methods = methods-[em.last ? em.last.methods : nil]-self.class.instance_methods
|
|
48
|
+
im = interesting_methods.size > 0 ? " (#{interesting_methods.join(",")})" : ""
|
|
49
|
+
tv = text_value
|
|
50
|
+
tv = "...#{tv[-20..-1]}" if tv.size > 20
|
|
51
|
+
|
|
52
|
+
indent +
|
|
53
|
+
self.class.to_s.sub(/.*:/,'') +
|
|
54
|
+
em.map{|m| "+"+m.to_s.sub(/.*:/,'')}*"" +
|
|
55
|
+
" offset=#{interval.first}" +
|
|
56
|
+
", #{tv.inspect}" +
|
|
57
|
+
im +
|
|
58
|
+
(elements && elements.size > 0 ?
|
|
59
|
+
":" +
|
|
60
|
+
(@elements||[]).map{|e|
|
|
61
|
+
begin
|
|
62
|
+
"\n"+e.inspect(indent+" ")
|
|
63
|
+
rescue # Defend against inspect not taking a parameter
|
|
64
|
+
"\n"+indent+" "+e.inspect
|
|
65
|
+
end
|
|
66
|
+
}.join("") :
|
|
67
|
+
""
|
|
68
|
+
)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Treetop
|
|
2
|
+
module Runtime
|
|
3
|
+
class TerminalParseFailure
|
|
4
|
+
attr_reader :index, :expected_string
|
|
5
|
+
|
|
6
|
+
def initialize(index, expected_string)
|
|
7
|
+
@index = index
|
|
8
|
+
@expected_string = expected_string
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def to_s
|
|
12
|
+
"String matching #{expected_string} expected."
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Treetop
|
|
2
|
+
module Runtime
|
|
3
|
+
class TerminalSyntaxNode < SyntaxNode
|
|
4
|
+
|
|
5
|
+
def initialize(input, interval)
|
|
6
|
+
super(input, interval, [])
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def inspect(indent="")
|
|
10
|
+
indent+
|
|
11
|
+
self.class.to_s.sub(/.*:/,'') +
|
|
12
|
+
" offset=#{interval.first}" +
|
|
13
|
+
" #{text_value.inspect}"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
|
|
2
|
+
|
|
3
|
+
module AndPredicateSpec
|
|
4
|
+
describe "An &-predicated terminal symbol" do
|
|
5
|
+
testing_expression '&"foo"'
|
|
6
|
+
|
|
7
|
+
it "successfully parses input matching the terminal symbol, returning an epsilon syntax node" do
|
|
8
|
+
parse('foo', :consume_all_input => false) do |result|
|
|
9
|
+
result.should_not be_nil
|
|
10
|
+
result.interval.should == (0...0)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe "A sequence of a terminal and an and another &-predicated terminal" do
|
|
16
|
+
testing_expression '"foo" &"bar"'
|
|
17
|
+
|
|
18
|
+
it "matches input matching both terminals, but only consumes the first" do
|
|
19
|
+
parse('foobar', :consume_all_input => false) do |result|
|
|
20
|
+
result.should_not be_nil
|
|
21
|
+
result.text_value.should == 'foo'
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "fails to parse input matching only the first terminal, with a terminal failure recorded at index 3" do
|
|
26
|
+
parse('foo') do |result|
|
|
27
|
+
result.should be_nil
|
|
28
|
+
terminal_failures = parser.terminal_failures
|
|
29
|
+
terminal_failures.size.should == 1
|
|
30
|
+
failure = terminal_failures[0]
|
|
31
|
+
failure.index.should == 3
|
|
32
|
+
failure.expected_string.should == 'bar'
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
|
|
2
|
+
|
|
3
|
+
module AnythingSymbolSpec
|
|
4
|
+
class Foo < Treetop::Runtime::SyntaxNode
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
describe "an anything symbol followed by a node class declaration and a block" do
|
|
8
|
+
testing_expression '. <AnythingSymbolSpec::Foo> { def a_method; end }'
|
|
9
|
+
|
|
10
|
+
it "matches any single character in a big range, returning an instance of the declared node class that responds to methods defined in the inline module" do
|
|
11
|
+
(33..127).each do |digit|
|
|
12
|
+
parse(digit.chr) do |result|
|
|
13
|
+
result.should_not be_nil
|
|
14
|
+
result.should be_an_instance_of(Foo)
|
|
15
|
+
result.should respond_to(:a_method)
|
|
16
|
+
result.interval.should == (0...1)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "fails to parse epsilon" do
|
|
22
|
+
parse('').should be_nil
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
module ModFoo
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe "an anything symbol followed by a module declaration and a block" do
|
|
30
|
+
testing_expression '. <AnythingSymbolSpec::ModFoo> { def a_method; end }'
|
|
31
|
+
|
|
32
|
+
it "matches any single character in a big range, returning an instance of SyntaxNode extended by the declared module that responds to methods defined in the inline module" do
|
|
33
|
+
(33..127).each do |digit|
|
|
34
|
+
parse(digit.chr) do |result|
|
|
35
|
+
result.should_not be_nil
|
|
36
|
+
result.should be_an_instance_of(Treetop::Runtime::SyntaxNode)
|
|
37
|
+
result.should be_a_kind_of(ModFoo)
|
|
38
|
+
result.should respond_to(:a_method)
|
|
39
|
+
result.interval.should == (0...1)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
|
2
|
+
|
|
3
|
+
module CharacterClassSpec
|
|
4
|
+
class Foo < Treetop::Runtime::SyntaxNode
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
describe "a character class followed by a node class declaration and a block" do
|
|
8
|
+
|
|
9
|
+
testing_expression "[A-Z] <CharacterClassSpec::Foo> { def a_method; end }"
|
|
10
|
+
|
|
11
|
+
it "matches single characters within that range, returning instances of the declared node class that respond to the method defined in the inline module" do
|
|
12
|
+
result = parse('A')
|
|
13
|
+
result.should be_an_instance_of(Foo)
|
|
14
|
+
result.should respond_to(:a_method)
|
|
15
|
+
result = parse('N')
|
|
16
|
+
result.should be_an_instance_of(Foo)
|
|
17
|
+
result.should respond_to(:a_method)
|
|
18
|
+
result = parse('Z')
|
|
19
|
+
result.should be_an_instance_of(Foo)
|
|
20
|
+
result.should respond_to(:a_method)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "does not match single characters outside of that range" do
|
|
24
|
+
parse('8').should be_nil
|
|
25
|
+
parse('a').should be_nil
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "matches a single character within that range at index 1" do
|
|
29
|
+
parse(' A', :index => 1).should_not be_nil
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "fails to match a single character out of that range at index 1" do
|
|
33
|
+
parse(' 1', :index => 1).should be_nil
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
module ModFoo
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
describe "a character class followed by a node module declaration and a block" do
|
|
41
|
+
|
|
42
|
+
testing_expression "[A-Z] <CharacterClassSpec::ModFoo> { def a_method; end }"
|
|
43
|
+
|
|
44
|
+
it "matches single characters within that range, returning instances of SyntaxNode extended by the specified module" do
|
|
45
|
+
result = parse('A')
|
|
46
|
+
result.should be_an_instance_of(Treetop::Runtime::SyntaxNode)
|
|
47
|
+
result.should be_a_kind_of(ModFoo)
|
|
48
|
+
result.should respond_to(:a_method)
|
|
49
|
+
result = parse('N')
|
|
50
|
+
result.should be_an_instance_of(Treetop::Runtime::SyntaxNode)
|
|
51
|
+
result.should be_a_kind_of(ModFoo)
|
|
52
|
+
result.should respond_to(:a_method)
|
|
53
|
+
result = parse('Z')
|
|
54
|
+
result.should be_an_instance_of(Treetop::Runtime::SyntaxNode)
|
|
55
|
+
result.should be_a_kind_of(ModFoo)
|
|
56
|
+
result.should respond_to(:a_method)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "does not match single characters outside of that range" do
|
|
60
|
+
parse('8').should be_nil
|
|
61
|
+
parse('a').should be_nil
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "matches a single character within that range at index 1" do
|
|
65
|
+
parse(' A', :index => 1).should_not be_nil
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "fails to match a single character out of that range at index 1" do
|
|
69
|
+
parse(' 1', :index => 1).should be_nil
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
describe "A character class containing quotes" do
|
|
74
|
+
testing_expression "[\"']"
|
|
75
|
+
|
|
76
|
+
it "matches a quote" do
|
|
77
|
+
parse("'").should_not be_nil
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "matches a double-quote" do
|
|
81
|
+
parse('"').should_not be_nil
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
describe "A character class containing a special character" do
|
|
86
|
+
testing_expression "[\t]"
|
|
87
|
+
it "matches that character only" do
|
|
88
|
+
parse("\t").should_not be_nil
|
|
89
|
+
parse('t').should be_nil
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
describe "A character class containing an escaped backslash" do
|
|
94
|
+
slash = "\\" # Make it explicit that there are *two* backslashes here
|
|
95
|
+
testing_expression "[#{slash}#{slash}]"
|
|
96
|
+
it "matches a backslash only" do
|
|
97
|
+
parse("\\").should_not be_nil
|
|
98
|
+
parse('t').should be_nil
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
describe "A character class containing a hex escape" do
|
|
103
|
+
slash = "\\"
|
|
104
|
+
testing_expression "[#{slash}x41]"
|
|
105
|
+
it "matches that character only" do
|
|
106
|
+
parse('A').should_not be_nil
|
|
107
|
+
parse('\\').should be_nil
|
|
108
|
+
parse('x').should be_nil
|
|
109
|
+
parse('4').should be_nil
|
|
110
|
+
parse('1').should be_nil
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
describe "A character class containing an octal escape" do
|
|
115
|
+
slash = "\\"
|
|
116
|
+
testing_expression "[#{slash}101]"
|
|
117
|
+
it "matches that character only" do
|
|
118
|
+
parse('A').should_not be_nil
|
|
119
|
+
parse('\\').should be_nil
|
|
120
|
+
parse('1').should be_nil
|
|
121
|
+
parse('0').should be_nil
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
describe "A character class containing a \\c control-char escape" do
|
|
126
|
+
slash = "\\"
|
|
127
|
+
testing_expression "[#{slash}cC]"
|
|
128
|
+
it "matches that character only" do
|
|
129
|
+
parse("\003").should_not be_nil
|
|
130
|
+
parse('\\').should be_nil
|
|
131
|
+
parse('c').should be_nil
|
|
132
|
+
parse('C').should be_nil
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
describe "A character class containing a \\C- control-char escape" do
|
|
137
|
+
slash = "\\"
|
|
138
|
+
testing_expression "[#{slash}C-C]"
|
|
139
|
+
it "matches that character only" do
|
|
140
|
+
parse("\003").should_not be_nil
|
|
141
|
+
parse('\\').should be_nil
|
|
142
|
+
parse('C').should be_nil
|
|
143
|
+
parse('-').should be_nil
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
describe "A character class containing a \\M- meta-char escape" do
|
|
148
|
+
slash = "\\"
|
|
149
|
+
testing_expression "[#{slash}M- ]"
|
|
150
|
+
it "matches that character only" do
|
|
151
|
+
parse("\240").should_not be_nil
|
|
152
|
+
parse('\\').should be_nil
|
|
153
|
+
parse('M').should be_nil
|
|
154
|
+
parse('-').should be_nil
|
|
155
|
+
parse(' ').should be_nil
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
describe "A character class containing an escaped non-special character" do
|
|
160
|
+
slash = "\\"
|
|
161
|
+
testing_expression "[#{slash}y]"
|
|
162
|
+
it "matches that character only" do
|
|
163
|
+
parse("y").should_not be_nil
|
|
164
|
+
parse('\\').should be_nil
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
describe "A character class containing an \#{...} insertion" do
|
|
169
|
+
testing_expression "[\#{raise 'error'}]"
|
|
170
|
+
it "doesn't evaluate the insertion" do
|
|
171
|
+
x = true
|
|
172
|
+
lambda{
|
|
173
|
+
x = parse("y")
|
|
174
|
+
}.should_not raise_error
|
|
175
|
+
x.should be_nil
|
|
176
|
+
parse('#').should_not be_nil
|
|
177
|
+
parse("'").should_not be_nil
|
|
178
|
+
parse("0").should be_nil
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
end
|