sgf_parser 0.1.0

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 (53) hide show
  1. data/.irbrc +3 -0
  2. data/.rvmrc +4 -0
  3. data/Gemfile +10 -0
  4. data/Gemfile.lock +17 -0
  5. data/LICENSE +20 -0
  6. data/README.textile +27 -0
  7. data/Rakefile +20 -0
  8. data/TODO +0 -0
  9. data/VERSION +1 -0
  10. data/bin/sgf +28 -0
  11. data/bin/stm2dot +18 -0
  12. data/doc/sgf_state_machine.dot +58 -0
  13. data/doc/sgf_state_machine.svg +269 -0
  14. data/lib/sgf.rb +15 -0
  15. data/lib/sgf/binary_file_error.rb +4 -0
  16. data/lib/sgf/debugger.rb +15 -0
  17. data/lib/sgf/default_event_listener.rb +37 -0
  18. data/lib/sgf/model/constants.rb +19 -0
  19. data/lib/sgf/model/event_listener.rb +72 -0
  20. data/lib/sgf/model/game.rb +52 -0
  21. data/lib/sgf/model/label.rb +12 -0
  22. data/lib/sgf/model/node.rb +115 -0
  23. data/lib/sgf/model/property_handler.rb +51 -0
  24. data/lib/sgf/more/state_machine_presenter.rb +43 -0
  25. data/lib/sgf/more/stm_dot_converter.rb +139 -0
  26. data/lib/sgf/parse_error.rb +25 -0
  27. data/lib/sgf/parser.rb +56 -0
  28. data/lib/sgf/renderer.rb +25 -0
  29. data/lib/sgf/sgf_helper.rb +55 -0
  30. data/lib/sgf/sgf_state_machine.rb +174 -0
  31. data/lib/sgf/state_machine.rb +76 -0
  32. data/sgf_parser.gemspec +95 -0
  33. data/spec/fixtures/2009-11-01-1.sgf +24 -0
  34. data/spec/fixtures/2009-11-01-2.sgf +23 -0
  35. data/spec/fixtures/chinese_gb.sgf +9 -0
  36. data/spec/fixtures/chinese_utf.sgf +9 -0
  37. data/spec/fixtures/example.sgf +18 -0
  38. data/spec/fixtures/good.sgf +55 -0
  39. data/spec/fixtures/good1.sgf +167 -0
  40. data/spec/fixtures/kgs.sgf +723 -0
  41. data/spec/fixtures/test.png +0 -0
  42. data/spec/sgf/model/event_listener_spec.rb +97 -0
  43. data/spec/sgf/model/game_spec.rb +29 -0
  44. data/spec/sgf/model/node_spec.rb +84 -0
  45. data/spec/sgf/more/state_machine_presenter_spec.rb +29 -0
  46. data/spec/sgf/parse_error_spec.rb +10 -0
  47. data/spec/sgf/parser_spec.rb +210 -0
  48. data/spec/sgf/sgf_helper_spec.rb +68 -0
  49. data/spec/sgf/sgf_state_machine_spec.rb +166 -0
  50. data/spec/sgf/state_machine_spec.rb +137 -0
  51. data/spec/spec.opts +4 -0
  52. data/spec/spec_helper.rb +47 -0
  53. metadata +150 -0
