pegex 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,7 +2,7 @@ require 'pegex/receiver'
2
2
 
3
3
  class Pegex::Tree < Pegex::Receiver
4
4
  def gotrule got=nil
5
- return $pegex_nil if got.nil?
5
+ return Pegex::Constant::Null if got.nil?
6
6
 
7
7
  if self.parser.parent['-wrap']
8
8
  return {self.parser.rule => (got || [])}
@@ -2,8 +2,8 @@ require 'pegex/tree'
2
2
 
3
3
  class Pegex::Tree::Wrap < Pegex::Tree
4
4
  def gotrule got
5
- return got if @parser.parent['-pass']
6
- return $pegex_nil unless got
5
+ return got || Pegex::Constant::Null if @parser.parent['-pass']
6
+ return Pegex::Constant::Null unless got
7
7
  return @parser.rule => got
8
8
  end
9
9
 
@@ -0,0 +1,38 @@
1
+ require 'test/unit'
2
+
3
+ class Test::Unit::TestCase
4
+ def test
5
+ require 'pegex'
6
+ assert method('pegex'),
7
+ 'pegex is exported'
8
+
9
+ parser1 = pegex "foo: <bar>\n"
10
+
11
+ assert parser1.kind_of?(Pegex::Parser),
12
+ 'pegex returns a Pegex::Parser object'
13
+
14
+ assert_equal parser1.grammar.tree['+toprule'], 'foo',
15
+ 'pegex() contains a grammar with a compiled tree'
16
+
17
+ parser2 = pegex(<<'...');
18
+ number: /<DIGIT>+/
19
+ ...
20
+
21
+ begin
22
+ parser2.parse '123'
23
+ assert true, 'parser2.parse worked'
24
+ rescue
25
+ assert false, "parser2.parse failed: #{$!.message}"
26
+ end
27
+
28
+ assert parser2.kind_of?(Pegex::Parser),
29
+ 'grammar property is Pegex::Parser object'
30
+
31
+ tree2 = parser2.grammar.tree
32
+ assert tree2, 'Grammar object has tree';
33
+ assert tree2.kind_of?(Hash), 'Grammar object is compiled to a tree'
34
+
35
+ assert_equal tree2['+toprule'], 'number',
36
+ '_FIRST_RULE is set correctly'
37
+ end
38
+ end
@@ -0,0 +1,30 @@
1
+ require 'test/unit'
2
+ require 'pegex'
3
+ require 'pegex/receiver'
4
+
5
+ class TestFlatten < Test::Unit::TestCase
6
+ def test_flatten
7
+ grammar = <<'...'
8
+ a: (((b)))+
9
+ b: (c | d)
10
+ c: /(x)/
11
+ d: /y/
12
+ ...
13
+ parser = pegex(grammar, R)
14
+ got = parser.parse('xxx')
15
+
16
+ assert_equal got.join(''), 'xxx', 'Array was flattened'
17
+ end
18
+ end
19
+
20
+ class R < Pegex::Receiver
21
+ def got_a(got)
22
+ got.flatten
23
+ end
24
+ def got_b(got)
25
+ [got]
26
+ end
27
+ def got_c(got)
28
+ [got]
29
+ end
30
+ end
@@ -1,6 +1,25 @@
1
- require './test/lib/test_pegex'
1
+ require 'testml'
2
+ require 'testml/compiler/lite'
3
+ require 'testml/util'; include TestML::Util
2
4
  require 'pegex/grammar'
3
5
 
6
+ TestML.new(
7
+ compiler: TestML::Compiler::Lite,
8
+ ).testml = <<'...'
9
+ %TestML 0.1.0
10
+ Plan = 1
11
+ # Label = 'MyGrammar1 compiled a tree from its text'
12
+ grammar_api() == 'foo'
13
+ ...
14
+
15
+ class TestML::Bridge
16
+ def grammar_api
17
+ grammar = MyGrammar1.new
18
+ grammar.make_tree
19
+ native grammar.tree['+toprule']
20
+ end
21
+ end
22
+
4
23
  class MyGrammar1 < Pegex::Grammar
5
24
  def initialize
6
25
  @text = <<'...'
@@ -12,10 +31,3 @@ baz: /def/
12
31
  ...
13
32
  end
14
33
  end
15
-
16
- TestML.run do |t|
17
- g1 = MyGrammar1.new
18
- g1.make_tree
19
- t.assert_equal g1.tree['+toprule'], 'foo',
20
- 'MyGrammar1 compiled a tree from its text'
21
- end
@@ -1,13 +1,13 @@
1
1
  def XXX object
