Spectre 0.0.1
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/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
|
+
|