data/.irbrc ADDED
@@ -0,0 +1,3 @@
1
+ $:.push(File.dirname(__FILE__) + '/lib')
2
+
3
+ require 'sgf'
data/.rvmrc ADDED
@@ -0,0 +1,4 @@
1
+ export rvm_gemset_create_on_use_flag=1
2
+
3
+ rvm use 1.8.7@sgf_parser
4
+
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source "http://rubygems.org"
2
+
3
+ group :development do
4
+ gem "jeweler"
5
+ end
6
+
7
+ group :test do
8
+ gem "rspec", "~>1.3.0"
9
+ end
10
+
data/Gemfile.lock ADDED
@@ -0,0 +1,17 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ git (1.2.5)
5
+ jeweler (1.6.4)
6
+ bundler (~> 1.0)
7
+ git (>= 1.2.5)
8
+ rake
9
+ rake (0.9.2.2)
10
+ rspec (1.3.2)
11
+
12
+ PLATFORMS
13
+ ruby
14
+
15
+ DEPENDENCIES
16
+ jeweler
17
+ rspec (~> 1.3.0)
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 YOUR NAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1,27 @@
1
+ A SGF parser gem
2
+
3
+
4
+ NOTES
5
+
6
+ (Below are tested on MAC OS X 10.5.8)
7
+ Use 'file -i XXX.sgf' to check file encoding
8
+ Use 'iconv -f gb18030 XXX.sgf' to convert GB2312/GB18030 to UTF16
9
+
10
+ Benchmark
11
+
12
+ time for i in {1..1000}; do bin/sgf spec/fixtures/2009-11-01-1.sgf; done
13
+
14
+ Fri Jan 8 08:49:18 EST 2010
15
+ real 0m26.221s
16
+ user 0m20.404s
17
+ sys 0m5.262s
18
+
19
+ Fri Jan 8 09:55:02 EST 2010
20
+ real 0m24.453s
21
+ user 0m18.758s
22
+ sys 0m5.080s
23
+
24
+ Sun Jan 10 10:01:09 EST 2010
25
+ real 0m18.660s
26
+ user 0m12.994s
27
+ sys 0m5.099s
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gem|
4
+ gem.name = "sgf_parser"
5
+ gem.summary = %Q{A SGF parser}
6
+ gem.description = %Q{A simple SGF parser}
7
+ gem.email = "gcao99@gmail.com"
8
+ gem.homepage = "http://github.com/gcao/discuz_robot"
9
+ gem.authors = ["Guoliang Cao"]
10
+ gem.add_development_dependency "rspec", "~> 1.3.0"
11
+ end
12
+ Jeweler::GemcutterTasks.new
13
+ rescue LoadError
14
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
15
+ end
16
+
17
+ desc "visualize SGF state machine"
18
+ task :vst do
19
+ system("bin/stm2dot && dot -T svg -o doc/sgf_state_machine.svg doc/sgf_state_machine.dot")
20
+ end
data/TODO ADDED
File without changes
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/bin/sgf ADDED
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ if ARGV.size == 0
4
+ puts <<-USAGE
5
+ Usage:
6
+ sgf <DIRECTORY_OR_FILE>
7
+ USAGE
8
+ exit 1
9
+ end
10
+
11
+ sgf_rb = File.expand_path(File.dirname(__FILE__) + '/../lib/sgf.rb')
12
+ if File.exists?(sgf_rb)
13
+ require sgf_rb
14
+ else
15
+ require 'rubygems'
16
+ require 'sgf'
17
+ end
18
+
19
+ filename = ARGV[0]
20
+ debug = ENV["DEBUG"] == "true"
21
+
22
+ if File.directory?(filename)
23
+ Dir["#{filename}/**/*"].each do |file|
24
+ SGF::Parser.parse_file(file, debug)
25
+ end
26
+ else
27
+ SGF::Parser.parse_file(filename, debug)
28
+ end
data/bin/stm2dot ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ dot_file = File.expand_path(File.dirname(__FILE__) + "/../doc/sgf_state_machine.dot")
4
+ dot_file = ARGV[0] if ARGV.size > 0
5
+
6
+ sgf_rb = File.expand_path(File.dirname(__FILE__) + '/../lib/sgf.rb')
7
+ if File.exists?(sgf_rb)
8
+ require sgf_rb
9
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/sgf/more/stm_dot_converter.rb')
10
+ else
11
+ require 'rubygems'
12
+ require 'sgf'
13
+ require 'sgf/more/stm_dot_converter'
14
+ end
15
+
16
+ File.open(dot_file, 'w') do |f|
17
+ f.print SGF::More::StmDotConverter.new.process(SGF::SGFStateMachine.new)
18
+ end
@@ -0,0 +1,58 @@
1
+ digraph SGF_STATE_MACHINE{
2
+ {rank = same; begin;}
3
+ {rank = same; game_begin;}
4
+ {rank = same; var_begin game_node;}
5
+ {rank = same; prop_name_begin;}
6
+ {rank = same; prop_name;}
7
+ {rank = same; value_begin;}
8
+ {rank = same; value value_escape;}
9
+ {rank = same; value_end;}
10
+ {rank = same; var_end;}
11
+ {rank = same; game_end invalid;}
12
+ begin[style = "filled",shape = "circle",fillcolor = "#44ff44"];
13
+ value[];
14
+ value_escape[];
15
+ value -> value_escape[label="\\"];
16
+ value -> value[label="[^\]]"];
17
+ value_end[];
18
+ value -> value_end[label="\]", weight=100];
19
+ game_node[];
20
+ value_end -> game_node[label=";"];
21
+ var_begin[];
22
+ value_end -> var_begin[label="\("];
23
+ prop_name_begin[];
24
+ value_end -> prop_name_begin[label="[a-zA-Z]"];
25
+ value_begin[];
26
+ value_end -> value_begin[label="\["];
27
+ var_end[];
28
+ value_end -> var_end[label="\)", weight=100];
29
+ invalid[style = "filled",label = "error",shape = "octagon",fillcolor = "#ff4444"];
30
+ value_end -> invalid[color="#FFBBBB", weight=-100];
31
+ var_end -> game_node[label=";", weight=90];
32
+ var_end -> var_begin[label="\("];
33
+ game_end[style = "filled",label = "end",shape = "doublecircle",fillcolor = "#44ff44"];
34
+ var_end -> game_end[label="EOS", weight=100];
35
+ var_end -> var_end[label="\)"];
36
+ var_end -> invalid[color="#FFBBBB", weight=-100];
37
+ value_begin -> value[label="[^\]]", weight=100];
38
+ value_begin -> value_escape[label="\\"];
39
+ value_begin -> value_end[label="\]"];
40
+ game_begin[];
41
+ begin -> game_begin[label="\(", weight=100];
42
+ begin -> invalid[color="#FFBBBB", weight=-100];
43
+ game_node -> var_begin[label="\("];
44
+ game_node -> prop_name_begin[label="[a-zA-Z]", weight=100];
45
+ game_node -> var_end[label="\)"];
46
+ game_node -> invalid[color="#FFBBBB", weight=-100];
47
+ prop_name[];
48
+ prop_name_begin -> prop_name[label="[a-zA-Z]", weight=100];
49
+ prop_name_begin -> value_begin[label="\["];
50
+ prop_name_begin -> invalid[color="#FFBBBB", weight=-100];
51
+ game_begin -> game_node[label=";", weight=100];
52
+ game_begin -> invalid[color="#FFBBBB", weight=-100];
53
+ value_escape -> value[label="."];
54
+ var_begin -> game_node[label=";"];
55
+ var_begin -> invalid[color="#FFBBBB", weight=-100];
56
+ prop_name -> value_begin[label="\[", weight=100];
57
+ prop_name -> invalid[color="#FFBBBB", weight=-100];
58
+ }
@@ -0,0 +1,269 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
3
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
4
+ <!-- Generated by graphviz version 2.24.0 (20090616.2323)
5
+ -->
6
+ <!-- Title: SGF_STATE_MACHINE Pages: 1 -->
7
+ <svg width="879pt" height="864pt"
8
+ viewBox="0.00 0.00 879.38 864.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
9
+ <g id="graph1" class="graph" transform="scale(1 1) rotate(0) translate(4 860)">
10
+ <title>SGF_STATE_MACHINE</title>
11
+ <polygon fill="white" stroke="white" points="-4,5 -4,-860 876.382,-860 876.382,5 -4,5"/>
12
+ <!-- begin -->
13
+ <g id="node2" class="node"><title>begin</title>
14
+ <ellipse fill="#44ff44" stroke="black" cx="174" cy="-825" rx="29.8234" ry="30.3205"/>
15
+ <text text-anchor="middle" x="174" y="-819.4" font-family="Times,serif" font-size="14.00">begin</text>
16
+ </g>
17
+ <!-- game_begin -->
18
+ <g id="node4" class="node"><title>game_begin</title>
19
+ <ellipse fill="none" stroke="black" cx="174" cy="-726" rx="54.9558" ry="18"/>
20
+ <text text-anchor="middle" x="174" y="-720.4" font-family="Times,serif" font-size="14.00">game_begin</text>
21
+ </g>
22
+ <!-- begin&#45;&gt;game_begin -->
23
+ <g id="edge46" class="edge"><title>begin&#45;&gt;game_begin</title>
24
+ <path fill="none" stroke="black" d="M174,-794.489C174,-781.746 174,-767.024 174,-754.502"/>
25
+ <polygon fill="black" stroke="black" points="177.5,-754.17 174,-744.17 170.5,-754.17 177.5,-754.17"/>
26
+ <text text-anchor="middle" x="176.5" y="-763.4" font-family="Times,serif" font-size="14.00">(</text>
27
+ </g>
28
+ <!-- invalid -->
29
+ <g id="node23" class="node"><title>invalid</title>
30
+ <polygon fill="#ff4444" stroke="black" points="60.0837,-20.5442 60.0837,-35.4558 42.4611,-46 17.5389,-46 -0.0837396,-35.4558 -0.0837396,-20.5442 17.5389,-10 42.4611,-10 60.0837,-20.5442"/>
31
+ <text text-anchor="middle" x="30" y="-22.4" font-family="Times,serif" font-size="14.00">error</text>
32
+ </g>
33
+ <!-- begin&#45;&gt;invalid -->
34
+ <g id="edge48" class="edge"><title>begin&#45;&gt;invalid</title>
35
+ <path fill="none" stroke="#ffbbbb" d="M204.014,-820.483C314.092,-803.369 693.77,-739.341 781,-658 915.865,-532.24 870.516,-425.895 830,-246 824.5,-221.58 827.277,-213.22 814,-192 774.054,-128.158 740.303,-127.064 668,-106 440.842,-39.8213 371.479,-94.3096 138,-56 114.346,-52.1188 88.3239,-45.4471 67.7504,-39.5896"/>
36
+ <polygon fill="#ffbbbb" stroke="#ffbbbb" points="68.7019,-36.2214 58.1226,-36.7953 66.7507,-42.944 68.7019,-36.2214"/>
37
+ </g>
38
+ <!-- game_node -->
39
+ <g id="node7" class="node"><title>game_node</title>
40
+ <ellipse fill="none" stroke="black" cx="174" cy="-640" rx="51.9298" ry="18"/>
41
+ <text text-anchor="middle" x="174" y="-634.4" font-family="Times,serif" font-size="14.00">game_node</text>
42
+ </g>
43
+ <!-- game_begin&#45;&gt;game_node -->
44
+ <g id="edge64" class="edge"><title>game_begin&#45;&gt;game_node</title>
45
+ <path fill="none" stroke="black" d="M174,-707.762C174,-696.36 174,-681.434 174,-668.494"/>
46
+ <polygon fill="black" stroke="black" points="177.5,-668.212 174,-658.212 170.5,-668.212 177.5,-668.212"/>
47
+ <text text-anchor="middle" x="176.5" y="-677.4" font-family="Times,serif" font-size="14.00">;</text>
48
+ </g>
49
+ <!-- game_begin&#45;&gt;invalid -->
50
+ <g id="edge66" class="edge"><title>game_begin&#45;&gt;invalid</title>
51
+ <path fill="none" stroke="#ffbbbb" d="M189.034,-708.181C199.923,-696.687 215.717,-682.68 233,-676 286.925,-655.158 705.112,-690.388 753,-658 787.614,-634.589 781.991,-612.805 791,-572 803.512,-515.326 855.404,-275.074 792,-192 701.939,-73.9992 283.256,-86.5902 138,-56 114.975,-51.1511 89.4837,-44.5993 69.0509,-39.0525"/>
52
+ <polygon fill="#ffbbbb" stroke="#ffbbbb" points="69.7337,-35.6106 59.164,-36.3403 67.8818,-42.3612 69.7337,-35.6106"/>
53
+ </g>
54
+ <!-- var_begin -->
55
+ <g id="node6" class="node"><title>var_begin</title>
56
+ <ellipse fill="none" stroke="black" cx="699" cy="-640" rx="44.9809" ry="18"/>
57
+ <text text-anchor="middle" x="699" y="-634.4" font-family="Times,serif" font-size="14.00">var_begin</text>
58
+ </g>
59
+ <!-- var_begin&#45;&gt;game_node -->
60
+ <g id="edge70" class="edge"><title>var_begin&#45;&gt;game_node</title>
61
+ <path fill="none" stroke="black" d="M654.652,-635.933C603.645,-631.475 517.36,-624.611 443,-622 370.931,-619.469 288.175,-626.505 233.701,-632.508"/>
62
+ <polygon fill="black" stroke="black" points="233.076,-629.056 223.531,-633.653 233.86,-636.012 233.076,-629.056"/>
63
+ <text text-anchor="middle" x="440" y="-623.4" font-family="Times,serif" font-size="14.00">;</text>
64
+ </g>
65
+ <!-- var_begin&#45;&gt;invalid -->
66
+ <g id="edge72" class="edge"><title>var_begin&#45;&gt;invalid</title>
67
+ <path fill="none" stroke="#ffbbbb" d="M704.97,-622.028C728.252,-548.187 804.43,-267.018 653,-160 630.845,-144.342 196.1,-95.4045 170,-88 131.769,-77.1539 90.1783,-58.3652 62.3473,-44.6968"/>
68
+ <polygon fill="#ffbbbb" stroke="#ffbbbb" points="63.6171,-41.4193 53.1051,-40.0971 60.4982,-47.6861 63.6171,-41.4193"/>
69
+ </g>
70
+ <!-- game_node&#45;&gt;var_begin -->
71
+ <g id="edge50" class="edge"><title>game_node&#45;&gt;var_begin</title>
72
+ <path fill="none" stroke="black" d="M226.743,-640C326.419,-640 541.565,-640 643.403,-640"/>
73
+ <polygon fill="black" stroke="black" points="643.485,-643.5 653.485,-640 643.485,-636.5 643.485,-643.5"/>
74
+ <text text-anchor="middle" x="440" y="-641.4" font-family="Times,serif" font-size="14.00">(</text>
75
+ </g>
76
+ <!-- prop_name_begin -->
77
+ <g id="node9" class="node"><title>prop_name_begin</title>
78
+ <ellipse fill="none" stroke="black" cx="174" cy="-554" rx="74.0375" ry="18"/>
79
+ <text text-anchor="middle" x="174" y="-548.4" font-family="Times,serif" font-size="14.00">prop_name_begin</text>
80
+ </g>
81
+ <!-- game_node&#45;&gt;prop_name_begin -->
82
+ <g id="edge52" class="edge"><title>game_node&#45;&gt;prop_name_begin</title>
83
+ <path fill="none" stroke="black" d="M174,-621.762C174,-610.36 174,-595.434 174,-582.494"/>
84
+ <polygon fill="black" stroke="black" points="177.5,-582.212 174,-572.212 170.5,-582.212 177.5,-582.212"/>
85
+ <text text-anchor="middle" x="200.5" y="-591.4" font-family="Times,serif" font-size="14.00">[a&#45;zA&#45;Z]</text>
86
+ </g>
87
+ <!-- var_end -->
88
+ <g id="node20" class="node"><title>var_end</title>
89
+ <ellipse fill="none" stroke="black" cx="174" cy="-124" rx="38.0318" ry="18"/>
90
+ <text text-anchor="middle" x="174" y="-118.4" font-family="Times,serif" font-size="14.00">var_end</text>
91
+ </g>
92
+ <!-- game_node&#45;&gt;var_end -->
93
+ <g id="edge54" class="edge"><title>game_node&#45;&gt;var_end</title>
94
+ <path fill="none" stroke="black" d="M225.514,-637.499C326.191,-632.297 541.889,-619.499 572,-604 598.06,-590.586 615,-583.31 615,-554 615,-554 615,-554 615,-425 615,-345.294 651.9,-309.707 604,-246 557.505,-184.162 322.558,-144.639 220.943,-130.185"/>
95
+ <polygon fill="black" stroke="black" points="221.347,-126.708 210.958,-128.785 220.375,-133.64 221.347,-126.708"/>
96
+ <text text-anchor="middle" x="623.5" y="-376.4" font-family="Times,serif" font-size="14.00">)</text>
97
+ </g>
98
+ <!-- game_node&#45;&gt;invalid -->
99
+ <g id="edge56" class="edge"><title>game_node&#45;&gt;invalid</title>
100
+ <path fill="none" stroke="#ffbbbb" d="M215.515,-628.956C311.427,-600.752 538.639,-517.257 517,-364 509.37,-309.958 521.521,-284.664 483,-246 468.457,-231.404 144.291,-153.206 127,-142 126.394,-141.607 79.7758,-86.6943 51.3959,-53.2349"/>
101
+ <polygon fill="#ffbbbb" stroke="#ffbbbb" points="53.7501,-50.5995 44.6127,-45.2367 48.4115,-55.1271 53.7501,-50.5995"/>
102
+ </g>
103
+ <!-- prop_name -->
104
+ <g id="node11" class="node"><title>prop_name</title>
105
+ <ellipse fill="none" stroke="black" cx="174" cy="-468" rx="49.9024" ry="18"/>
106
+ <text text-anchor="middle" x="174" y="-462.4" font-family="Times,serif" font-size="14.00">prop_name</text>
107
+ </g>
108
+ <!-- prop_name_begin&#45;&gt;prop_name -->
109
+ <g id="edge58" class="edge"><title>prop_name_begin&#45;&gt;prop_name</title>
110
+ <path fill="none" stroke="black" d="M174,-535.762C174,-524.36 174,-509.434 174,-496.494"/>
111
+ <polygon fill="black" stroke="black" points="177.5,-496.212 174,-486.212 170.5,-496.212 177.5,-496.212"/>
112
+ <text text-anchor="middle" x="200.5" y="-505.4" font-family="Times,serif" font-size="14.00">[a&#45;zA&#45;Z]</text>
113
+ </g>
114
+ <!-- value_begin -->
115
+ <g id="node13" class="node"><title>value_begin</title>
116
+ <ellipse fill="none" stroke="black" cx="174" cy="-382" rx="53.8258" ry="18"/>
117
+ <text text-anchor="middle" x="174" y="-376.4" font-family="Times,serif" font-size="14.00">value_begin</text>
118
+ </g>
119
+ <!-- prop_name_begin&#45;&gt;value_begin -->
120
+ <g id="edge60" class="edge"><title>prop_name_begin&#45;&gt;value_begin</title>
121
+ <path fill="none" stroke="black" d="M210.421,-538.158C218.501,-532.918 226.107,-526.257 231,-518 246.414,-491.989 243.575,-478.326 233,-450 226.707,-433.145 214.145,-417.699 202.223,-405.803"/>
122
+ <polygon fill="black" stroke="black" points="204.601,-403.234 194.945,-398.874 199.774,-408.304 204.601,-403.234"/>
123
+ <text text-anchor="middle" x="244.5" y="-462.4" font-family="Times,serif" font-size="14.00">[</text>
124
+ </g>
125
+ <!-- prop_name_begin&#45;&gt;invalid -->
126
+ <g id="edge62" class="edge"><title>prop_name_begin&#45;&gt;invalid</title>
127
+ <path fill="none" stroke="#ffbbbb" d="M155.178,-536.552C142.27,-523.675 125.621,-505.131 115,-486 38.6639,-348.491 46.3484,-298.62 32,-142 29.2401,-111.875 28.6712,-104.25 29,-74 29.0619,-68.3089 29.1667,-62.2224 29.2859,-56.4015"/>
128
+ <polygon fill="#ffbbbb" stroke="#ffbbbb" points="32.7861,-56.4289 29.5096,-46.3534 25.7878,-56.273 32.7861,-56.4289"/>
129
+ </g>
130
+ <!-- prop_name&#45;&gt;value_begin -->
131
+ <g id="edge74" class="edge"><title>prop_name&#45;&gt;value_begin</title>
132
+ <path fill="none" stroke="black" d="M174,-449.762C174,-438.36 174,-423.434 174,-410.494"/>
133
+ <polygon fill="black" stroke="black" points="177.5,-410.212 174,-400.212 170.5,-410.212 177.5,-410.212"/>
134
+ <text text-anchor="middle" x="176.5" y="-419.4" font-family="Times,serif" font-size="14.00">[</text>
135
+ </g>
136
+ <!-- prop_name&#45;&gt;invalid -->
137
+ <g id="edge76" class="edge"><title>prop_name&#45;&gt;invalid</title>
138
+ <path fill="none" stroke="#ffbbbb" d="M153.636,-451.342C139.541,-438.704 121.495,-420.119 111,-400 49.7354,-282.557 34.7516,-121.018 31.133,-56.3951"/>
139
+ <polygon fill="#ffbbbb" stroke="#ffbbbb" points="34.617,-55.9888 30.6124,-46.18 27.6261,-56.3452 34.617,-55.9888"/>
140
+ </g>
141
+ <!-- value -->
142
+ <g id="node15" class="node"><title>value</title>
143
+ <ellipse fill="none" stroke="black" cx="174" cy="-296" rx="29.1856" ry="18"/>
144
+ <text text-anchor="middle" x="174" y="-290.4" font-family="Times,serif" font-size="14.00">value</text>
145
+ </g>
146
+ <!-- value_begin&#45;&gt;value -->
147
+ <g id="edge40" class="edge"><title>value_begin&#45;&gt;value</title>
148
+ <path fill="none" stroke="black" d="M174,-363.762C174,-352.36 174,-337.434 174,-324.494"/>
149
+ <polygon fill="black" stroke="black" points="177.5,-324.212 174,-314.212 170.5,-324.212 177.5,-324.212"/>
150
+ <text text-anchor="middle" x="184.5" y="-333.4" font-family="Times,serif" font-size="14.00">[^]]</text>
151
+ </g>
152
+ <!-- value_escape -->
153
+ <g id="node16" class="node"><title>value_escape</title>
154
+ <ellipse fill="none" stroke="black" cx="336" cy="-296" rx="58.1142" ry="18"/>
155
+ <text text-anchor="middle" x="336" y="-290.4" font-family="Times,serif" font-size="14.00">value_escape</text>
156
+ </g>
157
+ <!-- value_begin&#45;&gt;value_escape -->
158
+ <g id="edge42" class="edge"><title>value_begin&#45;&gt;value_escape</title>
159
+ <path fill="none" stroke="black" d="M202.962,-366.625C229.324,-352.631 268.437,-331.867 297.436,-316.472"/>
160
+ <polygon fill="black" stroke="black" points="299.276,-319.458 306.468,-311.678 295.994,-313.275 299.276,-319.458"/>
161
+ <text text-anchor="middle" x="267" y="-333.4" font-family="Times,serif" font-size="14.00">\</text>
162
+ </g>
163
+ <!-- value_end -->
164
+ <g id="node18" class="node"><title>value_end</title>
165
+ <ellipse fill="none" stroke="black" cx="174" cy="-210" rx="46.877" ry="18"/>
166
+ <text text-anchor="middle" x="174" y="-204.4" font-family="Times,serif" font-size="14.00">value_end</text>
167
+ </g>
168
+ <!-- value_begin&#45;&gt;value_end -->
169
+ <g id="edge44" class="edge"><title>value_begin&#45;&gt;value_end</title>
170
+ <path fill="none" stroke="black" d="M223.054,-374.395C283.665,-363.879 381.452,-342.876 403,-314 450.943,-249.751 312.342,-224.167 230.103,-214.834"/>
171
+ <polygon fill="black" stroke="black" points="230.444,-211.35 220.124,-213.749 229.687,-218.309 230.444,-211.35"/>
172
+ <text text-anchor="middle" x="415.5" y="-290.4" font-family="Times,serif" font-size="14.00">]</text>
173
+ </g>
174
+ <!-- value&#45;&gt;value -->
175
+ <g id="edge14" class="edge"><title>value&#45;&gt;value</title>
176
+ <path fill="none" stroke="black" d="M200.574,-303.806C211.629,-304.344 221,-301.742 221,-296 221,-292.142 216.77,-289.701 210.641,-288.679"/>
177
+ <polygon fill="black" stroke="black" points="210.731,-285.179 200.574,-288.194 210.394,-292.171 210.731,-285.179"/>
178
+ <text text-anchor="middle" x="231.5" y="-290.4" font-family="Times,serif" font-size="14.00">[^]]</text>
179
+ </g>
180
+ <!-- value&#45;&gt;value_escape -->
181
+ <g id="edge12" class="edge"><title>value&#45;&gt;value_escape</title>
182
+ <path fill="none" stroke="black" d="M203.713,-296C221.694,-296 245.404,-296 267.779,-296"/>
183
+ <polygon fill="black" stroke="black" points="267.94,-299.5 277.94,-296 267.94,-292.5 267.94,-299.5"/>
184
+ <text text-anchor="middle" x="240" y="-297.4" font-family="Times,serif" font-size="14.00">\</text>
185
+ </g>
186
+ <!-- value&#45;&gt;value_end -->
187
+ <g id="edge16" class="edge"><title>value&#45;&gt;value_end</title>
188
+ <path fill="none" stroke="black" d="M174,-277.762C174,-266.36 174,-251.434 174,-238.494"/>
189
+ <polygon fill="black" stroke="black" points="177.5,-238.212 174,-228.212 170.5,-238.212 177.5,-238.212"/>
190
+ <text text-anchor="middle" x="176.5" y="-247.4" font-family="Times,serif" font-size="14.00">]</text>
191
+ </g>
192
+ <!-- value_escape&#45;&gt;value -->
193
+ <g id="edge68" class="edge"><title>value_escape&#45;&gt;value</title>
194
+ <path fill="none" stroke="black" d="M296.078,-282.808C278.349,-278.467 257.193,-275.352 238,-278 228.596,-279.297 218.628,-281.619 209.429,-284.173"/>
195
+ <polygon fill="black" stroke="black" points="208.421,-280.821 199.813,-286.998 210.394,-287.538 208.421,-280.821"/>
196
+ <text text-anchor="middle" x="240" y="-279.4" font-family="Times,serif" font-size="14.00">.</text>
197
+ </g>
198
+ <!-- value_end&#45;&gt;var_begin -->
199
+ <g id="edge20" class="edge"><title>value_end&#45;&gt;var_begin</title>
200
+ <path fill="none" stroke="black" d="M221.064,-211.66C349.066,-217.446 694,-242.033 694,-339 694,-554 694,-554 694,-554 694,-573.261 695.265,-594.909 696.523,-611.666"/>
201
+ <polygon fill="black" stroke="black" points="693.055,-612.206 697.335,-621.898 700.033,-611.652 693.055,-612.206"/>
202
+ <text text-anchor="middle" x="696.5" y="-419.4" font-family="Times,serif" font-size="14.00">(</text>
203
+ </g>
204
+ <!-- value_end&#45;&gt;game_node -->
205
+ <g id="edge18" class="edge"><title>value_end&#45;&gt;game_node</title>
206
+ <path fill="none" stroke="black" d="M220.488,-213.028C301.462,-218.651 461.821,-231.464 483,-246 495.96,-254.895 569,-382.967 569,-425 569,-554 569,-554 569,-554 569,-577.472 570.412,-589.443 552,-604 527.784,-623.146 336.627,-633.548 235.798,-637.751"/>
207
+ <polygon fill="black" stroke="black" points="235.588,-634.257 225.739,-638.162 235.874,-641.251 235.588,-634.257"/>
208
+ <text text-anchor="middle" x="571.5" y="-419.4" font-family="Times,serif" font-size="14.00">;</text>
209
+ </g>
210
+ <!-- value_end&#45;&gt;prop_name_begin -->
211
+ <g id="edge22" class="edge"><title>value_end&#45;&gt;prop_name_begin</title>
212
+ <path fill="none" stroke="black" d="M220.595,-213.091C297.764,-218.604 445.483,-230.977 464,-246 475.679,-255.475 472.522,-263.167 475,-278 497.343,-411.73 318.344,-499.678 226.341,-535.62"/>
213
+ <polygon fill="black" stroke="black" points="224.994,-532.388 216.913,-539.24 227.503,-538.923 224.994,-532.388"/>
214
+ <text text-anchor="middle" x="487.5" y="-376.4" font-family="Times,serif" font-size="14.00">[a&#45;zA&#45;Z]</text>
215
+ </g>
216
+ <!-- value_end&#45;&gt;value_begin -->
217
+ <g id="edge24" class="edge"><title>value_end&#45;&gt;value_begin</title>
218
+ <path fill="none" stroke="black" d="M220.569,-212.912C293.913,-217.979 429.534,-229.477 444,-246 473.277,-279.439 473.277,-312.561 444,-346 430.593,-361.313 313.119,-372.311 237.605,-377.872"/>
219
+ <polygon fill="black" stroke="black" points="236.965,-374.409 227.243,-378.621 237.469,-381.391 236.965,-374.409"/>
220
+ <text text-anchor="middle" x="468.5" y="-290.4" font-family="Times,serif" font-size="14.00">[</text>
221
+ </g>
222
+ <!-- value_end&#45;&gt;var_end -->
223
+ <g id="edge26" class="edge"><title>value_end&#45;&gt;var_end</title>
224
+ <path fill="none" stroke="black" d="M174,-191.762C174,-180.36 174,-165.434 174,-152.494"/>
225
+ <polygon fill="black" stroke="black" points="177.5,-152.212 174,-142.212 170.5,-152.212 177.5,-152.212"/>
226
+ <text text-anchor="middle" x="176.5" y="-161.4" font-family="Times,serif" font-size="14.00">)</text>
227
+ </g>
228
+ <!-- value_end&#45;&gt;invalid -->
229
+ <g id="edge28" class="edge"><title>value_end&#45;&gt;invalid</title>
230
+ <path fill="none" stroke="#ffbbbb" d="M150.702,-194.064C133.331,-181.378 109.802,-162.414 93,-142 71.0237,-115.299 52.8214,-79.8169 41.7266,-55.5736"/>
231
+ <polygon fill="#ffbbbb" stroke="#ffbbbb" points="44.8323,-53.9448 37.5542,-46.2454 38.4424,-56.8029 44.8323,-53.9448"/>
232
+ </g>
233
+ <!-- var_end&#45;&gt;var_begin -->
234
+ <g id="edge32" class="edge"><title>var_end&#45;&gt;var_begin</title>
235
+ <path fill="none" stroke="black" d="M212.103,-125.364C310.15,-129.113 569.322,-140.605 653,-160 711.29,-173.511 778,-150.165 778,-210 778,-554 778,-554 778,-554 778,-578.461 771.042,-585.535 755,-604 749.67,-610.135 743.044,-615.615 736.235,-620.338"/>
236
+ <polygon fill="black" stroke="black" points="734.105,-617.547 727.597,-625.908 737.898,-623.431 734.105,-617.547"/>
237
+ <text text-anchor="middle" x="780.5" y="-376.4" font-family="Times,serif" font-size="14.00">(</text>
238
+ </g>
239
+ <!-- var_end&#45;&gt;game_node -->
240
+ <g id="edge30" class="edge"><title>var_end&#45;&gt;game_node</title>
241
+ <path fill="none" stroke="black" d="M211.044,-128.204C246.635,-132.144 301.943,-138.01 350,-142 381.289,-144.598 605.972,-142.44 632,-160 652.434,-173.786 656,-185.35 656,-210 656,-554 656,-554 656,-554 656,-579.255 650.162,-590.216 629,-604 596.854,-624.937 352.973,-634.799 236.093,-638.36"/>
242
+ <polygon fill="black" stroke="black" points="235.758,-634.868 225.867,-638.665 235.967,-641.865 235.758,-634.868"/>
243
+ <text text-anchor="middle" x="658.5" y="-376.4" font-family="Times,serif" font-size="14.00">;</text>
244
+ </g>
245
+ <!-- var_end&#45;&gt;var_end -->
246
+ <g id="edge36" class="edge"><title>var_end&#45;&gt;var_end</title>
247
+ <path fill="none" stroke="black" d="M208.176,-131.871C220.224,-131.997 230,-129.373 230,-124 230,-120.306 225.379,-117.912 218.576,-116.817"/>
248
+ <polygon fill="black" stroke="black" points="218.385,-113.297 208.176,-116.129 217.923,-120.281 218.385,-113.297"/>
249
+ <text text-anchor="middle" x="232.5" y="-118.4" font-family="Times,serif" font-size="14.00">)</text>
250
+ </g>
251
+ <!-- game_end -->
252
+ <g id="node22" class="node"><title>game_end</title>
253
+ <ellipse fill="#44ff44" stroke="black" cx="174" cy="-28" rx="22.9471" ry="23.372"/>
254
+ <ellipse fill="none" stroke="black" cx="174" cy="-28" rx="26.8743" ry="27.372"/>
255
+ <text text-anchor="middle" x="174" y="-22.4" font-family="Times,serif" font-size="14.00">end</text>
256
+ </g>
257
+ <!-- var_end&#45;&gt;game_end -->
258
+ <g id="edge34" class="edge"><title>var_end&#45;&gt;game_end</title>
259
+ <path fill="none" stroke="black" d="M174,-105.943C174,-94.6899 174,-79.7809 174,-66.0175"/>
260
+ <polygon fill="black" stroke="black" points="177.5,-65.7953 174,-55.7954 170.5,-65.7954 177.5,-65.7953"/>
261
+ <text text-anchor="middle" x="187.5" y="-75.4" font-family="Times,serif" font-size="14.00">EOS</text>
262
+ </g>
263
+ <!-- var_end&#45;&gt;invalid -->
264
+ <g id="edge38" class="edge"><title>var_end&#45;&gt;invalid</title>
265
+ <path fill="none" stroke="#ffbbbb" d="M151.816,-109.21C126.9,-92.5997 86.3725,-65.5817 58.9735,-47.3157"/>
266
+ <polygon fill="#ffbbbb" stroke="#ffbbbb" points="60.8375,-44.3519 50.5755,-41.717 56.9545,-50.1762 60.8375,-44.3519"/>
267
+ </g>
268
+ </g>
269
+ </svg>