sbsm 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/COPYING +515 -0
  2. data/History.txt +5 -0
  3. data/Manifest.txt +49 -0
  4. data/README.txt +41 -0
  5. data/Rakefile +28 -0
  6. data/data/_flavored_uri.grammar +24 -0
  7. data/data/_uri.grammar +22 -0
  8. data/data/_zone_uri.grammar +24 -0
  9. data/data/flavored_uri.grammar +24 -0
  10. data/data/uri.grammar +22 -0
  11. data/data/zone_uri.grammar +24 -0
  12. data/install.rb +1098 -0
  13. data/lib/cgi/drbsession.rb +37 -0
  14. data/lib/sbsm/cgi.rb +79 -0
  15. data/lib/sbsm/drb.rb +19 -0
  16. data/lib/sbsm/drbserver.rb +162 -0
  17. data/lib/sbsm/exception.rb +28 -0
  18. data/lib/sbsm/flavored_uri_parser.rb +47 -0
  19. data/lib/sbsm/index.rb +66 -0
  20. data/lib/sbsm/lookandfeel.rb +176 -0
  21. data/lib/sbsm/lookandfeelfactory.rb +50 -0
  22. data/lib/sbsm/lookandfeelwrapper.rb +109 -0
  23. data/lib/sbsm/redefine_19_cookie.rb +4 -0
  24. data/lib/sbsm/redirector.rb +37 -0
  25. data/lib/sbsm/request.rb +162 -0
  26. data/lib/sbsm/session.rb +542 -0
  27. data/lib/sbsm/state.rb +301 -0
  28. data/lib/sbsm/time.rb +29 -0
  29. data/lib/sbsm/trans_handler.rb +119 -0
  30. data/lib/sbsm/turing.rb +25 -0
  31. data/lib/sbsm/uri_parser.rb +45 -0
  32. data/lib/sbsm/user.rb +47 -0
  33. data/lib/sbsm/validator.rb +256 -0
  34. data/lib/sbsm/viralstate.rb +47 -0
  35. data/lib/sbsm/zone_uri_parser.rb +48 -0
  36. data/test/data/dos_file.txt +2 -0
  37. data/test/data/lnf_file.txt +2 -0
  38. data/test/data/mac_file.txt +1 -0
  39. data/test/stub/cgi.rb +35 -0
  40. data/test/suite.rb +29 -0
  41. data/test/test_drbserver.rb +83 -0
  42. data/test/test_index.rb +90 -0
  43. data/test/test_lookandfeel.rb +230 -0
  44. data/test/test_session.rb +372 -0
  45. data/test/test_state.rb +176 -0
  46. data/test/test_trans_handler.rb +447 -0
  47. data/test/test_user.rb +44 -0
  48. data/test/test_validator.rb +126 -0
  49. data/usage-en.txt +112 -0
  50. metadata +142 -0
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+ # Turing -- SBSM -- 15.05.2009 -- hwyss@ywesee.com
3
+ # Use a Hash instead of a PStore to manage Captchas
4
+
5
+ require 'turing'
6
+ require 'thread'
7
+
8
+ module SBSM
9
+ class PStore < Hash
10
+ def initialize *args
11
+ super
12
+ @mutex = Mutex.new
13
+ end
14
+ def transaction &block
15
+ @mutex.synchronize &block
16
+ end
17
+ end
18
+ end
19
+ class Turing::Challenge
20
+ alias :__orig_initialize__ :initialize
21
+ def initialize *args
22
+ __orig_initialize__ *args
23
+ @store = SBSM::PStore.new
24
+ end
25
+ end
@@ -0,0 +1,45 @@
1
+ require 'rockit/rockit'
2
+ module SBSM
3
+ # Parser for Uri
4
+ # created by Rockit version 0.3.8 on Wed Jul 19 18:22:17 CEST 2006
5
+ # Rockit is copyright (c) 2001 Robert Feldt, feldt@ce.chalmers.se
6
+ # and licensed under GPL
7
+ # but this parser is under LGPL
8
+ tokens = [
9
+ t1 = EofToken.new("EOF",/^(�~~��~^^~3499569544)/),
10
+ t2 = Token.new("SLASH",/^(\/)/),
11
+ t3 = Token.new("OTHER",/^([^\/]+)/),
12
+ t4 = Token.new("LANG",/^([a-z]{2})/)
13
+ ]
14
+ productions = [
15
+ p1 = Production.new("Uri'".intern,[:Uri],SyntaxTreeBuilder.new("Uri'",["uri"],[])),
16
+ p2 = Production.new(:Uri,[t2, t4, t2, t3, t2, :Variables],SyntaxTreeBuilder.new("Uri",["_", "language", "_", "event", "_", "variables"],[])),
17
+ p3 = Production.new(:Uri,[t2, t4, t2, t3, t2],SyntaxTreeBuilder.new("Uri",["_", "language", "_", "event"],[])),
18
+ p4 = Production.new(:Uri,[t2, t4, t2, t3],SyntaxTreeBuilder.new("Uri",["_", "language", "_", "event"],[nil])),
19
+ p5 = Production.new(:Uri,[t2, t4, t2],SyntaxTreeBuilder.new("Uri",["_", "language"],[])),
20
+ p6 = Production.new(:Uri,[t2, t4],SyntaxTreeBuilder.new("Uri",["_", "language"],[nil])),
21
+ p7 = Production.new(:Uri,[t2],SyntaxTreeBuilder.new("Uri",["_"],[])),
22
+ p8 = Production.new(:Variables,[:Plus404380716, t2],LiftingSyntaxTreeBuilder.new(["pair"],[])),
23
+ p9 = Production.new(:Variables,[:Plus404380716],LiftingSyntaxTreeBuilder.new(["pair"],[nil])),
24
+ p10 = Production.new(:Plus404380716,[:Plus404380716, :Pair],ArrayNodeBuilder.new([1],0,nil,nil,[],true)),
25
+ p11 = Production.new(:Plus404380716,[:Pair],ArrayNodeBuilder.new([0],nil,nil,nil,[],true)),
26
+ p12 = Production.new(:Pair,[t3, t2, t3, t2],SyntaxTreeBuilder.new("Pair",["key", "_", "value"],[])),
27
+ p13 = Production.new(:Pair,[t3, t2, t3],SyntaxTreeBuilder.new("Pair",["key", "_", "value"],[nil])),
28
+ p14 = Production.new(:Pair,[t3, t2, t2],SyntaxTreeBuilder.new("Pair",["key"],[])),
29
+ p15 = Production.new(:Pair,[t3],SyntaxTreeBuilder.new("Pair",["key"],[]))
30
+ ]
31
+ relations = [
32
+
33
+ ]
34
+ priorities = ProductionPriorities.new(relations)
35
+ action_table = [[9, 2], [2, 1], [13, 8, 24, 1], [17, 2, 20, 1], [21, 4, 16, 1], [25, 2, 12, 1], [41, 4, 8, 1], [49, 2, 41, 4, 32, 1], [4, 1], [40, 7], [53, 2, 56, 7], [36, 7], [28, 1], [57, 2, 61, 4], [52, 7], [65, 2, 48, 7], [44, 7]]
36
+ goto_hash = {0 => {1 => 1}, 6 => {2 => 8, 3 => 7, 4 => 9}, 7 => {4 => 11}}
37
+ @@parse_table404243016 = ParseTable.new(productions,tokens,priorities,action_table,goto_hash,2,[
38
+ :REDUCE,
39
+ :SHIFT,
40
+ :ACCEPT
41
+ ])
42
+ def SBSM._uri_parser
43
+ GeneralizedLrParser.new(@@parse_table404243016)
44
+ end
45
+ end
data/lib/sbsm/user.rb ADDED
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # State Based Session Management
4
+ # Copyright (C) 2004 Hannes Wyss
5
+ #
6
+ # This library is free software; you can redistribute it and/or
7
+ # modify it under the terms of the GNU Lesser General Public
8
+ # License as published by the Free Software Foundation; either
9
+ # version 2.1 of the License, or (at your option) any later version.
10
+ #
11
+ # This library is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ # Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with this library; if not, write to the Free Software
18
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ #
20
+ # ywesee - intellectual capital connected, Winterthurerstrasse 52, CH-8006 Z�rich, Switzerland
21
+ # hwyss@ywesee.com
22
+ #
23
+ # User -- sbsm -- 20.11.2002 -- hwyss@ywesee.com
24
+
25
+ module SBSM
26
+ class User
27
+ HOME = nil
28
+ NAVIGATION = []
29
+ SESSION_WEIGHT = 1
30
+ SESSION_WEIGHT_FACTOR = 60 * 15 # 15 Minutes
31
+ def home
32
+ self::class::HOME
33
+ end
34
+ def navigation
35
+ self::class::NAVIGATION.dup
36
+ end
37
+ def pass; end
38
+ def session_weight
39
+ self::class::SESSION_WEIGHT * SESSION_WEIGHT_FACTOR
40
+ end
41
+ end
42
+ class UnknownUser < User
43
+ end
44
+ class KnownUser < User
45
+ SESSION_WEIGHT = 2
46
+ end
47
+ end
@@ -0,0 +1,256 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # State Based Session Management
4
+ # Copyright (C) 2004 Hannes Wyss
5
+ #
6
+ # This library is free software; you can redistribute it and/or
7
+ # modify it under the terms of the GNU Lesser General Public
8
+ # License as published by the Free Software Foundation; either
9
+ # version 2.1 of the License, or (at your option) any later version.
10
+ #
11
+ # This library is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ # Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with this library; if not, write to the Free Software
18
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ #
20
+ # ywesee - intellectual capital connected, Winterthurerstrasse 52, CH-8006 Z�rich, Switzerland
21
+ # hwyss@ywesee.com
22
+ #
23
+ # Validator -- sbsm -- 15.11.2002 -- hwyss@ywesee.com
24
+
25
+ require 'digest/md5'
26
+ require 'rmail'
27
+ require 'date'
28
+ require 'drb/drb'
29
+ require 'uri'
30
+ require 'stringio'
31
+ require 'hpricot'
32
+
33
+ module SBSM
34
+ class InvalidDataError < RuntimeError
35
+ attr_reader :key, :value
36
+ alias :data :value
37
+ def initialize(msg, key, value)
38
+ super(msg.to_s)
39
+ @key = key
40
+ @value = value
41
+ end
42
+ end
43
+ class Validator
44
+ BOOLEAN = []
45
+ DATES = []
46
+ ENUMS = {}
47
+ EVENTS = []
48
+ FILES = []
49
+ HTML = []
50
+ NUMERIC = []
51
+ PATTERNS = {}
52
+ STRINGS = []
53
+ URIS = []
54
+ ALLOWED_TAGS = %{a b br div font h1 h2 h3 i img li ol p pre span strong u ul}
55
+ def initialize
56
+ reset_errors()
57
+ @boolean = self::class::BOOLEAN.dup
58
+ @dates = self::class::DATES.dup
59
+ @enums = self::class::ENUMS.dup
60
+ @events = self::class::EVENTS.dup
61
+ @files = self::class::FILES.dup
62
+ @html = self::class::HTML.dup
63
+ @numeric = self::class::NUMERIC.dup
64
+ @patterns = self::class::PATTERNS.dup
65
+ @strings = self::class::STRINGS.dup
66
+ @uris = self::class::URIS.dup
67
+ end
68
+ def error?
69
+ !@errors.empty?
70
+ end
71
+ def reset_errors
72
+ @errors = {}
73
+ end
74
+ def set_pass(value1, value2)
75
+ valid1 = pass(value1.to_s)
76
+ valid2 = pass(value2.to_s)
77
+ if(value1.to_s.empty?)
78
+ SBSM::InvalidDataError.new(:e_empty_pass, :pass, '')
79
+ elsif(valid1 != valid2)
80
+ SBSM::InvalidDataError.new(:e_non_matching_pass, :pass, '')
81
+ else
82
+ valid1
83
+ end
84
+ end
85
+ def valid_values(key)
86
+ key = key.intern if key.is_a? String
87
+ @enums.fetch(key) {
88
+ if(@boolean.include?(key))
89
+ ['false', 'true']
90
+ end
91
+ }
92
+ end
93
+ def validate(key, value)
94
+ value = value.pop if value.is_a? Array
95
+ return nil if value.nil?
96
+ if value.is_a?(StringIO)
97
+ if(@files.include?(key))
98
+ return validate_file(key, value)
99
+ else
100
+ begin
101
+ value = value.read
102
+ rescue StandardError => e
103
+ p e
104
+ end
105
+ end
106
+ elsif(value.is_a? DRb::DRbObject)
107
+ value = value[0]
108
+ if(@files.include?(key))
109
+ return validate_file(key, value)
110
+ else
111
+ begin
112
+ value = value.read
113
+ rescue StandardError => e
114
+ #p e
115
+ end
116
+ end
117
+ end
118
+ perform_validation(key, value)
119
+ end
120
+ def perform_validation(key, value)
121
+ value = value.to_s.strip
122
+ begin
123
+ if(key==:event)
124
+ symbol = value.to_sym
125
+ symbol if @events.include?(symbol)
126
+ elsif(@boolean.include?(key))
127
+ validate_boolean(key, value)
128
+ elsif(@dates.include?(key))
129
+ validate_date(key, value)
130
+ elsif(@enums.has_key?(key))
131
+ value if @enums[key].include?(value)
132
+ elsif(@html.include?(key))
133
+ validate_html(value)
134
+ elsif(@patterns.include?(key))
135
+ validate_pattern(key, value)
136
+ elsif(@numeric.include?(key))
137
+ validate_numeric(key, value)
138
+ elsif(@uris.include?(key))
139
+ validate_uri(key, value)
140
+ elsif(@strings.include?(key))
141
+ validate_string(value)
142
+ elsif(@files.include?(key))
143
+ StringIO.new(value)
144
+ elsif(self.respond_to?(key, true))
145
+ self.send(key, value)
146
+ end
147
+ rescue InvalidDataError => e
148
+ @errors.store(e.key, e)
149
+ end
150
+ end
151
+ private
152
+ def email(value)
153
+ return if(value.empty?)
154
+ parsed = RMail::Address.parse(value).first
155
+ if(parsed.nil?)
156
+ raise InvalidDataError.new(:e_invalid_email_address, :email, value)
157
+ elsif(parsed.domain)
158
+ parsed.address
159
+ else
160
+ raise InvalidDataError.new(:e_domainless_email_address, :email, value)
161
+ end
162
+ end
163
+ def filename(value)
164
+ if(value == File.basename(value))
165
+ value
166
+ end
167
+ end
168
+ def flavor(value)
169
+ validate_string(value)
170
+ end
171
+ alias :default_flavor :flavor
172
+ def language(value)
173
+ validate_string(value)
174
+ end
175
+ def pass(value)
176
+ unless(value.empty?)
177
+ Digest::MD5::hexdigest(value)
178
+ end
179
+ end
180
+ alias :confirm_pass :pass
181
+ @@state_id_ptrn = /-?\d+/
182
+ def state_id(value)
183
+ if(match = @@state_id_ptrn.match(value))
184
+ match[0].to_i
185
+ else
186
+ nil
187
+ end
188
+ end
189
+ def validate_boolean(key, value)
190
+ case value.to_s.downcase
191
+ when 'true', '1', 'y', 'j'
192
+ true
193
+ when 'false', '0', 'n'
194
+ false
195
+ else
196
+ raise InvalidDataError.new(:e_invalid_boolean, key, value)
197
+ end
198
+ end
199
+ def validate_date(key, value)
200
+ return nil if (value.empty?)
201
+ begin
202
+ Date.parse(value.tr('.', '-'))
203
+ rescue ArgumentError
204
+ raise InvalidDataError.new(:e_invalid_date, key, value)
205
+ end
206
+ end
207
+ def validate_file(key, value)
208
+ return nil if value.original_filename.empty?
209
+ value
210
+ end
211
+ def validate_html(value)
212
+ _validate_html(value)
213
+ end
214
+ @@xml_ptrn = /<\?xml[^>]+>/
215
+ def _validate_html(value, valid=self.class.const_get(:ALLOWED_TAGS))
216
+ doc = Hpricot(value.gsub(@@xml_ptrn, ''), :fixup_tags => true)
217
+ (doc/"*").each { |element|
218
+ unless(element.is_a?(Hpricot::Text) \
219
+ || (element.respond_to?(:name) \
220
+ && valid.include?(element.name.downcase)))
221
+ element.swap _validate_html(element.inner_html.to_s)
222
+ end
223
+ }
224
+ valid = doc.to_html
225
+ valid.force_encoding 'UTF-8' if valid.respond_to?(:force_encoding)
226
+ valid
227
+ end
228
+ @@numeric_ptrn = /\d+(\.\d{1,2})?/
229
+ def validate_numeric(key, value)
230
+ return if(value.empty?)
231
+ if(match = @@numeric_ptrn.match(value))
232
+ match[0]
233
+ else
234
+ raise InvalidDataError.new("e_invalid_#{key}", key, value)
235
+ end
236
+ end
237
+ def validate_pattern(key, value)
238
+ pattern = @patterns[key]
239
+ if(match = pattern.match(value))
240
+ match[0]
241
+ end
242
+ end
243
+ def validate_string(value)
244
+ _validate_html(value, [])
245
+ end
246
+ def validate_uri(key, value)
247
+ uri = URI.parse(value)
248
+ if(uri.scheme.nil?)
249
+ uri = URI.parse('http://' << value)
250
+ end
251
+ uri
252
+ rescue
253
+ raise InvalidDataError.new(:e_invalid_uri, key, value)
254
+ end
255
+ end
256
+ end
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # State Based Session Management
4
+ # Copyright (C) 2004 Hannes Wyss
5
+ #
6
+ # This library is free software; you can redistribute it and/or
7
+ # modify it under the terms of the GNU Lesser General Public
8
+ # License as published by the Free Software Foundation; either
9
+ # version 2.1 of the License, or (at your option) any later version.
10
+ #
11
+ # This library is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ # Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with this library; if not, write to the Free Software
18
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ #
20
+ # ywesee - intellectual capital connected, Winterthurerstrasse 52, CH-8006 Z�rich, Switzerland
21
+ # hwyss@ywesee.com
22
+ #
23
+ # ViralState -- sbsm -- 16.04.2004 -- hwyss@ywesee.com
24
+
25
+ module SBSM
26
+ module ViralState
27
+ VIRAL = true
28
+ def infect(newstate)
29
+ @viral_modules.uniq.each { |mod|
30
+ newstate.extend(mod) unless newstate.is_a?(mod)
31
+ }
32
+ newstate
33
+ end
34
+ def trigger(event)
35
+ newstate = super
36
+ if(event==:logout)
37
+ @session.logout
38
+ else
39
+ infect(newstate)
40
+ end
41
+ newstate
42
+ rescue DRb::DRbError, RangeError
43
+ @session.logout
44
+ home
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+ require 'rockit/rockit'
3
+ module SBSM
4
+ # Parser for Uri
5
+ # created by Rockit version 0.3.8 on Wed Jul 19 18:24:42 CEST 2006
6
+ # Rockit is copyright (c) 2001 Robert Feldt, feldt@ce.chalmers.se
7
+ # and licensed under GPL
8
+ # but this parser is under LGPL
9
+ tokens = [
10
+ t1 = EofToken.new("EOF",/^(¤~~¤¤~^^~3493746103)/),
11
+ t2 = Token.new("SLASH",/^(\/)/),
12
+ t3 = Token.new("OTHER",/^([^\/]+)/),
13
+ t4 = Token.new("LANG",/^([a-z]{2})/)
14
+ ]
15
+ productions = [
16
+ p1 = Production.new("Uri'".intern,[:Uri],SyntaxTreeBuilder.new("Uri'",["uri"],[])),
17
+ p2 = Production.new(:Uri,[t2, t4, t2, t3, t2, t3, t2, :Variables],SyntaxTreeBuilder.new("Uri",["_", "language", "_", "zone", "_", "event", "_", "variables"],[])),
18
+ p3 = Production.new(:Uri,[t2, t4, t2, t3, t2, t3, t2],SyntaxTreeBuilder.new("Uri",["_", "language", "_", "zone", "_", "event"],[])),
19
+ p4 = Production.new(:Uri,[t2, t4, t2, t3, t2, t3],SyntaxTreeBuilder.new("Uri",["_", "language", "_", "zone", "_", "event"],[nil])),
20
+ p5 = Production.new(:Uri,[t2, t4, t2, t3, t2],SyntaxTreeBuilder.new("Uri",["_", "language", "_", "zone"],[])),
21
+ p6 = Production.new(:Uri,[t2, t4, t2, t3],SyntaxTreeBuilder.new("Uri",["_", "language", "_", "zone"],[nil])),
22
+ p7 = Production.new(:Uri,[t2, t4, t2],SyntaxTreeBuilder.new("Uri",["_", "language"],[])),
23
+ p8 = Production.new(:Uri,[t2, t4],SyntaxTreeBuilder.new("Uri",["_", "language"],[nil])),
24
+ p9 = Production.new(:Uri,[t2],SyntaxTreeBuilder.new("Uri",["_"],[])),
25
+ p10 = Production.new(:Variables,[:Plus403922760, t2],LiftingSyntaxTreeBuilder.new(["pair"],[])),
26
+ p11 = Production.new(:Variables,[:Plus403922760],LiftingSyntaxTreeBuilder.new(["pair"],[nil])),
27
+ p12 = Production.new(:Plus403922760,[:Plus403922760, :Pair],ArrayNodeBuilder.new([1],0,nil,nil,[],true)),
28
+ p13 = Production.new(:Plus403922760,[:Pair],ArrayNodeBuilder.new([0],nil,nil,nil,[],true)),
29
+ p14 = Production.new(:Pair,[t3, t2, t3, t2],SyntaxTreeBuilder.new("Pair",["key", "_", "value"],[])),
30
+ p15 = Production.new(:Pair,[t3, t2, t3],SyntaxTreeBuilder.new("Pair",["key", "_", "value"],[nil])),
31
+ p16 = Production.new(:Pair,[t3, t2, t2],SyntaxTreeBuilder.new("Pair",["key"],[])),
32
+ p17 = Production.new(:Pair,[t3],SyntaxTreeBuilder.new("Pair",["key"],[]))
33
+ ]
34
+ relations = [
35
+
36
+ ]
37
+ priorities = ProductionPriorities.new(relations)
38
+ action_table = [[9, 2], [2, 1], [13, 8, 32, 1], [17, 2, 28, 1], [21, 4, 24, 1], [25, 2, 20, 1], [29, 4, 16, 1], [33, 2, 12, 1], [49, 4, 8, 1], [53, 2, 49, 4, 40, 1], [4, 1], [48, 7], [61, 2, 64, 7], [36, 1], [44, 7], [65, 2, 69, 4], [60, 7], [73, 2, 56, 7], [52, 7]]
39
+ goto_hash = {0 => {1 => 1}, 8 => {2 => 10, 3 => 9, 4 => 11}, 9 => {4 => 14}}
40
+ @@parse_table403739556 = ParseTable.new(productions,tokens,priorities,action_table,goto_hash,2,[
41
+ :REDUCE,
42
+ :SHIFT,
43
+ :ACCEPT
44
+ ])
45
+ def SBSM._zone_uri_parser
46
+ GeneralizedLrParser.new(@@parse_table403739556)
47
+ end
48
+ end