ghazel-parslet 1.4.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. data/HISTORY.txt +195 -0
  2. data/LICENSE +23 -0
  3. data/README +70 -0
  4. data/Rakefile +49 -0
  5. data/example/boolean_algebra.rb +70 -0
  6. data/example/calc.rb +153 -0
  7. data/example/comments.rb +35 -0
  8. data/example/deepest_errors.rb +131 -0
  9. data/example/documentation.rb +18 -0
  10. data/example/email_parser.rb +52 -0
  11. data/example/empty.rb +13 -0
  12. data/example/erb.rb +47 -0
  13. data/example/ignore.rb +33 -0
  14. data/example/ip_address.rb +125 -0
  15. data/example/json.rb +128 -0
  16. data/example/local.rb +34 -0
  17. data/example/mathn.rb +44 -0
  18. data/example/minilisp.rb +94 -0
  19. data/example/modularity.rb +47 -0
  20. data/example/nested_errors.rb +132 -0
  21. data/example/output/boolean_algebra.out +4 -0
  22. data/example/output/calc.out +1 -0
  23. data/example/output/comments.out +8 -0
  24. data/example/output/deepest_errors.out +54 -0
  25. data/example/output/documentation.err +4 -0
  26. data/example/output/documentation.out +1 -0
  27. data/example/output/email_parser.out +2 -0
  28. data/example/output/empty.err +1 -0
  29. data/example/output/erb.out +7 -0
  30. data/example/output/ignore.out +1 -0
  31. data/example/output/ignore_whitespace.out +1 -0
  32. data/example/output/ip_address.out +9 -0
  33. data/example/output/json.out +5 -0
  34. data/example/output/local.out +3 -0
  35. data/example/output/mathn.out +4 -0
  36. data/example/output/minilisp.out +5 -0
  37. data/example/output/modularity.out +0 -0
  38. data/example/output/nested_errors.out +54 -0
  39. data/example/output/parens.out +8 -0
  40. data/example/output/readme.out +1 -0
  41. data/example/output/seasons.out +28 -0
  42. data/example/output/sentence.out +1 -0
  43. data/example/output/simple_xml.out +2 -0
  44. data/example/output/string_parser.out +3 -0
  45. data/example/parens.rb +42 -0
  46. data/example/readme.rb +30 -0
  47. data/example/seasons.rb +46 -0
  48. data/example/sentence.rb +36 -0
  49. data/example/simple.lit +3 -0
  50. data/example/simple_xml.rb +54 -0
  51. data/example/string_parser.rb +77 -0
  52. data/example/test.lit +4 -0
  53. data/lib/parslet.rb +254 -0
  54. data/lib/parslet/atoms.rb +32 -0
  55. data/lib/parslet/atoms/alternative.rb +50 -0
  56. data/lib/parslet/atoms/base.rb +124 -0
  57. data/lib/parslet/atoms/can_flatten.rb +137 -0
  58. data/lib/parslet/atoms/context.rb +94 -0
  59. data/lib/parslet/atoms/dsl.rb +98 -0
  60. data/lib/parslet/atoms/entity.rb +41 -0
  61. data/lib/parslet/atoms/lookahead.rb +49 -0
  62. data/lib/parslet/atoms/named.rb +32 -0
  63. data/lib/parslet/atoms/re.rb +38 -0
  64. data/lib/parslet/atoms/repetition.rb +63 -0
  65. data/lib/parslet/atoms/rule.rb +12 -0
  66. data/lib/parslet/atoms/rule/position.rb +143 -0
  67. data/lib/parslet/atoms/sequence.rb +38 -0
  68. data/lib/parslet/atoms/str.rb +37 -0
  69. data/lib/parslet/atoms/visitor.rb +89 -0
  70. data/lib/parslet/cause.rb +94 -0
  71. data/lib/parslet/convenience.rb +35 -0
  72. data/lib/parslet/error_reporter.rb +7 -0
  73. data/lib/parslet/error_reporter/deepest.rb +95 -0
  74. data/lib/parslet/error_reporter/tree.rb +57 -0
  75. data/lib/parslet/export.rb +162 -0
  76. data/lib/parslet/expression.rb +51 -0
  77. data/lib/parslet/expression/treetop.rb +92 -0
  78. data/lib/parslet/parser.rb +67 -0
  79. data/lib/parslet/pattern.rb +114 -0
  80. data/lib/parslet/pattern/binding.rb +49 -0
  81. data/lib/parslet/rig/rspec.rb +51 -0
  82. data/lib/parslet/slice.rb +101 -0
  83. data/lib/parslet/source.rb +62 -0
  84. data/lib/parslet/source/line_cache.rb +95 -0
  85. data/lib/parslet/transform.rb +236 -0
  86. data/lib/parslet/transform/context.rb +32 -0
  87. metadata +264 -0
