ghazel-parslet 1.4.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 (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>")