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.
Files changed (38) hide show
  1. data/CHANGELOG +1 -0
  2. data/LICENSE +23 -0
  3. data/README +20 -0
  4. data/Rakefile +112 -0
  5. data/lib/spectre/base.rb +44 -0
  6. data/lib/spectre/base/closure.rb +96 -0
  7. data/lib/spectre/base/directive.rb +148 -0
  8. data/lib/spectre/base/grammar.rb +269 -0
  9. data/lib/spectre/base/inputiterator.rb +276 -0
  10. data/lib/spectre/base/node.rb +393 -0
  11. data/lib/spectre/base/operators.rb +342 -0
  12. data/lib/spectre/base/parser.rb +110 -0
  13. data/lib/spectre/generic.rb +115 -0
  14. data/lib/spectre/generic/directives.rb +246 -0
  15. data/lib/spectre/generic/negations.rb +68 -0
  16. data/lib/spectre/generic/primitives.rb +172 -0
  17. data/lib/spectre/generic/semanticaction.rb +43 -0
  18. data/lib/spectre/string.rb +57 -0
  19. data/lib/spectre/string/additionals.rb +80 -0
  20. data/lib/spectre/string/directives.rb +51 -0
  21. data/lib/spectre/string/inputiterator.rb +57 -0
  22. data/lib/spectre/string/primitives.rb +400 -0
  23. data/test/base/closure_tests.rb +108 -0
  24. data/test/base/grammar_tests.rb +97 -0
  25. data/test/base/operator_tests.rb +335 -0
  26. data/test/base/semanticaction_tests.rb +53 -0
  27. data/test/generic/directive_tests.rb +224 -0
  28. data/test/generic/negation_tests.rb +146 -0
  29. data/test/generic/primitive_tests.rb +99 -0
  30. data/test/string/POD2Parser_tests.rb +93 -0
  31. data/test/string/additional_tests.rb +43 -0
  32. data/test/string/directive_tests.rb +32 -0
  33. data/test/string/primitive_tests.rb +173 -0
  34. data/test/tests.rb +33 -0
  35. data/test/tutorial/funnymath_tests.rb +57 -0
  36. data/test/tutorial/html_tests.rb +171 -0
  37. data/test/tutorial/skipping_tests.rb +60 -0
  38. metadata +109 -0
