Spectre 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +1 -0
- data/LICENSE +23 -0
- data/README +20 -0
- data/Rakefile +112 -0
- data/lib/spectre/base.rb +44 -0
- data/lib/spectre/base/closure.rb +96 -0
- data/lib/spectre/base/directive.rb +148 -0
- data/lib/spectre/base/grammar.rb +269 -0
- data/lib/spectre/base/inputiterator.rb +276 -0
- data/lib/spectre/base/node.rb +393 -0
- data/lib/spectre/base/operators.rb +342 -0
- data/lib/spectre/base/parser.rb +110 -0
- data/lib/spectre/generic.rb +115 -0
- data/lib/spectre/generic/directives.rb +246 -0
- data/lib/spectre/generic/negations.rb +68 -0
- data/lib/spectre/generic/primitives.rb +172 -0
- data/lib/spectre/generic/semanticaction.rb +43 -0
- data/lib/spectre/string.rb +57 -0
- data/lib/spectre/string/additionals.rb +80 -0
- data/lib/spectre/string/directives.rb +51 -0
- data/lib/spectre/string/inputiterator.rb +57 -0
- data/lib/spectre/string/primitives.rb +400 -0
- data/test/base/closure_tests.rb +108 -0
- data/test/base/grammar_tests.rb +97 -0
- data/test/base/operator_tests.rb +335 -0
- data/test/base/semanticaction_tests.rb +53 -0
- data/test/generic/directive_tests.rb +224 -0
- data/test/generic/negation_tests.rb +146 -0
- data/test/generic/primitive_tests.rb +99 -0
- data/test/string/POD2Parser_tests.rb +93 -0
- data/test/string/additional_tests.rb +43 -0
- data/test/string/directive_tests.rb +32 -0
- data/test/string/primitive_tests.rb +173 -0
- data/test/tests.rb +33 -0
- data/test/tutorial/funnymath_tests.rb +57 -0
- data/test/tutorial/html_tests.rb +171 -0
- data/test/tutorial/skipping_tests.rb +60 -0
- metadata +109 -0
@@ -0,0 +1,93 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This is Spectre, a parser framework inspired by Boost.Spirit,
|
3
|
+
# which can be found at http://spirit.sourceforge.net/.
|
4
|
+
#
|
5
|
+
# If you want to find out more or need a tutorial, go to
|
6
|
+
# http://spectre.rubyforge.org/
|
7
|
+
# You'll find a nice wiki there!
|
8
|
+
#
|
9
|
+
# Author:: Fabian Streitel (karottenreibe)
|
10
|
+
# Copyright:: Copyright (c) 2009 Fabian Streitel
|
11
|
+
# License:: Boost Software License 1.0
|
12
|
+
# For further information regarding this license, you can go to
|
13
|
+
# http://www.boost.org/LICENSE_1_0.txt
|
14
|
+
# or read the file LICENSE distributed with this software.
|
15
|
+
# Homepage:: http://spectre.rubyforge.org/
|
16
|
+
# Git repo:: http://rubyforge.org/scm/?group_id=7618
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'rubygems'
|
20
|
+
require 'test/unit'
|
21
|
+
require 'spectre/string'
|
22
|
+
|
23
|
+
class POD2ParserTests < Test::Unit::TestCase
|
24
|
+
include Spectre
|
25
|
+
include Spectre::StringParsing
|
26
|
+
include Spectre::ShortcutsMixin
|
27
|
+
|
28
|
+
def testChar
|
29
|
+
p = ('a'.to_p >> 'c').+
|
30
|
+
ret = parse "acacacac", p
|
31
|
+
assert_equal 8, ret.length
|
32
|
+
assert_equal "acacacac", ret.value
|
33
|
+
|
34
|
+
ret = parse "as", p
|
35
|
+
assert_kind_of NilClass, ret
|
36
|
+
end
|
37
|
+
|
38
|
+
def testString
|
39
|
+
p = lexeme_d[('chunky' >> -( ' '.to_p >> 'bacon'.to_p ) >> -(' '.to_p) ).*]
|
40
|
+
ret = parse "chunky bacon", p
|
41
|
+
assert_equal 12, ret.length
|
42
|
+
assert_equal "chunky bacon", ret.value
|
43
|
+
|
44
|
+
ret = parse "chunky chunky chunky", p
|
45
|
+
assert_equal 20, ret.length
|
46
|
+
assert_equal "chunky chunky chunky", ret.value
|
47
|
+
|
48
|
+
ret = parse "chunky bacon chunkychunky bacon", p
|
49
|
+
assert_equal 31, ret.length
|
50
|
+
assert_equal "chunky bacon chunkychunky bacon", ret.value
|
51
|
+
|
52
|
+
ret = parse "bacon?", p
|
53
|
+
assert_equal 0, ret.length
|
54
|
+
assert_equal "", ret.value
|
55
|
+
|
56
|
+
ret = parse "", p
|
57
|
+
assert_equal 0, ret.length
|
58
|
+
assert_equal "", ret.value
|
59
|
+
end
|
60
|
+
|
61
|
+
def testRange
|
62
|
+
p = ('a'..'m').to_p % ('n'..'z')
|
63
|
+
ret = parse "axbyczmni", p
|
64
|
+
assert_equal 9, ret.length
|
65
|
+
assert_equal "axbyczmni", ret.value
|
66
|
+
|
67
|
+
ret = parse "ds", p
|
68
|
+
assert_equal 1, ret.length
|
69
|
+
assert_equal "d", ret.value
|
70
|
+
|
71
|
+
ret = parse "xs", p
|
72
|
+
assert_kind_of NilClass, ret
|
73
|
+
end
|
74
|
+
|
75
|
+
def testArray
|
76
|
+
p = ['1', '3', '5', '7', '9'].to_p.+ >> LowerParser.new.to_p.*
|
77
|
+
ret = parse "13131go!!!", p
|
78
|
+
assert_equal 7, ret.length
|
79
|
+
assert_equal "13131go", ret.value
|
80
|
+
|
81
|
+
ret = parse "gogogo!!", p
|
82
|
+
assert_kind_of NilClass, ret
|
83
|
+
|
84
|
+
ret = parse "444go!!!", p
|
85
|
+
assert_kind_of NilClass, ret
|
86
|
+
end
|
87
|
+
|
88
|
+
def testSymbol
|
89
|
+
p = :foo.to_p
|
90
|
+
assert_kind_of SymParser, p.parser
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This is Spectre, a parser framework inspired by Boost.Spirit,
|
3
|
+
# which can be found at http://spirit.sourceforge.net/.
|
4
|
+
#
|
5
|
+
# If you want to find out more or need a tutorial, go to
|
6
|
+
# http://spectre.rubyforge.org/
|
7
|
+
# You'll find a nice wiki there!
|
8
|
+
#
|
9
|
+
# Author:: Fabian Streitel (karottenreibe)
|
10
|
+
# Copyright:: Copyright (c) 2009 Fabian Streitel
|
11
|
+
# License:: Boost Software License 1.0
|
12
|
+
# For further information regarding this license, you can go to
|
13
|
+
# http://www.boost.org/LICENSE_1_0.txt
|
14
|
+
# or read the file LICENSE distributed with this software.
|
15
|
+
# Homepage:: http://spectre.rubyforge.org/
|
16
|
+
# Git repo:: http://rubyforge.org/scm/?group_id=7618
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'rubygems'
|
20
|
+
require 'test/unit'
|
21
|
+
require 'spectre/string'
|
22
|
+
|
23
|
+
class StringPrimitivesTests < Test::Unit::TestCase
|
24
|
+
include Spectre
|
25
|
+
include Spectre::StringParsing
|
26
|
+
include Spectre::ShortcutsMixin
|
27
|
+
|
28
|
+
def testRegexpParser
|
29
|
+
p = rex(/[ABCD]+z{3} [^5]*/)
|
30
|
+
ret = parse "AACBDDzzz 43", p
|
31
|
+
assert_kind_of Match, ret
|
32
|
+
assert_equal 12, ret.length
|
33
|
+
assert_equal "AACBDDzzz 43", ret.value
|
34
|
+
|
35
|
+
ret = parse "zAACBDDzzz 43", p
|
36
|
+
assert_kind_of NilClass, ret
|
37
|
+
|
38
|
+
ret = parse "AACBDDzzz 435sfasdf", p
|
39
|
+
assert_kind_of Match, ret
|
40
|
+
assert_equal 12, ret.length
|
41
|
+
assert_equal "AACBDDzzz 43", ret.value
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This is Spectre, a parser framework inspired by Boost.Spirit,
|
3
|
+
# which can be found at http://spirit.sourceforge.net/.
|
4
|
+
#
|
5
|
+
# If you want to find out more or need a tutorial, go to
|
6
|
+
# http://spectre.rubyforge.org/
|
7
|
+
# You'll find a nice wiki there!
|
8
|
+
#
|
9
|
+
# Author:: Fabian Streitel (karottenreibe)
|
10
|
+
# Copyright:: Copyright (c) 2009 Fabian Streitel
|
11
|
+
# License:: Boost Software License 1.0
|
12
|
+
# For further information regarding this license, you can go to
|
13
|
+
# http://www.boost.org/LICENSE_1_0.txt
|
14
|
+
# or read the file LICENSE distributed with this software.
|
15
|
+
# Homepage:: http://spectre.rubyforge.org/
|
16
|
+
# Git repo:: http://rubyforge.org/scm/?group_id=7618
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'rubygems'
|
20
|
+
require 'test/unit'
|
21
|
+
require 'spectre/string'
|
22
|
+
|
23
|
+
class StringDirectiveTests < Test::Unit::TestCase
|
24
|
+
include Spectre
|
25
|
+
include Spectre::StringParsing
|
26
|
+
include Spectre::ShortcutsMixin
|
27
|
+
|
28
|
+
def testLexemeD
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,173 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This is Spectre, a parser framework inspired by Boost.Spirit,
|
3
|
+
# which can be found at http://spirit.sourceforge.net/.
|
4
|
+
#
|
5
|
+
# If you want to find out more or need a tutorial, go to
|
6
|
+
# http://spectre.rubyforge.org/
|
7
|
+
# You'll find a nice wiki there!
|
8
|
+
#
|
9
|
+
# Author:: Fabian Streitel (karottenreibe)
|
10
|
+
# Copyright:: Copyright (c) 2009 Fabian Streitel
|
11
|
+
# License:: Boost Software License 1.0
|
12
|
+
# For further information regarding this license, you can go to
|
13
|
+
# http://www.boost.org/LICENSE_1_0.txt
|
14
|
+
# or read the file LICENSE distributed with this software.
|
15
|
+
# Homepage:: http://spectre.rubyforge.org/
|
16
|
+
# Git repo:: http://rubyforge.org/scm/?group_id=7618
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'rubygems'
|
20
|
+
require 'test/unit'
|
21
|
+
require 'spectre/string'
|
22
|
+
|
23
|
+
class StringPrimitivesTests < Test::Unit::TestCase
|
24
|
+
include Spectre
|
25
|
+
include Spectre::StringParsing
|
26
|
+
include Spectre::ShortcutsMixin
|
27
|
+
|
28
|
+
def testWhiteSpaceSkipping
|
29
|
+
p = char("a") >> char("b") >> char("c")
|
30
|
+
ret = parse " a b c ", p
|
31
|
+
assert_kind_of Match, ret
|
32
|
+
assert_equal 6, ret.length
|
33
|
+
assert_equal "abc", ret.value
|
34
|
+
|
35
|
+
p = char("a") >> lexeme_d[char("b") >> char("c")]
|
36
|
+
ret = parse " a bc ", p
|
37
|
+
assert_kind_of Match, ret
|
38
|
+
assert_equal 5, ret.length
|
39
|
+
assert_equal "abc", ret.value
|
40
|
+
|
41
|
+
ret = parse " a b c ", p
|
42
|
+
assert_kind_of NilClass, ret
|
43
|
+
end
|
44
|
+
|
45
|
+
def testCharParser
|
46
|
+
p = CharParser.new "a"
|
47
|
+
ret = parse "a", p
|
48
|
+
assert_kind_of Match, ret
|
49
|
+
assert_equal 1, ret.length
|
50
|
+
assert_equal "a", ret.value
|
51
|
+
|
52
|
+
ret = parse "asdf", p
|
53
|
+
assert_kind_of Match, ret
|
54
|
+
assert_equal 1, ret.length
|
55
|
+
assert_equal "a", ret.value
|
56
|
+
|
57
|
+
ret = parse "b", p
|
58
|
+
assert_kind_of NilClass, ret
|
59
|
+
|
60
|
+
ret = parse "ba", p
|
61
|
+
assert_kind_of NilClass, ret
|
62
|
+
|
63
|
+
ret = parse "", p
|
64
|
+
assert_kind_of NilClass, ret
|
65
|
+
end
|
66
|
+
|
67
|
+
def testStringParser
|
68
|
+
p = StringParser.new "asdf"
|
69
|
+
ret = parse "asdf", p
|
70
|
+
assert_kind_of Match, ret
|
71
|
+
assert_equal 4, ret.length
|
72
|
+
assert_equal "asdf", ret.value
|
73
|
+
|
74
|
+
ret = parse "asdfqwert", p
|
75
|
+
assert_kind_of Match, ret
|
76
|
+
assert_equal 4, ret.length
|
77
|
+
assert_equal "asdf", ret.value
|
78
|
+
|
79
|
+
ret = parse " as df ", p
|
80
|
+
assert_kind_of NilClass, ret
|
81
|
+
|
82
|
+
ret = parse "b", p
|
83
|
+
assert_kind_of NilClass, ret
|
84
|
+
|
85
|
+
ret = parse "bas", p
|
86
|
+
assert_kind_of NilClass, ret
|
87
|
+
|
88
|
+
ret = parse "", p
|
89
|
+
assert_kind_of NilClass, ret
|
90
|
+
|
91
|
+
p = StringParser.new ""
|
92
|
+
ret = parse "asdf", p
|
93
|
+
assert_kind_of Match, ret
|
94
|
+
assert_equal 0, ret.length
|
95
|
+
assert_equal "", ret.value
|
96
|
+
|
97
|
+
p = StringParser.new ""
|
98
|
+
ret = parse "", p
|
99
|
+
assert_kind_of Match, ret
|
100
|
+
assert_equal 0, ret.length
|
101
|
+
assert_equal "", ret.value
|
102
|
+
end
|
103
|
+
|
104
|
+
def testAnycharParser
|
105
|
+
p = AnycharParser.new
|
106
|
+
ret = parse "asdf", p
|
107
|
+
assert_kind_of Match, ret
|
108
|
+
assert_equal 1, ret.length
|
109
|
+
assert_equal "a", ret.value
|
110
|
+
|
111
|
+
ret = parse "asdfqwert", p
|
112
|
+
assert_kind_of Match, ret
|
113
|
+
assert_equal 1, ret.length
|
114
|
+
assert_equal "a", ret.value
|
115
|
+
|
116
|
+
ret = parse "", p
|
117
|
+
assert_kind_of NilClass, ret
|
118
|
+
end
|
119
|
+
|
120
|
+
def testGraphParser
|
121
|
+
p = lexeme_d[GraphParser.new.to_p]
|
122
|
+
ret = parse "asdf", p
|
123
|
+
assert_kind_of Match, ret
|
124
|
+
assert_equal 1, ret.length
|
125
|
+
assert_equal "a", ret.value
|
126
|
+
|
127
|
+
ret = parse "\tasdfqwert", p, false
|
128
|
+
assert_kind_of NilClass, ret
|
129
|
+
|
130
|
+
ret = parse "", p
|
131
|
+
assert_kind_of NilClass, ret
|
132
|
+
end
|
133
|
+
|
134
|
+
def testPrintParser
|
135
|
+
p = lexeme_d[PrintParser.new.to_p]
|
136
|
+
ret = parse "asdf", p
|
137
|
+
assert_kind_of Match, ret
|
138
|
+
assert_equal 1, ret.length
|
139
|
+
assert_equal "a", ret.value
|
140
|
+
|
141
|
+
ret = parse " asdf", p, false
|
142
|
+
assert_kind_of Match, ret
|
143
|
+
assert_equal 1, ret.length
|
144
|
+
assert_equal " ", ret.value
|
145
|
+
|
146
|
+
ret = parse "\tasdfqwert", p, false
|
147
|
+
assert_kind_of NilClass, ret
|
148
|
+
|
149
|
+
ret = parse "", p
|
150
|
+
assert_kind_of NilClass, ret
|
151
|
+
end
|
152
|
+
|
153
|
+
def testEOLParser
|
154
|
+
p = lexeme_d[EOLParser.new.to_p]
|
155
|
+
ret = parse "\nasdf", p, false
|
156
|
+
assert_kind_of Match, ret
|
157
|
+
assert_equal 1, ret.length
|
158
|
+
assert_equal "\n", ret.value
|
159
|
+
|
160
|
+
ret = parse "\n\r\n\nasdf", p, false
|
161
|
+
assert_kind_of Match, ret
|
162
|
+
assert_equal 4, ret.length
|
163
|
+
assert_equal "\n\r\n\n", ret.value
|
164
|
+
|
165
|
+
ret = parse "asdf", p, false
|
166
|
+
assert_kind_of NilClass, ret
|
167
|
+
|
168
|
+
ret = parse "", p
|
169
|
+
assert_kind_of NilClass, ret
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
173
|
+
|
data/test/tests.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This is Spectre, a parser framework inspired by Boost.Spirit,
|
3
|
+
# which can be found at http://spirit.sourceforge.net/.
|
4
|
+
#
|
5
|
+
# If you want to find out more or need a tutorial, go to
|
6
|
+
# http://spectre.rubyforge.org/
|
7
|
+
# You'll find a nice wiki there!
|
8
|
+
#
|
9
|
+
# Author:: Fabian Streitel (karottenreibe)
|
10
|
+
# Copyright:: Copyright (c) 2009 Fabian Streitel
|
11
|
+
# License:: Boost Software License 1.0
|
12
|
+
# For further information regarding this license, you can go to
|
13
|
+
# http://www.boost.org/LICENSE_1_0.txt
|
14
|
+
# or read the file LICENSE distributed with this software.
|
15
|
+
# Homepage:: http://spectre.rubyforge.org/
|
16
|
+
# Git repo:: http://rubyforge.org/scm/?group_id=7618
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'base/operator_tests.rb'
|
20
|
+
require 'base/grammar_tests.rb'
|
21
|
+
require 'base/closure_tests.rb'
|
22
|
+
require 'base/semanticaction_tests.rb'
|
23
|
+
require 'generic/directive_tests.rb'
|
24
|
+
require 'generic/primitive_tests.rb'
|
25
|
+
require 'generic/negation_tests.rb'
|
26
|
+
require 'string/primitive_tests.rb'
|
27
|
+
require 'string/additional_tests.rb'
|
28
|
+
require 'string/POD2Parser_tests.rb'
|
29
|
+
require 'string/directive_tests.rb'
|
30
|
+
require 'tutorial/funnymath_tests.rb'
|
31
|
+
require 'tutorial/html_tests.rb'
|
32
|
+
require 'tutorial/skipping_tests.rb'
|
33
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This is Spectre, a parser framework inspired by Boost.Spirit,
|
3
|
+
# which can be found at http://spirit.sourceforge.net/.
|
4
|
+
#
|
5
|
+
# If you want to find out more or need a tutorial, go to
|
6
|
+
# http://spectre.rubyforge.org/
|
7
|
+
# You'll find a nice wiki there!
|
8
|
+
#
|
9
|
+
# Author:: Fabian Streitel (karottenreibe)
|
10
|
+
# Copyright:: Copyright (c) 2009 Fabian Streitel
|
11
|
+
# License:: Boost Software License 1.0
|
12
|
+
# For further information regarding this license, you can go to
|
13
|
+
# http://www.boost.org/LICENSE_1_0.txt
|
14
|
+
# or read the file LICENSE distributed with this software.
|
15
|
+
# Homepage:: http://spectre.rubyforge.org/
|
16
|
+
# Git repo:: http://rubyforge.org/scm/?group_id=7618
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'rubygems'
|
20
|
+
require 'test/unit'
|
21
|
+
require 'spectre/string'
|
22
|
+
|
23
|
+
class FunnyMathTests < Test::Unit::TestCase
|
24
|
+
include Spectre
|
25
|
+
include Spectre::StringParsing
|
26
|
+
include Spectre::ShortcutsMixin
|
27
|
+
|
28
|
+
def testFunnyMath
|
29
|
+
g = Grammar.new do ||
|
30
|
+
rule :variable => (upper_char % lower_char) >> -lower_char,
|
31
|
+
:constant => string('42').+ >> char('.') >> string('42').+,
|
32
|
+
:operator => ' '.to_p >> :eyes >> :nose >> :mouth >> ' ',
|
33
|
+
:expression => char('(') >> :operand >> :operator >> :operand >> char(')'),
|
34
|
+
:operand => :variable.to_p | :constant | :expression
|
35
|
+
|
36
|
+
rule :eyes => ':'.to_p | ';' | '8',
|
37
|
+
:nose => '-',
|
38
|
+
:mouth => char(')') | '(' | '['
|
39
|
+
|
40
|
+
start_with lexeme_d[:expression]
|
41
|
+
end
|
42
|
+
|
43
|
+
text = "(FoO :-) (4242.4242 8-[ ChUnKyBaCoN))"
|
44
|
+
ret = parse text, g
|
45
|
+
assert_kind_of Match, ret
|
46
|
+
assert_equal text.length, ret.length
|
47
|
+
assert_equal text, ret.value
|
48
|
+
|
49
|
+
text = "((ChUnKy :-) BaCoN) 8-( (424242.42 ;-) FuBaR))"
|
50
|
+
ret = parse text, g
|
51
|
+
assert_kind_of Match, ret
|
52
|
+
assert_equal text.length, ret.length
|
53
|
+
assert_equal text, ret.value
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
@@ -0,0 +1,171 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This is Spectre, a parser framework inspired by Boost.Spirit,
|
3
|
+
# which can be found at http://spirit.sourceforge.net/.
|
4
|
+
#
|
5
|
+
# If you want to find out more or need a tutorial, go to
|
6
|
+
# http://spectre.rubyforge.org/
|
7
|
+
# You'll find a nice wiki there!
|
8
|
+
#
|
9
|
+
# Author:: Fabian Streitel (karottenreibe)
|
10
|
+
# Copyright:: Copyright (c) 2009 Fabian Streitel
|
11
|
+
# License:: Boost Software License 1.0
|
12
|
+
# For further information regarding this license, you can go to
|
13
|
+
# http://www.boost.org/LICENSE_1_0.txt
|
14
|
+
# or read the file LICENSE distributed with this software.
|
15
|
+
# Homepage:: http://spectre.rubyforge.org/
|
16
|
+
# Git repo:: http://rubyforge.org/scm/?group_id=7618
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'test/unit'
|
20
|
+
require 'rubygems'
|
21
|
+
require 'spectre/string'
|
22
|
+
|
23
|
+
class HTMLTests < Test::Unit::TestCase
|
24
|
+
include Spectre
|
25
|
+
include Spectre::StringParsing
|
26
|
+
|
27
|
+
def testTag
|
28
|
+
element = Grammar.new do ||
|
29
|
+
rule :tagname => ( ~char('>') & ~char(' ') ).+
|
30
|
+
start_with( char('<') >> :tagname >> string('></') >> :tagname >> char('>') )
|
31
|
+
end
|
32
|
+
|
33
|
+
ret = parse '<foo></foo>', element
|
34
|
+
assert_kind_of Match, ret
|
35
|
+
assert_equal 11, ret.length
|
36
|
+
|
37
|
+
ret = parse ' < foo ></bar>', element
|
38
|
+
assert_kind_of Match, ret
|
39
|
+
|
40
|
+
ret = parse ' < foo></bar>', element
|
41
|
+
assert_kind_of Match, ret
|
42
|
+
assert_equal 15, ret.length
|
43
|
+
end
|
44
|
+
|
45
|
+
def testTagClosure
|
46
|
+
element = Grammar.new do ||
|
47
|
+
rule :tagname => ( ~char('>') & ~char(' ') ).+,
|
48
|
+
:element => char('<') >> sym(:tagname)[:tag] >> string('></') >> closed(:tag) >> char('>')
|
49
|
+
start_with close(:element)
|
50
|
+
end
|
51
|
+
|
52
|
+
ret = parse '<foo></foo>', element
|
53
|
+
assert_kind_of Match, ret
|
54
|
+
assert_equal 11, ret.length
|
55
|
+
|
56
|
+
ret = parse '<foo></bar>', element
|
57
|
+
assert_kind_of NilClass, ret
|
58
|
+
end
|
59
|
+
|
60
|
+
def testData
|
61
|
+
element = Grammar.new do ||
|
62
|
+
rule :tagname => ( ~char('>') & ~char(' ') ).+,
|
63
|
+
:element => char('<') >> sym(:tagname)[:tag] >> char('>') >> :data >> string('</') >> closed(:tag) >> char('>'),
|
64
|
+
:data => ( ~char('<') ).*
|
65
|
+
start_with close(:element)
|
66
|
+
end
|
67
|
+
|
68
|
+
ret = parse '<foo></foo>', element
|
69
|
+
assert_kind_of Match, ret
|
70
|
+
assert_equal 11, ret.length
|
71
|
+
|
72
|
+
ret = parse '<foo>data</foo>', element
|
73
|
+
assert_kind_of Match, ret
|
74
|
+
assert_equal 15, ret.length
|
75
|
+
|
76
|
+
ret = parse '<foo><</foo>', element
|
77
|
+
assert_kind_of NilClass, ret
|
78
|
+
|
79
|
+
ret = parse '<foo></bar>', element
|
80
|
+
assert_kind_of NilClass, ret
|
81
|
+
end
|
82
|
+
|
83
|
+
class Element
|
84
|
+
attr_accessor :tag, :attributes, :data
|
85
|
+
end
|
86
|
+
|
87
|
+
class Data
|
88
|
+
attr_accessor :data
|
89
|
+
end
|
90
|
+
|
91
|
+
def testNodeAction
|
92
|
+
val = 1
|
93
|
+
|
94
|
+
newelement_a = lambda { |match, closure|
|
95
|
+
closure[:element] = Element.new
|
96
|
+
closure[:element].tag = match.value
|
97
|
+
val += val
|
98
|
+
}
|
99
|
+
|
100
|
+
element = Grammar.new do ||
|
101
|
+
rule :tagname => ( ~char('>') & ~char(' ') ).+,
|
102
|
+
:element => char('<') >> sym(:tagname)[:tag][newelement_a] >> char('>') >> :data >> string('</') >> closed(:tag) >> char('>'),
|
103
|
+
:data => ( ~char('<') ).*
|
104
|
+
start_with close(:element)
|
105
|
+
end
|
106
|
+
|
107
|
+
ret = parse '<foo></foo>', element
|
108
|
+
assert_kind_of Match, ret
|
109
|
+
assert_equal 11, ret.length
|
110
|
+
|
111
|
+
ret = parse '<foo>data</foo>', element
|
112
|
+
assert_kind_of Match, ret
|
113
|
+
assert_equal 15, ret.length
|
114
|
+
|
115
|
+
ret = parse '<foo><</foo>', element
|
116
|
+
assert_kind_of NilClass, ret
|
117
|
+
|
118
|
+
ret = parse '<foo></bar>', element
|
119
|
+
assert_kind_of NilClass, ret
|
120
|
+
|
121
|
+
assert_equal 16, val
|
122
|
+
end
|
123
|
+
|
124
|
+
def testDataAction
|
125
|
+
val = 1
|
126
|
+
foo = nil
|
127
|
+
|
128
|
+
newelement_a = lambda { |match, closure|
|
129
|
+
closure[:element] = Element.new
|
130
|
+
closure[:element].tag = closure[:tag]
|
131
|
+
closure[:element].data = closure[:data]
|
132
|
+
val += val
|
133
|
+
}
|
134
|
+
|
135
|
+
foo_a = lambda { |match, closure|
|
136
|
+
foo = match.value
|
137
|
+
}
|
138
|
+
|
139
|
+
element = Grammar.new do ||
|
140
|
+
rule :tagname => ( ~char('>') & ~char(' ') ).+,
|
141
|
+
:element => char('<') >> sym(:tagname)[:tag] >> lexeme_d[char('>') >> sym(:data)[:data]] >> string('</') >> closed(:tag) >> char('>'),
|
142
|
+
:data => ( ( ~char('<') ).* )[foo_a]
|
143
|
+
start_with sym(:element)[newelement_a]
|
144
|
+
end
|
145
|
+
|
146
|
+
element.closure = Closure.new
|
147
|
+
|
148
|
+
ret = parse '<foo></foo>', element
|
149
|
+
assert_kind_of Match, ret
|
150
|
+
assert_kind_of Element, element.closure[:element]
|
151
|
+
assert_equal 11, ret.length
|
152
|
+
|
153
|
+
ret = parse '<foo>data</foo>', element
|
154
|
+
assert_kind_of Match, ret
|
155
|
+
assert_equal 15, ret.length
|
156
|
+
|
157
|
+
ret = parse '<foo><</foo>', element
|
158
|
+
assert_kind_of NilClass, ret
|
159
|
+
|
160
|
+
ret = parse '<foo></bar>', element
|
161
|
+
assert_kind_of NilClass, ret
|
162
|
+
|
163
|
+
foo = nil
|
164
|
+
ret = parse '<foo> data</bar>', element
|
165
|
+
assert_equal " data", foo
|
166
|
+
|
167
|
+
assert_equal 4, val
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
|