@@ -0,0 +1,4 @@
1
+ {:and=>
2
+ {:left=>{:var=>"1"@3},
3
+ :right=>{:or=>{:left=>{:var=>"2"@13}, :right=>{:var=>"3"@21}}}}}
4
+ [["1", "2"], ["1", "3"]]
@@ -0,0 +1 @@
1
+ 123*2 (command line): -> 246
@@ -0,0 +1,8 @@
1
+ [{:exp=>{:a=>"a"@3}},
2
+ {:line=>"// line comment"@7},
3
+ {:exp=>{:a=>"a"@25}},
4
+ {:exp=>{:a=>"a"@27}},
5
+ {:exp=>[{:a=>"a"@29}, {:line=>"// line comment"@31}]},
6
+ {:exp=>[{:a=>"a"@49}, {:multi=>"/* inline comment */"@51}]},
7
+ {:exp=>{:a=>"a"@72}},
8
+ {:multi=>"/* multiline\n comment */"@77}]
@@ -0,0 +1,54 @@
1
+ --------------------------------------------------------------------------------
2
+ . 10 . 20
3
+ 01
4
+ 02 define f()
5
+ 03 @res.name
6
+ 04 end
7
+ 05
8
+ Failed to match sequence (LINE_SEPARATOR? BLOCK LINE_SEPARATOR?) at line 2 char 5.
9
+ `- Expected one of [DEFINE_BLOCK, BEGIN_BLOCK] at line 2 char 5.
10
+ |- Failed to match sequence (define:'define' SPACE name:IDENTIFIER '()' BODY 'end') at line 2 char 15.
11
+ | `- Failed to match sequence (body:((LINE_SEPARATOR (BLOCK / EXPRESSION)){1, }) LINE_SEPARATOR) at line 3 char 11.
12
+ | `- Expected at least 1 of SPACE? (COMMENT? NEWLINE / ';') SPACE? at line 3 char 11.
13
+ | `- Failed to match sequence (SPACE? (COMMENT? NEWLINE / ';') SPACE?) at line 3 char 11.
14
+ | `- Expected one of [COMMENT? NEWLINE, ';'] at line 3 char 11.
15
+ | |- Failed to match sequence (COMMENT? NEWLINE) at line 3 char 11.
16
+ | | `- Expected "()", but got "\n " at line 3 char 16.
17
+ | `- Expected "()", but got "\n " at line 3 char 16.
18
+ `- Failed to match sequence (pre:((type:'concurrent' SPACE)?) begin:'begin' BODY 'end') at line 2 char 5.
19
+ `- Expected "()", but got "\n " at line 3 char 16.
20
+ --------------------------------------------------------------------------------
21
+ . 10 . 20
22
+ 01
23
+ 02 define f()
24
+ 03 begin
25
+ 04 @res.name
26
+ 05 end
27
+ 06 end
28
+ 07
29
+ Failed to match sequence (LINE_SEPARATOR? BLOCK LINE_SEPARATOR?) at line 2 char 5.
30
+ `- Expected one of [DEFINE_BLOCK, BEGIN_BLOCK] at line 2 char 5.
31
+ |- Failed to match sequence (define:'define' SPACE name:IDENTIFIER '()' BODY 'end') at line 2 char 15.
32
+ | `- Failed to match sequence (body:((LINE_SEPARATOR (BLOCK / EXPRESSION)){1, }) LINE_SEPARATOR) at line 2 char 15.
33
+ | `- Expected at least 1 of LINE_SEPARATOR (BLOCK / EXPRESSION) at line 2 char 15.
34
+ | `- Failed to match sequence (LINE_SEPARATOR (BLOCK / EXPRESSION)) at line 3 char 7.
35
+ | `- Expected one of [BLOCK, EXPRESSION] at line 3 char 7.
36
+ | |- Expected one of [DEFINE_BLOCK, BEGIN_BLOCK] at line 3 char 7.
37
+ | | |- Failed to match sequence (define:'define' SPACE name:IDENTIFIER '()' BODY 'end') at line 3 char 7.
38
+ | | | `- Expected "define", but got "begin\n" at line 3 char 7.
39
+ | | `- Failed to match sequence (pre:((type:'concurrent' SPACE)?) begin:'begin' BODY 'end') at line 3 char 12.
40
+ | | `- Failed to match sequence (body:((LINE_SEPARATOR (BLOCK / EXPRESSION)){1, }) LINE_SEPARATOR) at line 4 char 13.
41
+ | | `- Expected at least 1 of SPACE? (COMMENT? NEWLINE / ';') SPACE? at line 4 char 13.
42
+ | | `- Failed to match sequence (SPACE? (COMMENT? NEWLINE / ';') SPACE?) at line 4 char 13.
43
+ | | `- Expected one of [COMMENT? NEWLINE, ';'] at line 4 char 13.
44
+ | | |- Failed to match sequence (COMMENT? NEWLINE) at line 4 char 13.
45
+ | | | `- Expected "()", but got "\n " at line 4 char 18.
46
+ | | `- Expected "()", but got "\n " at line 4 char 18.
47
+ | `- Failed to match sequence (RES_ACTIONS res_field:((':' name:IDENTIFIER)?)) at line 3 char 7.
48
+ | `- Failed to match sequence (resources:REFERENCE res_actions:(res_action:RES_ACTION_OR_LINK{0, })) at line 3 char 7.
49
+ | `- Failed to match sequence ('@'{1, 2} IDENTIFIER) at line 3 char 7.
50
+ | `- Expected at least 1 of '@' at line 3 char 7.
51
+ | `- Expected "()", but got "\n " at line 4 char 18.
52
+ `- Failed to match sequence (pre:((type:'concurrent' SPACE)?) begin:'begin' BODY 'end') at line 2 char 5.
53
+ `- Expected "()", but got "\n " at line 4 char 18.
54
+ --------------------------------------------------------------------------------
@@ -0,0 +1,4 @@
1
+ /Users/kaspar/git_work/own/parslet/lib/parslet/atoms/base.rb:326:in `parse_failed': Don't know what to do with bbbb at line 1 char 1. (Parslet::ParseFailed)
2
+ from /Users/kaspar/git_work/own/parslet/lib/parslet/atoms/base.rb:55:in `parse'
3
+ from example/documentation.rb:13:in `parse'
4
+ from example/documentation.rb:18:in `<main>'
@@ -0,0 +1 @@
1
+ "aaaa"@0
@@ -0,0 +1,2 @@
1
+ since you haven't specified any EMAIL_ADDR, for testing purposes we're using a.b.c.d@gmail.com
2
+ "a.b.c.d@gmail.com"
@@ -0,0 +1 @@
1
+ example/empty.rb:13:in `<main>': rule(:empty) { ... } returns nil. Still not implemented, but already used? (NotImplementedError)
@@ -0,0 +1,7 @@
1
+ {:text=>[{:text=>"The value of x is "@0}, {:expression=>{:ruby=>" x "@21}}, {:text=>"."@26}]}
2
+ {:text=>[{:code=>{:ruby=>" 1 + 2 "@2}}]}
3
+ {:text=>[{:comment=>{:ruby=>" commented "@3}}]}
4
+ The not printed result of "a = 2".
5
+ The not printed non-evaluated comment "a = 1", see the value of a below.
6
+ The nicely printed result.
7
+ The value of a is 2, and b is 3.
@@ -0,0 +1 @@
1
+ "ac"@0
@@ -0,0 +1 @@
1
+ [{:a=>"a"@0}, {:a=>"a"@1}, {:a=>"a"@5}, {:a=>"a"@7}]
@@ -0,0 +1,9 @@
1
+ 0.0.0.0 -> {:ipv4=>"0.0.0.0"@0}
2
+ 255.255.255.255 -> {:ipv4=>"255.255.255.255"@0}
3
+ 255.255.255 -> Failed: Expected one of [IPV4, IPV6] at line 1 char 1.
4
+ 1:2:3:4:5:6:7:8 -> {:ipv6=>"1:2:3:4:5:6:7:8"@0}
5
+ 12AD:34FC:A453:1922:: -> {:ipv6=>"12AD:34FC:A453:1922::"@0}
6
+ 12AD::34FC -> {:ipv6=>"12AD::34FC"@0}
7
+ 12AD:: -> {:ipv6=>"12AD::"@0}
8
+ :: -> {:ipv6=>"::"@0}
9
+ 1:2 -> Failed: Expected one of [IPV4, IPV6] at line 1 char 1.
@@ -0,0 +1,5 @@
1
+
2
+ {:array=>[{:number=>"1"@5}, {:number=>"2"@8}, {:number=>"3"@11}, {:null=>"null"@14}, {:string=>"asdfasdf asdfds"@25}, {:object=>{:entry=>{:key=>{:string=>"a"@46}, :val=>{:number=>"-1.2"@50}}}}, {:object=>[{:entry=>{:key=>{:string=>"b"@61}, :val=>{:true=>"true"@65}}}, {:entry=>{:key=>{:string=>"c"@72}, :val=>{:false=>"false"@76}}}]}, {:number=>"0.1e24"@89}, {:true=>"true"@97}, {:false=>"false"@103}, {:array=>{:number=>"1"@112}}]}
3
+
4
+ [1, 2, 3, nil, "asdfasdf asdfds", {"a"=>-1.2}, {"b"=>true, "c"=>false}, 1.0e+23, true, false, [1]]
5
+
@@ -0,0 +1,3 @@
1
+ {:e=>"a"@0, :rec=>{:e=>"a"@1, :rec=>{:e=>"a"@2, :rec=>{:e=>"a"@3, :rec=>nil}}}}
2
+ e2:'aa' !. / e1:'a' rec:B
3
+ {:e1=>"a"@0, :rec=>{:e1=>"a"@1, :rec=>{:e2=>"aa"@2}}}
@@ -0,0 +1,4 @@
1
+ it terminates before we require mathn
2
+ requiring mathn now
3
+ and trying again (will hang without the fix)
4
+ okay!
@@ -0,0 +1,5 @@
1
+ [:define,
2
+ :test,
3
+ [:lambda,
4
+ [],
5
+ [:begin, [:display, "something"@54], [:display, 1], [:display, 3.08]]]]
File without changes
@@ -0,0 +1,54 @@
1
+ --------------------------------------------------------------------------------
2
+ . 10 . 20
3
+ 01
4
+ 02 define f()
5
+ 03 @res.name
6
+ 04 end
7
+ 05
8
+ Failed to match sequence (LINE_SEPARATOR? BLOCK LINE_SEPARATOR?) at line 2 char 5.
9
+ `- Expected one of [DEFINE_BLOCK, BEGIN_BLOCK] at line 2 char 5.
10
+ |- Failed to match sequence (define:'define' SPACE name:IDENTIFIER '()' BODY 'end') at line 2 char 15.
11
+ | `- Failed to match sequence (body:((LINE_SEPARATOR (BLOCK / EXPRESSION)){1, }) LINE_SEPARATOR) at line 3 char 11.
12
+ | `- Expected at least 1 of SPACE? (COMMENT? NEWLINE / ';') SPACE? at line 3 char 11.
13
+ | `- Failed to match sequence (SPACE? (COMMENT? NEWLINE / ';') SPACE?) at line 3 char 11.
14
+ | `- Expected one of [COMMENT? NEWLINE, ';'] at line 3 char 11.
15
+ | |- Failed to match sequence (COMMENT? NEWLINE) at line 3 char 11.
16
+ | | `- Failed to match [\\r\\n] at line 3 char 11.
17
+ | `- Expected ";", but got "." at line 3 char 11.
18
+ `- Failed to match sequence (pre:((type:'concurrent' SPACE)?) begin:'begin' BODY 'end') at line 2 char 5.
19
+ `- Expected "begin", but got "defin" at line 2 char 5.
20
+ --------------------------------------------------------------------------------
21
+ . 10 . 20
22
+ 01
23
+ 02 define f()
24
+ 03 begin
25
+ 04 @res.name
26
+ 05 end
27
+ 06 end
28
+ 07
29
+ Failed to match sequence (LINE_SEPARATOR? BLOCK LINE_SEPARATOR?) at line 2 char 5.
30
+ `- Expected one of [DEFINE_BLOCK, BEGIN_BLOCK] at line 2 char 5.
31
+ |- Failed to match sequence (define:'define' SPACE name:IDENTIFIER '()' BODY 'end') at line 2 char 15.
32
+ | `- Failed to match sequence (body:((LINE_SEPARATOR (BLOCK / EXPRESSION)){1, }) LINE_SEPARATOR) at line 2 char 15.
33
+ | `- Expected at least 1 of LINE_SEPARATOR (BLOCK / EXPRESSION) at line 2 char 15.
34
+ | `- Failed to match sequence (LINE_SEPARATOR (BLOCK / EXPRESSION)) at line 3 char 7.
35
+ | `- Expected one of [BLOCK, EXPRESSION] at line 3 char 7.
36
+ | |- Expected one of [DEFINE_BLOCK, BEGIN_BLOCK] at line 3 char 7.
37
+ | | |- Failed to match sequence (define:'define' SPACE name:IDENTIFIER '()' BODY 'end') at line 3 char 7.
38
+ | | | `- Expected "define", but got "begin\n" at line 3 char 7.
39
+ | | `- Failed to match sequence (pre:((type:'concurrent' SPACE)?) begin:'begin' BODY 'end') at line 3 char 12.
40
+ | | `- Failed to match sequence (body:((LINE_SEPARATOR (BLOCK / EXPRESSION)){1, }) LINE_SEPARATOR) at line 4 char 13.
41
+ | | `- Expected at least 1 of SPACE? (COMMENT? NEWLINE / ';') SPACE? at line 4 char 13.
42
+ | | `- Failed to match sequence (SPACE? (COMMENT? NEWLINE / ';') SPACE?) at line 4 char 13.
43
+ | | `- Expected one of [COMMENT? NEWLINE, ';'] at line 4 char 13.
44
+ | | |- Failed to match sequence (COMMENT? NEWLINE) at line 4 char 13.
45
+ | | | `- Failed to match [\\r\\n] at line 4 char 13.
46
+ | | `- Expected ";", but got "." at line 4 char 13.
47
+ | `- Failed to match sequence (RES_ACTIONS res_field:((':' name:IDENTIFIER)?)) at line 3 char 7.
48
+ | `- Failed to match sequence (resources:REFERENCE res_actions:(res_action:RES_ACTION_OR_LINK{0, })) at line 3 char 7.
49
+ | `- Failed to match sequence ('@'{1, 2} IDENTIFIER) at line 3 char 7.
50
+ | `- Expected at least 1 of '@' at line 3 char 7.
51
+ | `- Expected "@", but got "b" at line 3 char 7.
52
+ `- Failed to match sequence (pre:((type:'concurrent' SPACE)?) begin:'begin' BODY 'end') at line 2 char 5.
53
+ `- Expected "begin", but got "defin" at line 2 char 5.
54
+ --------------------------------------------------------------------------------
@@ -0,0 +1,8 @@
1
+ (): {:l=>"("@0, :m=>nil, :r=>")"@1} (1 parens)
2
+
3
+ (()): {:l=>"("@0, :m=>{:l=>"("@1, :m=>nil, :r=>")"@2}, :r=>")"@3} (2 parens)
4
+
5
+ ((((())))): {:l=>"("@0, :m=>{:l=>"("@1, :m=>{:l=>"("@2, :m=>{:l=>"("@3, :m=>{:l=>"("@4, :m=>nil, :r=>")"@5}, :r=>")"@6}, :r=>")"@7}, :r=>")"@8}, :r=>")"@9} (5 parens)
6
+
7
+ ((()): Failed to match sequence (l:'(' m:(BALANCED?) r:')') at line 1 char 6.
8
+
@@ -0,0 +1 @@
1
+ String contents: This is a \"String\" in which you can escape stuff
@@ -0,0 +1,28 @@
1
+ "And when Spring comes"
2
+ {:bud=>{:stem=>[{:branch=>:leaf}]}}
3
+
4
+ "And when Summer comes"
5
+ {:bud=>{:stem=>[{:branch=>[:leaf, :flower]}]}}
6
+
7
+ "And when Fall comes"
8
+ Fruit!
9
+ Falling Leaves!
10
+ {:bud=>{:stem=>[{:branch=>[]}]}}
11
+
12
+ "And when Winter comes"
13
+ {:bud=>{:stem=>[]}}
14
+
15
+ "And when Spring comes"
16
+ {:bud=>{:stem=>[{:branch=>:leaf}]}}
17
+
18
+ "And when Summer comes"
19
+ {:bud=>{:stem=>[{:branch=>[:leaf, :flower]}]}}
20
+
21
+ "And when Fall comes"
22
+ Fruit!
23
+ Falling Leaves!
24
+ {:bud=>{:stem=>[{:branch=>[]}]}}
25
+
26
+ "And when Winter comes"
27
+ {:bud=>{:stem=>[]}}
28
+
@@ -0,0 +1 @@
1
+ ["RubyKaigi2009のテーマは、「変わる/変える」です。", " 前回のRubyKaigi2008のテーマであった「多様性」の言葉の通り、 2008年はRubyそのものに関しても、またRubyの活躍する舞台に関しても、 ますます多様化が進みつつあります。", "RubyKaigi2008は、そのような Rubyの生態系をあらためて認識する場となりました。", " しかし、こうした多様化が進む中、異なる者同士が単純に距離を 置いたままでは、その違いを認識したところであまり意味がありません。", " 異なる実装、異なる思想、異なる背景といった、様々な多様性を理解しつつ、 すり合わせるべきものをすり合わせ、変えていくべきところを 変えていくことが、豊かな未来へとつながる道に違いありません。"]
@@ -0,0 +1,2 @@
1
+ "verified"
2
+ {:o=>{:name=>"b"@1}, :i=>"verified", :c=>{:name=>"a"@33}}
@@ -0,0 +1,3 @@
1
+ [#<struct IntLit text="123"@0>,
2
+ #<struct IntLit text="12345"@4>,
3
+ #<struct StringLit text=" Some String with \\\"escapes\\\""@11>]
@@ -0,0 +1,42 @@
1
+ # A small example that demonstrates the power of tree pattern matching. Also
2
+ # uses '.as(:name)' to construct a tree that can reliably be matched
3
+ # afterwards.
4
+
5
+ $:.unshift File.dirname(__FILE__) + "/../lib"
6
+
7
+ require 'pp'
8
+ require 'parslet'
9
+
10
+ module LISP # as in 'lots of insipid and stupid parenthesis'
11
+ class Parser < Parslet::Parser
12
+ rule(:balanced) {
13
+ str('(').as(:l) >> balanced.maybe.as(:m) >> str(')').as(:r)
14
+ }
15
+
16
+ root(:balanced)
17
+ end
18
+
19
+ class Transform < Parslet::Transform
20
+ rule(:l => '(', :m => simple(:x), :r => ')') {
21
+ # innermost :m will contain nil
22
+ x.nil? ? 1 : x+1
23
+ }
24
+ end
25
+ end
26
+
27
+ parser = LISP::Parser.new
28
+ transform = LISP::Transform.new
29
+ %w!
30
+ ()
31
+ (())
32
+ ((((()))))
33
+ ((())
34
+ !.each do |pexp|
35
+ begin
36
+ result = parser.parse(pexp)
37
+ puts "#{"%20s"%pexp}: #{result.inspect} (#{transform.apply(result)} parens)"
38
+ rescue Parslet::ParseFailed => m
39
+ puts "#{"%20s"%pexp}: #{m}"
40
+ end
41
+ puts
42
+ end
@@ -0,0 +1,30 @@
1
+ # The example from the readme. With this, I am making sure that the readme
2
+ # 'works'. Is this too messy?
3
+
4
+ $:.unshift File.dirname(__FILE__) + "/../lib"
5
+
6
+ # cut here -------------------------------------------------------------------
7
+ require 'parslet'
8
+ include Parslet
9
+
10
+ # Constructs a parser using a Parser Expression Grammar like DSL:
11
+ parser = str('"') >>
12
+ (
13
+ str('\\') >> any |
14
+ str('"').absent? >> any
15
+ ).repeat.as(:string) >>
16
+ str('"')
17
+
18
+ # Parse the string and capture parts of the interpretation (:string above)
19
+ tree = parser.parse('"This is a \\"String\\" in which you can escape stuff"')
20
+
21
+ tree # => {:string=>"This is a \\\"String\\\" in which you can escape stuff"}
22
+
23
+ # Here's how you can grab results from that tree:
24
+
25
+ transform = Parslet::Transform.new do
26
+ rule(:string => simple(:x)) {
27
+ puts "String contents: #{x}" }
28
+ end
29
+ transform.apply(tree)
30
+
@@ -0,0 +1,46 @@
1
+ $:.unshift File.dirname(__FILE__) + "/../lib"
2
+
3
+ require 'parslet'
4
+ require 'pp'
5
+
6
+ tree = {:bud => {:stem => []}}
7
+
8
+ class Spring < Parslet::Transform
9
+ rule(:stem => sequence(:branches)) {
10
+ {:stem => (branches + [{:branch => :leaf}])}
11
+ }
12
+ end
13
+ class Summer < Parslet::Transform
14
+ rule(:stem => subtree(:branches)) {
15
+ new_branches = branches.map { |b| {:branch => [:leaf, :flower]} }
16
+ {:stem => new_branches}
17
+ }
18
+ end
19
+ class Fall < Parslet::Transform
20
+ rule(:branch => sequence(:x)) {
21
+ x.each { |e| puts "Fruit!" if e==:flower }
22
+ x.each { |e| puts "Falling Leaves!" if e==:leaf }
23
+ {:branch => []}
24
+ }
25
+ end
26
+ class Winter < Parslet::Transform
27
+ rule(:stem => subtree(:x)) {
28
+ {:stem => []}
29
+ }
30
+ end
31
+
32
+ def do_seasons(tree)
33
+ [Spring, Summer, Fall, Winter].each do |season|
34
+ p "And when #{season} comes"
35
+ tree = season.new.apply(tree)
36
+ pp tree
37
+ puts
38
+ end
39
+ tree
40
+ end
41
+
42
+ # What marvel of life!
43
+ tree = do_seasons(tree)
44
+ tree = do_seasons(tree)
45
+
46
+
@@ -0,0 +1,36 @@
1
+ # encoding: UTF-8
2
+
3
+ # A small example contributed by John Mettraux (jmettraux) that demonstrates
4
+ # working with Unicode. This only works on Ruby 1.9.
5
+
6
+ $:.unshift File.dirname(__FILE__) + "/../lib"
7
+
8
+ require 'parslet'
9
+
10
+ class Parser < Parslet::Parser
11
+ rule(:sentence) { (match('[^。]').repeat(1) >> str("。")).as(:sentence) }
12
+ rule(:sentences) { sentence.repeat }
13
+ root(:sentences)
14
+ end
15
+
16
+ class Transformer < Parslet::Transform
17
+ rule(:sentence => simple(:sen)) { sen.to_s }
18
+ end
19
+
20
+ string =
21
+ "RubyKaigi2009のテーマは、「変わる/変える」です。 前回の" +
22
+ "RubyKaigi2008のテーマであった「多様性」の言葉の通り、 " +
23
+ "2008年はRubyそのものに関しても、またRubyの活躍する舞台に関しても、 " +
24
+ "ますます多様化が進みつつあります。RubyKaigi2008は、そのような " +
25
+ "Rubyの生態系をあらためて認識する場となりました。 しかし、" +
26
+ "こうした多様化が進む中、異なる者同士が単純に距離を 置いたままでは、" +
27
+ "その違いを認識したところであまり意味がありません。 異なる実装、" +
28
+ "異なる思想、異なる背景といった、様々な多様性を理解しつつ、 " +
29
+ "すり合わせるべきものをすり合わせ、変えていくべきところを " +
30
+ "変えていくことが、豊かな未来へとつながる道に違いありません。"
31
+
32
+ parser = Parser.new
33
+ transformer = Transformer.new
34
+
35
+ tree = parser.parse(string)
36
+ p transformer.apply(tree)
@@ -0,0 +1,3 @@
1
+ 123
2
+ 12345
3
+ " Some String with \"escapes\""
@@ -0,0 +1,54 @@
1
+ # A simple xml parser. It is simple in the respect as that it doesn't address
2
+ # any of the complexities of XML. This is ruby 1.9.
3
+
4
+ $:.unshift File.dirname(__FILE__) + "/../lib"
5
+
6
+ require 'pp'
7
+ require 'parslet'
8
+
9
+ class XML < Parslet::Parser
10
+ root :document
11
+
12
+ rule(:document) {
13
+ tag(close: false).as(:o) >> document.as(:i) >> tag(close: true).as(:c) |
14
+ text
15
+ }
16
+
17
+ # Perhaps we could have some syntax sugar to make this more easy?
18
+ #
19
+ def tag(opts={})
20
+ close = opts[:close] || false
21
+
22
+ parslet = str('<')
23
+ parslet = parslet >> str('/') if close
24
+ parslet = parslet >> (str('>').absent? >> match("[a-zA-Z]")).repeat(1).as(:name)
25
+ parslet = parslet >> str('>')
26
+
27
+ parslet
28
+ end
29
+
30
+ rule(:text) {
31
+ match('[^<>]').repeat(0)
32
+ }
33
+ end
34
+
35
+ def check(xml)
36
+ r = XML.new.parse(xml)
37
+
38
+ # We'll validate the tree by reducing valid pairs of tags into simply the
39
+ # string "verified". If the transformation ends on a string, then the
40
+ # document was 'valid'.
41
+ #
42
+ t = Parslet::Transform.new do
43
+ rule(
44
+ o: {name: simple(:tag)},
45
+ c: {name: simple(:tag)},
46
+ i: simple(:t)
47
+ ) { 'verified' }
48
+ end
49
+
50
+ t.apply(r)
51
+ end
52
+
53
+ pp check("<a><b>some text in the tags</b></a>")
54
+ pp check("<b><b>some text in the tags</b></a>")