@@ -0,0 +1,53 @@
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 SemanticActionTests < Test::Unit::TestCase
24
+ include Spectre
25
+ include Spectre::StringParsing
26
+ include Spectre::ShortcutsMixin
27
+
28
+ def setup
29
+ @tag_grammar = Grammar.new do ||
30
+ rule :tag => lexeme_d['<'.to_p >> blank_char >> :tagname.to_p[:tag] >> '>']
31
+ rule :tagname => ( ~char('>') ).+
32
+ rule :border => :tag
33
+ start_with :tag
34
+ end
35
+ end
36
+
37
+ def testSimpleAction
38
+ val = 0
39
+ a = lambda { val = 22 }
40
+ p = any_char[a]
41
+
42
+ ret = parse 'a', p
43
+ assert_equal 1, ret.length
44
+ assert_equal 'a', ret.value
45
+ assert_equal val, 22
46
+ end
47
+
48
+ def testClosureAction
49
+ c = @tag_grammar.closure = Closure.new
50
+ ret = parse '< foo>', @tag_grammar
51
+ assert_equal 'foo', c[:tag]
52
+ end
53
+ end
@@ -0,0 +1,224 @@
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 DirectiveTests < Test::Unit::TestCase
24
+ include Spectre
25
+ include Spectre::StringParsing
26
+ include Spectre::ShortcutsMixin
27
+
28
+ def testNoActionD
29
+ val = 1
30
+
31
+ tester = lambda { |m,c|
32
+ val += 12
33
+ }
34
+
35
+ p = noaction_d[any_char[tester]]
36
+ ret = parse 'aaa', p
37
+ assert_kind_of Match, ret
38
+ assert_equal 1, val
39
+ assert_equal "a", ret.value
40
+ end
41
+
42
+ def testResetD
43
+ val = 1
44
+
45
+ tester = lambda { |m,c|
46
+ val += 12
47
+ }
48
+
49
+ p = noaction_d[reset_d[any_char[tester]]]
50
+ ret = parse 'aa', p
51
+ assert_kind_of Match, ret
52
+ assert_equal 13, val
53
+ end
54
+
55
+ class Limit
56
+ include Comparable
57
+
58
+ def initialize fn
59
+ @fn = fn
60
+ end
61
+
62
+ def <=> s
63
+ @fn <=> s.length
64
+ end
65
+ end
66
+
67
+ def testLimitD
68
+ p = limit_d(Limit.new(2),Limit.new(4))[any_char.*]
69
+ ret = parse 'aa', p
70
+ assert_kind_of Match, ret
71
+ ret = parse 'aaa', p
72
+ assert_kind_of Match, ret
73
+ ret = parse 'aaaa', p
74
+ assert_kind_of Match, ret
75
+ ret = parse 'a', p
76
+ assert_kind_of NilClass, ret
77
+ ret = parse 'aaaaa', p
78
+ assert_kind_of NilClass, ret
79
+ end
80
+
81
+ def testSkipD
82
+ p = skip_d(['a', 'b', 'c'].to_p)[blank_char >> any_char]
83
+
84
+ ret = parse ' u', p
85
+ assert_kind_of Match, ret
86
+ assert_equal 2, ret.length
87
+
88
+ ret = parse 'abcabc abcu', p
89
+ assert_kind_of Match, ret
90
+ assert_equal 11, ret.length
91
+
92
+ p = skip_d(["\n", "\r", "\t", "\f", " "].to_p)[char("a") >> any_char]
93
+ ret = parse " \n \r a \t\fu ", p
94
+ assert_kind_of Match, ret
95
+ end
96
+
97
+ class SP < StringParser
98
+ class << self
99
+ attr_accessor :val
100
+
101
+ def new *args
102
+ Spectre::Node.new super(*args)
103
+ end
104
+ end
105
+
106
+ def scan *args
107
+ SP.val += 1
108
+ super(*args)
109
+ end
110
+ end
111
+
112
+ def testLongestD
113
+ SP.val = 0
114
+ p = longest_d[SP.new('a')|SP.new('ab')|SP.new('aac')]
115
+ ret = parse "aac", p
116
+ assert_equal 3, SP.val
117
+ assert_kind_of Match, ret
118
+ assert_equal "aac", ret.value
119
+
120
+ SP.val = 0
121
+ ret = parse "ab", p
122
+ assert_equal 3, SP.val
123
+ assert_kind_of Match, ret
124
+ assert_equal "ab", ret.value
125
+
126
+ SP.val = 0
127
+ ret = parse "a", p
128
+ assert_equal 3, SP.val
129
+ assert_kind_of Match, ret
130
+ assert_equal "a", ret.value
131
+ end
132
+
133
+ def testShortestD
134
+ SP.val = 0
135
+ p = shortest_d[SP.new('a')|SP.new('ab')|SP.new('cac')]
136
+ ret = parse "cac", p
137
+ assert_equal 3, SP.val
138
+ assert_kind_of Match, ret
139
+ assert_equal "cac", ret.value
140
+
141
+ SP.val = 0
142
+ ret = parse "ab", p
143
+ assert_equal 3, SP.val
144
+ assert_kind_of Match, ret
145
+ assert_equal "a", ret.value
146
+
147
+ SP.val = 0
148
+ ret = parse "a", p
149
+ assert_equal 3, SP.val
150
+ assert_kind_of Match, ret
151
+ assert_equal "a", ret.value
152
+ end
153
+
154
+ def testLexemeD
155
+ p = noskip_d[char('a') >> char('b')]
156
+ p = lexeme_d[char('a') >> char('b')]
157
+ ret = parse "ab", p
158
+ assert_kind_of Match, ret
159
+ assert_equal "ab", ret.value
160
+ assert_equal 2, ret.length
161
+
162
+ ret = parse " ab", p
163
+ assert_kind_of Match, ret
164
+ assert_equal "ab", ret.value
165
+ assert_equal 3, ret.length
166
+
167
+ ret = parse "a b", p
168
+ assert_kind_of NilClass, ret
169
+
170
+ p = char('o') >> lexeme_d[char('a') >> char('b')]
171
+ ret = parse "o ab", p
172
+ assert_kind_of Match, ret
173
+ assert_equal "oab", ret.value
174
+ assert_equal 4, ret.length
175
+
176
+ ret = parse "oab", p
177
+ assert_kind_of Match, ret
178
+ assert_equal "oab", ret.value
179
+ assert_equal 3, ret.length
180
+ end
181
+
182
+ def testNoPreSkipLexemeD
183
+ p = noskip_d![char('a') >> char('b')]
184
+ p = lexeme_d![char('a') >> char('b')]
185
+ ret = parse "ab", p
186
+ assert_kind_of Match, ret
187
+ assert_equal "ab", ret.value
188
+ assert_equal 2, ret.length
189
+
190
+ ret = parse "a b", p
191
+ assert_kind_of NilClass, ret
192
+
193
+ ret = parse " ab", p
194
+ assert_kind_of NilClass, ret
195
+
196
+ p = char('o') >> lexeme_d![char('a') >> char('b')]
197
+ ret = parse "o ab", p
198
+ assert_kind_of NilClass, ret
199
+
200
+ ret = parse "oab", p
201
+ assert_kind_of Match, ret
202
+ assert_equal "oab", ret.value
203
+ assert_equal 3, ret.length
204
+ end
205
+
206
+ def testEpsilonD
207
+ p = epsilon[string("foo")]
208
+ p = e[string("foo")]
209
+ ret = parse "foo", p
210
+ assert_kind_of Match, ret
211
+ assert_equal 0, ret.length
212
+ assert_equal "foo", ret.value
213
+
214
+ ret = parse " foo", p
215
+ assert_kind_of Match, ret
216
+ assert_equal 0, ret.length
217
+ assert_equal "foo", ret.value
218
+
219
+ ret = parse "bar", p
220
+ assert_kind_of NilClass, ret
221
+ end
222
+
223
+ end
224
+
@@ -0,0 +1,146 @@
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 GenericNegationTests < Test::Unit::TestCase
24
+ include Spectre
25
+ include Spectre::Operators
26
+ include Spectre::StringParsing
27
+
28
+ def testSingleTokenNegation
29
+ p = Node.new Negation.new, CharParser.new("a")
30
+ iter = StringInputIterator.new "asdf"
31
+ ret = p.parse iter
32
+ assert_kind_of NilClass, ret
33
+ assert_equal 0, iter.pos
34
+
35
+ iter = StringInputIterator.new "33df"
36
+ ret = p.parse iter
37
+ assert_kind_of Match, ret
38
+ assert_equal 1, ret.length
39
+ assert_equal "3", ret.value
40
+ assert_equal 1, iter.pos
41
+
42
+ iter = StringInputIterator.new " 33df"
43
+ ret = p.parse iter
44
+ assert_kind_of Match, ret
45
+ assert_equal 3, ret.length
46
+ assert_equal "3", ret.value
47
+ assert_equal 3, iter.pos
48
+
49
+ iter = StringInputIterator.new "\tdf"
50
+ ret = p.parse iter
51
+ assert_kind_of Match, ret
52
+ assert_equal 2, ret.length
53
+ assert_equal "d", ret.value
54
+ assert_equal 2, iter.pos
55
+ end
56
+
57
+ def testZeroTokenNegation
58
+ p = Node.new Negation.new, EOIParser.new
59
+ iter = StringInputIterator.new " asdf"
60
+ ret = p.parse iter, false
61
+ assert_kind_of Match, ret
62
+ assert_equal 0, ret.length
63
+ assert_equal "", ret.value
64
+ assert_equal 0, iter.pos
65
+
66
+ iter = StringInputIterator.new " "
67
+ ret = p.parse iter
68
+ assert_kind_of NilClass, ret
69
+ assert_equal 0, iter.pos
70
+
71
+ iter = StringInputIterator.new ""
72
+ ret = p.parse iter
73
+ assert_kind_of NilClass, ret
74
+ assert_equal 0, iter.pos
75
+ end
76
+
77
+ def testSequenceNegation
78
+ p = Node.new Negation.new, SequenceParser.new("foa")
79
+ iter = StringInputIterator.new " a of"
80
+ ret = p.parse iter
81
+ assert_kind_of Match, ret
82
+ assert_equal 1, ret.length
83
+ assert_equal "", ret.value
84
+ assert_equal 1, iter.pos
85
+
86
+ iter = StringInputIterator.new " "
87
+ ret = p.parse iter, false
88
+ assert_kind_of Match, ret
89
+ assert_equal 0, ret.length
90
+ assert_equal "", ret.value
91
+ assert_equal 0, iter.pos
92
+
93
+ iter = StringInputIterator.new "fo a"
94
+ ret = p.parse iter
95
+ assert_kind_of NilClass, ret
96
+ assert_equal 0, iter.pos
97
+ end
98
+
99
+ def testStringNegation
100
+ p = Node.new Negation.new, StringParser.new("foo")
101
+ iter = StringInputIterator.new " asdf"
102
+ ret = p.parse iter
103
+ assert_kind_of Match, ret
104
+ assert_equal 1, ret.length
105
+ assert_equal "", ret.value
106
+ assert_equal 1, iter.pos
107
+
108
+ iter = StringInputIterator.new " "
109
+ ret = p.parse iter, false
110
+ assert_kind_of Match, ret
111
+ assert_equal 0, ret.length
112
+ assert_equal "", ret.value
113
+ assert_equal 0, iter.pos
114
+
115
+ iter = StringInputIterator.new "foo"
116
+ ret = p.parse iter
117
+ assert_kind_of NilClass, ret
118
+ assert_equal 0, iter.pos
119
+ end
120
+
121
+ def testClosureParserNegation
122
+ gram = Grammar.new do ||
123
+ start_with close( lower_char[:foo] >> ~closed(:foo) )
124
+ end
125
+
126
+ iter = StringInputIterator.new 'ab'
127
+ ret = gram.parse iter
128
+ assert_kind_of Match, ret
129
+ assert_equal 2, ret.length
130
+ assert_equal "ab", ret.value
131
+ assert_equal 2, iter.pos
132
+
133
+ iter = StringInputIterator.new ' ab'
134
+ ret = gram.parse iter
135
+ assert_kind_of Match, ret
136
+ assert_equal 4, ret.length
137
+ assert_equal "ab", ret.value
138
+ assert_equal 4, iter.pos
139
+
140
+ iter = StringInputIterator.new ' aa'
141
+ ret = gram.parse iter
142
+ assert_kind_of NilClass, ret
143
+ end
144
+
145
+ end
146
+
@@ -0,0 +1,99 @@
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 testRangeParser
29
+ p = RangeParser.new "a".."c"
30
+ ret = parse "a", p
31
+ assert_kind_of Match, ret
32
+ assert_equal 1, ret.length
33
+ assert_equal "a", ret.value
34
+
35
+ ret = parse "chunky", p
36
+ assert_kind_of Match, ret
37
+ assert_equal 1, ret.length
38
+ assert_equal "c", ret.value
39
+
40
+ ret = parse "1", p
41
+ assert_kind_of NilClass, ret
42
+
43
+ ret = parse "zba", p
44
+ assert_kind_of NilClass, ret
45
+
46
+ ret = parse "", p
47
+ assert_kind_of NilClass, ret
48
+ end
49
+
50
+ def testSequenceParser
51
+ p = SequenceParser.new "chunky".split("")
52
+ ret = parse "chunky-b", p
53
+ assert_kind_of Match, ret
54
+ assert_equal 6, ret.length
55
+ assert_equal "chunky", ret.value
56
+
57
+ ret = parse "chunky", p
58
+ assert_kind_of Match, ret
59
+ assert_equal 6, ret.length
60
+ assert_equal "chunky", ret.value
61
+
62
+ ret = parse "\tc h u\nnk y\f", p
63
+ assert_kind_of Match, ret
64
+ assert_equal 12, ret.length
65
+ assert_equal "chunky", ret.value
66
+
67
+ ret = parse "z", p
68
+ assert_kind_of NilClass, ret
69
+
70
+ ret = parse "", p
71
+ assert_kind_of NilClass, ret
72
+ end
73
+
74
+ def testNothingParser
75
+ p = NothingParser.new
76
+ ret = parse "asdf", p
77
+ assert_kind_of NilClass, ret
78
+
79
+ ret = parse "", p
80
+ assert_kind_of NilClass, ret
81
+ end
82
+
83
+ def testEOIParser
84
+ p = EOIParser.new
85
+ ret = parse "asdf", p
86
+ assert_kind_of NilClass, ret
87
+
88
+ ret = parse "", p
89
+ assert_kind_of Match, ret
90
+ assert_equal 0, ret.length
91
+ assert_equal "", ret.value
92
+
93
+ ret = parse " ", p
94
+ assert_kind_of Match, ret
95
+ assert_equal 0, ret.length
96
+ assert_equal "", ret.value
97
+ end
98
+ end
99
+