2
- require 'psych'
3
- puts Psych.dump object
2
+ require 'yaml'
3
+ puts YAML.dump object
4
4
  puts 'XXX from: ' + caller.first
5
5
  exit
6
6
  end
7
7
 
8
8
  def YYY object, show_caller=true
9
- require 'psych'
10
- puts Psych.dump object
9
+ require 'yaml'
10
+ puts YAML.dump object
11
11
  puts 'YYY from: ' + caller.first if show_caller
12
12
  return object
13
13
  end
@@ -0,0 +1,7 @@
1
+ phrase: !one number ~ things EOL
2
+
3
+ one: /1/
4
+
5
+ number: DIGIT
6
+
7
+ things: /blind<SPACE>mice/
@@ -0,0 +1,18 @@
1
+ require 'test/unit'
2
+ require 'pegex'
3
+ require 'pegex/input'
4
+
5
+ class TestParse < Test::Unit::TestCase
6
+ def test_parse
7
+ grammar_file = 'test/mice.pgx';
8
+ # XXX need to add file support to Pegex::Input
9
+ # input = Pegex::Input.new(file: grammar_file)
10
+ input = File.read(grammar_file)
11
+ begin
12
+ pegex(input).parse("3 blind mice\n")
13
+ assert true, "!<rule> works"
14
+ rescue
15
+ assert false, "!<rule> fails"
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,10 @@
1
+ require 'test/unit'
2
+ require 'pegex'
3
+
4
+ class TestRepeat < Test::Unit::TestCase
5
+ def test_repeat
6
+ parser = pegex('a: /<ANY>*?(x+)<ANY>*/')
7
+ assert_equal parser.parse('xxxx')['a'], 'xxxx', 'First parse works'
8
+ assert_equal parser.parse('xxxx')['a'], 'xxxx', 'Second parse works'
9
+ end
10
+ end
@@ -0,0 +1,72 @@
1
+ require 'test/unit'
2
+
3
+ class TestSample < Test::Unit::TestCase
4
+ def test_sample
5
+ grammar_text = <<'...'
6
+ contact:
7
+ name_section
8
+ phone_section
9
+ address_section
10
+
11
+ name_section:
12
+ / Name <COLON> <BLANK>+ /
13
+ name
14
+ EOL
15
+
16
+ name: /(<WORD>+)<BLANK>(<WORD>+)/
17
+
18
+ phone_section: /Phone<COLON><BLANK>+/ <phone_number> <EOL>
19
+ phone_number: term
20
+
21
+ address_section:
22
+ /Address<COLON><EOL>/
23
+ street_line
24
+ city_line
25
+ country_line?
26
+
27
+ street_line: indent street EOL
28
+ street: /<NS><ANY>*/
29
+ city_line: indent city EOL
30
+ city: term
31
+ country_line: indent country EOL
32
+ country: term
33
+
34
+ term: /(
35
+ <NS> # NS is "non-space"
36
+ <ANY>*
37
+ )/
38
+
39
+ indent: /<BLANK>{2}/
40
+ ...
41
+
42
+ input = <<'...'
43
+ Name: Ingy Net
44
+ Phone: 919-876-5432
45
+ Address:
46
+ 1234 Main St
47
+ Niceville
48
+ OK
49
+ ...
50
+
51
+ want = <<'...'
52
+ ...
53
+
54
+ require 'pegex/grammar'
55
+ require 'pegex/receiver'
56
+ require 'pegex/compiler'
57
+ grammar = Pegex::Grammar.new do |i|
58
+ i.tree = Pegex::Compiler.new.compile(grammar_text).tree
59
+ end
60
+ parser = Pegex::Parser.new do |i|
61
+ i.grammar = grammar
62
+ i.receiver = Pegex::Receiver.new
63
+ end
64
+ ast1 = parser.parse(input)
65
+
66
+ assert true, 'parsed'
67
+ # TODO
68
+ # got = YAML.dump(ast1)
69
+ # assert_equal got, want, 'It works'
70
+ end
71
+ end
72
+
@@ -0,0 +1,25 @@
1
+ require 'test/unit'
2
+ require 'testml'
3
+ require 'testml/compiler/lite'
4
+ $:.unshift "#{Dir.getwd}/test"
5
+ $:.unshift "#{Dir.getwd}/test/lib"
6
+ require 'testml_bridge'
7
+
8
+ class TestMLTestCase < Test::Unit::TestCase
9
+ def run_testml_file(file)
10
+ TestML.new(
11
+ testml: file,
12
+ bridge: TestMLBridge,
13
+ compiler: TestML::Compiler::Lite,
14
+ ).run(self)
15
+ end
16
+
17
+ (Dir.glob('test/testml/*.tml')
18
+ .collect {|f| f.sub(/^test\//, '')}
19
+ ).each do |file|
20
+ method_name = 'test_' + file.gsub(/\W+/, '_').sub(/_tml$/, '')
21
+ define_method(method_name.to_sym) do
22
+ run_testml_file(file)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,3 @@
1
+ source_testml_dir: ../../pegex-tml
2
+ local_testml_dir: ./testml
3
+ exclude_testml_files: []
@@ -1,12 +1,10 @@
1
- #!/usr/bin/env testml
1
+ %TestML 0.1.0
2
2
 
3
- %TestML 1.0
3
+ Plan = 48
4
4
 
5
- Plan = 50;
5
+ *grammar.bootstrap_compile.yaml.clean == *yaml
6
+ *grammar.compile.yaml.clean == *yaml
6
7
 
7
- *grammar.compile.yaml.clean == *yaml;
8
-
9
- testml_data <<'...'
10
8
  === Empty Grammar
11
9
  --- grammar
12
10
  --- yaml
@@ -256,10 +254,10 @@ a:
256
254
 
257
255
  === Meta Lines
258
256
  --- grammar
259
- %grammar foo
260
- %version 1.1.1
261
- %extends bar bar
262
- %include bazzy
257
+ \%grammar foo
258
+ \%version 1.1.1
259
+ \%extends bar bar
260
+ \%include bazzy
263
261
  a: /b/
264
262
  --- yaml
265
263
  +extends: bar bar
@@ -268,4 +266,3 @@ a: /b/
268
266
  +version: 1.1.1
269
267
  a:
270
268
  .rgx: b
271
- ...
@@ -1,12 +1,7 @@
1
- require './test/lib/test_pegex'
1
+ %TestML 0.1.0
2
2
 
3
- TestML.require_or_skip 'psych'
3
+ *grammar1.compile.yaml == *grammar2.compile.yaml
4
4
 
5
- TestML.run do |t|
6
- t.eval '*grammar1.compile.yaml == *grammar2.compile.yaml'
7
- end
8
-
9
- TestML.data <<'...'
10
5
  === Simple Test Case
11
6
  --- grammar1
12
7
  a: /x/
@@ -76,4 +71,3 @@ a b: /O HAI/
76
71
  --- grammar2
77
72
  a: /O HAI/
78
73
  b: /O HAI/
79
- ...
@@ -1,3 +1,16 @@
1
+ %TestML 0.1.0
2
+
3
+ Plan = 63
4
+
5
+ Label = '$BlockLabel - Compiler output matches bootstrap?'
6
+ *grammar.compile.yaml == *grammar.bootstrap_compile.yaml
7
+
8
+ Label = '$BlockLabel - Compressed grammar compiles the same?'
9
+ *grammar.compress.compile.yaml == *grammar.compress.compile.yaml
10
+
11
+ Label = '$BlockLabel - Compressed grammar matches uncompressed?'
12
+ *grammar.compress.compile.yaml == *grammar.compile.yaml
13
+
1
14
  === Single Regex
2
15
  --- grammar
3
16
  a: /x/
@@ -1,17 +1,7 @@
1
- require './test/lib/test_pegex'
1
+ %TestML 0.1.0
2
2
 
3
- TestML.run do |t|
4
- t.eval 'parse_input(*grammar, *input).Catch ~~ *error'
5
- end
3
+ parse_input(*grammar, *input).Catch ~~ *error
6
4
 
7
- class TestPegex
8
- def parse_input grammar, input
9
- parser = pegex grammar
10
- return parser.parse input
11
- end
12
- end
13
-
14
- TestML.data <<'...'
15
5
  === Error fails at furthest match
16
6
  # XXX This one not testing much.
17
7
  --- grammar
@@ -158,4 +148,3 @@ a: /a+/ %%~%%^%% ~
158
148
  aaa
159
149
  --- error: Rule ending syntax error
160
150
  # --- error: Illegal characters in separator indicator
161
- ...
@@ -0,0 +1,14 @@
1
+ %TestML 0.1.0
2
+
3
+ # XXX Skipping this test for now. Might need a %Skip in TestML
4
+ '1' == '1'
5
+ # *grammar.compile.optimize.yaml.clean == *yaml
6
+
7
+
8
+ === Question Mark Expansion
9
+ --- SKIP
10
+ --- grammar
11
+ a: /(:foo)/
12
+ --- yaml
13
+ a:
14
+ .rgx: /(?:foo)/
@@ -1,5 +1,15 @@
1
+ %TestML 0.1.0
2
+
3
+ Plan = 2
4
+
5
+ Label = '$BlockLabel - Pegex::Tree'
6
+ parse_to_tree(*grammar, *input).yaml.clean == *tree
7
+ Label = '$BlockLabel - Pegex::Tree::Wrap'
8
+ parse_to_tree_wrap(*grammar, *input).yaml.clean == *wrap
9
+ Label = '$BlockLabel - TestAST'
10
+ parse_to_tree_test(*grammar, *input).yaml.clean == *ast
11
+
1
12
  === Part of Pegex Grammar
2
- --- SKIP
3
13
  --- grammar
4
14
  \# This is the Pegex grammar for Pegex grammars!
5
15
  grammar: ( <comment>* <rule_definition> )+ <comment>*
@@ -1,3 +1,14 @@
1
+ %TestML 0.1.0
2
+
3
+ Plan = 56
4
+
5
+ Label = '$BlockLabel - Pegex::Tree'
6
+ parse_to_tree(*grammar, *input).yaml.clean == *tree
7
+ Label = '$BlockLabel - Pegex::Tree::Wrap'
8
+ parse_to_tree_wrap(*grammar, *input).yaml.clean == *wrap
9
+ Label = '$BlockLabel - t::TestAST'
10
+ parse_to_tree_test(*grammar, *input).yaml.clean == *ast
11
+
1
12
  === Single Regex - Single Capture
2
13
  --- grammar
3
14
  a: /x*(y*)z*<EOL>/
@@ -57,13 +68,12 @@ d: /d/
57
68
  --- tree
58
69
  - []
59
70
  - []
60
- --- wrapSKIP
71
+ --- wrap
61
72
  a:
62
73
  - []
63
74
  - []
64
75
 
65
76
  === A subrule
66
- --- SKIP
67
77
  --- grammar
68
78
  a: <b> /(y+)/ <EOL>
69
79
  b: /(x+)/
@@ -109,7 +119,6 @@ a:
109
119
  - zzz
110
120
 
111
121
  === + Modifier
112
- --- SKIP
113
122
  --- grammar
114
123
  a: ( b c )+ <EOL>
115
124
  b: /(x*)/
@@ -186,7 +195,6 @@ a:
186
195
  c: ccc
187
196
 
188
197
  === Assertion not captured
189
- --- SKIP
190
198
  --- grammar
191
199
  a: =x x y EOL
192
200
  x: /(x+)/
@@ -202,7 +210,6 @@ a:
202
210
  - y: yyyy
203
211
 
204
212
  === Empty regex group plus rule
205
- --- SKIP
206
213
  --- grammar
207
214
  a: <b>* <c> <EOL>
208
215
  b: /xxx/
@@ -218,7 +225,6 @@ a:
218
225
  - c: yyy
219
226
 
220
227
  === Rule to Rule to Rule
221
- --- SKIP
222
228
  --- grammar
223
229
  a: <b>
224
230
  b: <c>*
@@ -262,7 +268,6 @@ a:
262
268
  - c: c
263
269
 
264
270
  === Rule with Separator
265
- --- SKIP
266
271
  --- grammar
267
272
  a: <c>* % <d>
268
273
  c: /(c+)/
@@ -388,7 +393,6 @@ a:
388
393
  - b: b
389
394
 
390
395
  === Quantifier on the Separator
391
- --- SKIP
392
396
  --- grammar
393
397
  a: <b>2-4 %% <c>*
394
398
  b: /(b)/
@@ -422,7 +426,6 @@ a:
422
426
  - - b: b
423
427
  - b: b
424
428
 
425
- # TODO - deal with psych null output
426
429
  === False Values
427
430
  --- grammar
428
431
  a: <zero> <empty> <undef>
@@ -447,3 +450,14 @@ a:
447
450
  - b: bb
448
451
  - c: cc
449
452
  - d: dd
453
+
454
+ === 2 + 1
455
+ --- SKIP
456
+ --- grammar
457
+ a: <b>2 b
458
+ b: /(b)/
459
+ --- input: bbb
460
+ --- ast
461
+ - b
462
+ - b
463
+ - b