review-peg 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0dc696d5bf81d76955a754d7f7e8b1c1f6160199
4
- data.tar.gz: 550ffcce6822a8f998baaf33f33de445f17c9bec
3
+ metadata.gz: 02a8314cbab450277e8afa8b82587710657765c4
4
+ data.tar.gz: 2a1eb42ee5b296e430b1c8a4f24ca5aee7daa592
5
5
  SHA512:
6
- metadata.gz: 00a1e008047bf22ef4565a33a9b95f6aa2ef218940dd08a47b5fadba5a2d86f52f52ca4c8bae6a75829350153e2d67ce84d6843fbf76d2045d16de61e148755d
7
- data.tar.gz: 0438df61b57a4a90ffaed53009093ff9922a9d471e88a6bbe0f5bc8bf8cd1b2cae3095ca4a84a90cc68ab170ae955d2876c8822af794a20dfc76ffd1f5f1bc2f
6
+ metadata.gz: 5c9daa8c4e7649c01b8fd4579f1b894ad140ee6c6adba721c063cd4633bf3190e2f85bc0eed84aad79a9d1a1b28fd28e27f86a057099f9cbe6d9506dc21ac6ea
7
+ data.tar.gz: a94b8dcae6985bdef5bfc5e91a617d962f60003db27f7725029720b694a8309b627425410b56b8fed42be8e91e7fcc9e8b4ab4176453eb48e9d742c92aaef334
data/Rakefile CHANGED
@@ -15,8 +15,6 @@ task :default => [:test]
15
15
 
16
16
  task :kpeg do
17
17
  FileUtils.rm_f "lib/review/compiler.rb"
18
- FileUtils.rm_f "lib/review/compiler/literals_1_9.rb"
19
- sh "kpeg -s lib/review/compiler/literals_1_9.kpeg -o lib/review/compiler/literals_1_9.rb"
20
18
  sh "kpeg -s lib/review/review.kpeg -o lib/review/compiler.rb"
21
19
  end
22
20
 
@@ -1,3 +1,4 @@
1
+ # coding: UTF-8
1
2
  class ReVIEW::Compiler
2
3
  # :stopdoc:
3
4
 
@@ -35,22 +36,16 @@ class ReVIEW::Compiler
35
36
  end
36
37
 
37
38
  def current_line(target=pos)
38
- cur_offset = 0
39
- cur_line = 0
40
-
41
- string.each_line do |line|
42
- cur_line += 1
43
- cur_offset += line.size
44
- return cur_line if cur_offset >= target
45
- end
39
+ offset = @sizes_memo.bsearch{|line, cur_offset| cur_offset >= target}
40
+ if offset
41
+ return offset[0]
42
+ end
46
43
 
47
44
  -1
48
45
  end
49
46
 
50
47
  def lines
51
- lines = []
52
- string.each_line { |l| lines << l }
53
- lines
48
+ @lines_memo
54
49
  end
55
50
 
56
51
 
@@ -61,9 +56,22 @@ class ReVIEW::Compiler
61
56
 
62
57
  # Sets the string and current parsing position for the parser.
63
58
  def set_string string, pos
64
- @string = string
65
- @string_size = string ? string.size : 0
59
+ @string = string.freeze
66
60
  @pos = pos
61
+ @sizes_memo = []
62
+ if string
63
+ @string_size = string.size
64
+ @lines_memo = string.lines
65
+ cur_offset = cur_line = 0
66
+ @lines_memo.each do |line|
67
+ cur_line += 1
68
+ cur_offset += line.size
69
+ @sizes_memo << [cur_line, cur_offset]
70
+ end
71
+ else
72
+ @string_size = 0
73
+ @lines_memo = []
74
+ end
67
75
  end
68
76
 
69
77
  def show_pos
@@ -373,7 +381,7 @@ require 'review/preprocessor'
373
381
  require 'review/exception'
374
382
  require 'review/node'
375
383
  require 'lineinput'
376
- require 'review/compiler/literals_1_9'
384
+ # require 'review/compiler/literals_1_9'
377
385
  # require 'review/compiler/literals_1_8'
378
386
 
379
387
  ## redifine Compiler.new
@@ -1194,9 +1202,7 @@ require 'review/node'
1194
1202
  end
1195
1203
  end
1196
1204
  include ::ReVIEWConstruction
1197
- def setup_foreign_grammar
1198
- @_grammar_literals = ReVIEW::Compiler::Literals.new(nil)
1199
- end
1205
+ def setup_foreign_grammar; end
1200
1206
 
1201
1207
  # root = Start
1202
1208
  def _root
@@ -5036,48 +5042,40 @@ require 'review/node'
5036
5042
  return _tmp
5037
5043
  end
5038
5044
 
5039
- # Alphanumeric = %literals.Alphanumeric
5040
- def _Alphanumeric
5041
- _tmp = @_grammar_literals.external_invoke(self, :_Alphanumeric)
5042
- set_failed_rule :_Alphanumeric unless _tmp
5043
- return _tmp
5044
- end
5045
-
5046
- # AlphanumericAscii = %literals.AlphanumericAscii
5045
+ # AlphanumericAscii = /[A-Za-z0-9]/
5047
5046
  def _AlphanumericAscii
5048
- _tmp = @_grammar_literals.external_invoke(self, :_AlphanumericAscii)
5047
+ _tmp = scan(/\A(?-mix:[A-Za-z0-9])/)
5049
5048
  set_failed_rule :_AlphanumericAscii unless _tmp
5050
5049
  return _tmp
5051
5050
  end
5052
5051
 
5053
- # LowerAlphabetAscii = %literals.LowerAlphabetAscii
5052
+ # LowerAlphabetAscii = /[a-z]/
5054
5053
  def _LowerAlphabetAscii
5055
- _tmp = @_grammar_literals.external_invoke(self, :_LowerAlphabetAscii)
5054
+ _tmp = scan(/\A(?-mix:[a-z])/)
5056
5055
  set_failed_rule :_LowerAlphabetAscii unless _tmp
5057
5056
  return _tmp
5058
5057
  end
5059
5058
 
5060
- # Digit = %literals.Digit
5059
+ # Digit = /[0-9]/
5061
5060
  def _Digit
5062
- _tmp = @_grammar_literals.external_invoke(self, :_Digit)
5061
+ _tmp = scan(/\A(?-mix:[0-9])/)
5063
5062
  set_failed_rule :_Digit unless _tmp
5064
5063
  return _tmp
5065
5064
  end
5066
5065
 
5067
- # BOM = %literals.BOM
5066
+ # BOM = "uFEFF"
5068
5067
  def _BOM
5069
- _tmp = @_grammar_literals.external_invoke(self, :_BOM)
5068
+ _tmp = match_string("uFEFF")
5070
5069
  set_failed_rule :_BOM unless _tmp
5071
5070
  return _tmp
5072
5071
  end
5073
5072
 
5074
- # Newline = %literals.Newline:n {newline(self, position, "\n")}
5073
+ # Newline = /\n|\r\n?|\p{Zl}|\p{Zp}/ {newline(self, position, "\n")}
5075
5074
  def _Newline
5076
5075
 
5077
5076
  _save = self.pos
5078
5077
  while true # sequence
5079
- _tmp = @_grammar_literals.external_invoke(self, :_Newline)
5080
- n = @result
5078
+ _tmp = scan(/\A(?-mix:\n|\r\n?|\p{Zl}|\p{Zp})/)
5081
5079
  unless _tmp
5082
5080
  self.pos = _save
5083
5081
  break
@@ -5094,20 +5092,6 @@ require 'review/node'
5094
5092
  return _tmp
5095
5093
  end
5096
5094
 
5097
- # NonAlphanumeric = %literals.NonAlphanumeric
5098
- def _NonAlphanumeric
5099
- _tmp = @_grammar_literals.external_invoke(self, :_NonAlphanumeric)
5100
- set_failed_rule :_NonAlphanumeric unless _tmp
5101
- return _tmp
5102
- end
5103
-
5104
- # Spacechar = %literals.Spacechar
5105
- def _Spacechar
5106
- _tmp = @_grammar_literals.external_invoke(self, :_Spacechar)
5107
- set_failed_rule :_Spacechar unless _tmp
5108
- return _tmp
5109
- end
5110
-
5111
5095
  Rules = {}
5112
5096
  Rules[:_root] = rule_info("root", "Start")
5113
5097
  Rules[:_Start] = rule_info("Start", "&. { @list_stack = Array.new } Document:c { @strategy.ast = c }")
@@ -5171,13 +5155,10 @@ require 'review/node'
5171
5155
  Rules[:_EOL] = rule_info("EOL", "(Newline | EOF)")
5172
5156
  Rules[:_EOF] = rule_info("EOF", "!.")
5173
5157
  Rules[:_ElementName] = rule_info("ElementName", "< LowerAlphabetAscii+ > { text }")
5174
- Rules[:_Alphanumeric] = rule_info("Alphanumeric", "%literals.Alphanumeric")
5175
- Rules[:_AlphanumericAscii] = rule_info("AlphanumericAscii", "%literals.AlphanumericAscii")
5176
- Rules[:_LowerAlphabetAscii] = rule_info("LowerAlphabetAscii", "%literals.LowerAlphabetAscii")
5177
- Rules[:_Digit] = rule_info("Digit", "%literals.Digit")
5178
- Rules[:_BOM] = rule_info("BOM", "%literals.BOM")
5179
- Rules[:_Newline] = rule_info("Newline", "%literals.Newline:n {newline(self, position, \"\\n\")}")
5180
- Rules[:_NonAlphanumeric] = rule_info("NonAlphanumeric", "%literals.NonAlphanumeric")
5181
- Rules[:_Spacechar] = rule_info("Spacechar", "%literals.Spacechar")
5158
+ Rules[:_AlphanumericAscii] = rule_info("AlphanumericAscii", "/[A-Za-z0-9]/")
5159
+ Rules[:_LowerAlphabetAscii] = rule_info("LowerAlphabetAscii", "/[a-z]/")
5160
+ Rules[:_Digit] = rule_info("Digit", "/[0-9]/")
5161
+ Rules[:_BOM] = rule_info("BOM", "\"uFEFF\"")
5162
+ Rules[:_Newline] = rule_info("Newline", "/\\n|\\r\\n?|\\p{Zl}|\\p{Zp}/ {newline(self, position, \"\\n\")}")
5182
5163
  # :startdoc:
5183
5164
  end
@@ -654,8 +654,9 @@ module ReVIEW
654
654
  '\noindent'
655
655
  end
656
656
 
657
- def inline_chapref(id)
658
- title = super
657
+ def node_inline_chapref(node)
658
+ id = node[0].to_raw
659
+ title = @book.chapter_index.display_string(id)
659
660
  if @book.config["chapterlink"]
660
661
  "\\hyperref[chap:#{id}]{#{title}}"
661
662
  else
@@ -666,7 +667,8 @@ module ReVIEW
666
667
  nofunc_text("[UnknownChapter:#{id}]")
667
668
  end
668
669
 
669
- def inline_chap(id)
670
+ def node_inline_chap(node)
671
+ id = node[0].to_raw
670
672
  if @book.config["chapterlink"]
671
673
  "\\hyperref[chap:#{id}]{#{@book.chapter_index.number(id)}}"
672
674
  else
@@ -677,7 +679,8 @@ module ReVIEW
677
679
  nofunc_text("[UnknownChapter:#{id}]")
678
680
  end
679
681
 
680
- def inline_title(id)
682
+ def node_inline_title(node)
683
+ id = node[0].to_raw
681
684
  title = super
682
685
  if @book.config["chapterlink"]
683
686
  "\\hyperref[chap:#{id}]{#{title}}"
@@ -697,12 +700,14 @@ module ReVIEW
697
700
  macro('reviewlistref', "#{chapter.number}.#{chapter.list(id).number}")
698
701
  end
699
702
 
700
- def inline_table(id)
703
+ def node_inline_table(node)
704
+ id = node[0].to_raw
701
705
  chapter, id = extract_chapter_id(id)
702
706
  macro('reviewtableref', "#{chapter.number}.#{chapter.table(id).number}", table_label(id, chapter))
703
707
  end
704
708
 
705
- def inline_img(id)
709
+ def node_inline_img(node)
710
+ id = node[0].to_raw
706
711
  chapter, id = extract_chapter_id(id)
707
712
  macro('reviewimageref', "#{chapter.number}.#{chapter.image(id).number}", image_label(id, chapter))
708
713
  end
@@ -812,7 +817,8 @@ module ReVIEW
812
817
  macro('texttt', macro('textbf', str))
813
818
  end
814
819
 
815
- def inline_bib(id)
820
+ def node_inline_bib(node)
821
+ id = node[0].to_raw
816
822
  macro('reviewbibref', "[#{@chapter.bibpaper(id).number}]", bib_label(id))
817
823
  end
818
824
 
@@ -831,7 +837,8 @@ module ReVIEW
831
837
  end
832
838
  end
833
839
 
834
- def inline_column(id)
840
+ def node_inline_column(node)
841
+ id = node[0].to_raw
835
842
  macro('reviewcolumnref', "#{@chapter.column(id).caption}", column_label(id))
836
843
  end
837
844
 
@@ -863,7 +870,8 @@ module ReVIEW
863
870
  macro('reviewami', str)
864
871
  end
865
872
 
866
- def inline_icon(id)
873
+ def node_inline_icon(node)
874
+ id = node[0].to_raw
867
875
  macro('includegraphics', @chapter.image(id).path)
868
876
  end
869
877
 
@@ -1,5 +1,10 @@
1
1
  %% name = ReVIEW::Compiler
2
2
 
3
+ %% header {
4
+ # coding: UTF-8
5
+
6
+ }
7
+
3
8
  %% {
4
9
  class Error; end
5
10
  class Position
@@ -18,7 +23,7 @@ require 'review/preprocessor'
18
23
  require 'review/exception'
19
24
  require 'review/node'
20
25
  require 'lineinput'
21
- require 'review/compiler/literals_1_9'
26
+ # require 'review/compiler/literals_1_9'
22
27
  # require 'review/compiler/literals_1_8'
23
28
 
24
29
  ## redifine Compiler.new
@@ -734,12 +739,8 @@ EOF = !.
734
739
 
735
740
  ElementName = < LowerAlphabetAscii+ > { text }
736
741
 
737
- %literals = ReVIEW::Compiler::Literals
738
- Alphanumeric = %literals.Alphanumeric
739
- AlphanumericAscii = %literals.AlphanumericAscii
740
- LowerAlphabetAscii = %literals.LowerAlphabetAscii
741
- Digit = %literals.Digit
742
- BOM = %literals.BOM
743
- Newline = %literals.Newline:n ~newline(self, position, "\n")
744
- NonAlphanumeric = %literals.NonAlphanumeric
745
- Spacechar = %literals.Spacechar
742
+ AlphanumericAscii = /[A-Za-z0-9]/
743
+ LowerAlphabetAscii = /[a-z]/
744
+ Digit = /[0-9]/
745
+ BOM = "\uFEFF"
746
+ Newline = /\n|\r\n?|\p{Zl}|\p{Zp}/ ~newline(self, position, "\n")
@@ -1,3 +1,3 @@
1
1
  module ReVIEW
2
- VERSION = "0.1.3"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: review-peg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - kmuto
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-11-10 00:00:00.000000000 Z
12
+ date: 2015-11-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -171,8 +171,6 @@ files:
171
171
  - lib/review/builder.rb
172
172
  - lib/review/catalog.rb
173
173
  - lib/review/compiler.rb
174
- - lib/review/compiler/literals_1_9.kpeg
175
- - lib/review/compiler/literals_1_9.rb
176
174
  - lib/review/configure.rb
177
175
  - lib/review/epubbuilder.rb
178
176
  - lib/review/epubmaker.rb
@@ -1,22 +0,0 @@
1
- %% name = ReVIEW::Compiler::Literals
2
-
3
- %% header {
4
- # coding: UTF-8
5
-
6
- ##
7
- #--
8
- # This set of literals is for Ruby 1.9 regular expressions and gives full
9
- # unicode support.
10
- #
11
- # Unlike peg-markdown, this set of literals recognizes Unicode alphanumeric
12
- # characters, newlines and spaces.
13
- }
14
-
15
- Alphanumeric = /\p{Word}/
16
- AlphanumericAscii = /[A-Za-z0-9]/
17
- LowerAlphabetAscii = /[a-z]/
18
- Digit = /[0-9]/
19
- BOM = "\uFEFF"
20
- Newline = /\n|\r\n?|\p{Zl}|\p{Zp}/
21
- NonAlphanumeric = /\p{^Word}/
22
- Spacechar = /\t|\p{Zs}/
@@ -1,435 +0,0 @@
1
- # coding: UTF-8
2
-
3
- ##
4
- #--
5
- # This set of literals is for Ruby 1.9 regular expressions and gives full
6
- # unicode support.
7
- #
8
- # Unlike peg-markdown, this set of literals recognizes Unicode alphanumeric
9
- # characters, newlines and spaces.
10
- class ReVIEW::Compiler::Literals
11
- # :stopdoc:
12
-
13
- # This is distinct from setup_parser so that a standalone parser
14
- # can redefine #initialize and still have access to the proper
15
- # parser setup code.
16
- def initialize(str, debug=false)
17
- setup_parser(str, debug)
18
- end
19
-
20
-
21
-
22
- # Prepares for parsing +str+. If you define a custom initialize you must
23
- # call this method before #parse
24
- def setup_parser(str, debug=false)
25
- set_string str, 0
26
- @memoizations = Hash.new { |h,k| h[k] = {} }
27
- @result = nil
28
- @failed_rule = nil
29
- @failing_rule_offset = -1
30
-
31
- setup_foreign_grammar
32
- end
33
-
34
- attr_reader :string
35
- attr_reader :failing_rule_offset
36
- attr_accessor :result, :pos
37
-
38
- def current_column(target=pos)
39
- if c = string.rindex("\n", target-1)
40
- return target - c - 1
41
- end
42
-
43
- target + 1
44
- end
45
-
46
- def current_line(target=pos)
47
- cur_offset = 0
48
- cur_line = 0
49
-
50
- string.each_line do |line|
51
- cur_line += 1
52
- cur_offset += line.size
53
- return cur_line if cur_offset >= target
54
- end
55
-
56
- -1
57
- end
58
-
59
- def lines
60
- lines = []
61
- string.each_line { |l| lines << l }
62
- lines
63
- end
64
-
65
-
66
-
67
- def get_text(start)
68
- @string[start..@pos-1]
69
- end
70
-
71
- # Sets the string and current parsing position for the parser.
72
- def set_string string, pos
73
- @string = string
74
- @string_size = string ? string.size : 0
75
- @pos = pos
76
- end
77
-
78
- def show_pos
79
- width = 10
80
- if @pos < width
81
- "#{@pos} (\"#{@string[0,@pos]}\" @ \"#{@string[@pos,width]}\")"
82
- else
83
- "#{@pos} (\"... #{@string[@pos - width, width]}\" @ \"#{@string[@pos,width]}\")"
84
- end
85
- end
86
-
87
- def failure_info
88
- l = current_line @failing_rule_offset
89
- c = current_column @failing_rule_offset
90
-
91
- if @failed_rule.kind_of? Symbol
92
- info = self.class::Rules[@failed_rule]
93
- "line #{l}, column #{c}: failed rule '#{info.name}' = '#{info.rendered}'"
94
- else
95
- "line #{l}, column #{c}: failed rule '#{@failed_rule}'"
96
- end
97
- end
98
-
99
- def failure_caret
100
- l = current_line @failing_rule_offset
101
- c = current_column @failing_rule_offset
102
-
103
- line = lines[l-1]
104
- "#{line}\n#{' ' * (c - 1)}^"
105
- end
106
-
107
- def failure_character
108
- l = current_line @failing_rule_offset
109
- c = current_column @failing_rule_offset
110
- lines[l-1][c-1, 1]
111
- end
112
-
113
- def failure_oneline
114
- l = current_line @failing_rule_offset
115
- c = current_column @failing_rule_offset
116
-
117
- char = lines[l-1][c-1, 1]
118
-
119
- if @failed_rule.kind_of? Symbol
120
- info = self.class::Rules[@failed_rule]
121
- "@#{l}:#{c} failed rule '#{info.name}', got '#{char}'"
122
- else
123
- "@#{l}:#{c} failed rule '#{@failed_rule}', got '#{char}'"
124
- end
125
- end
126
-
127
- class ParseError < RuntimeError
128
- end
129
-
130
- def raise_error
131
- raise ParseError, failure_oneline
132
- end
133
-
134
- def show_error(io=STDOUT)
135
- error_pos = @failing_rule_offset
136
- line_no = current_line(error_pos)
137
- col_no = current_column(error_pos)
138
-
139
- io.puts "On line #{line_no}, column #{col_no}:"
140
-
141
- if @failed_rule.kind_of? Symbol
142
- info = self.class::Rules[@failed_rule]
143
- io.puts "Failed to match '#{info.rendered}' (rule '#{info.name}')"
144
- else
145
- io.puts "Failed to match rule '#{@failed_rule}'"
146
- end
147
-
148
- io.puts "Got: #{string[error_pos,1].inspect}"
149
- line = lines[line_no-1]
150
- io.puts "=> #{line}"
151
- io.print(" " * (col_no + 3))
152
- io.puts "^"
153
- end
154
-
155
- def set_failed_rule(name)
156
- if @pos > @failing_rule_offset
157
- @failed_rule = name
158
- @failing_rule_offset = @pos
159
- end
160
- end
161
-
162
- attr_reader :failed_rule
163
-
164
- def match_string(str)
165
- len = str.size
166
- if @string[pos,len] == str
167
- @pos += len
168
- return str
169
- end
170
-
171
- return nil
172
- end
173
-
174
- def scan(reg)
175
- if m = reg.match(@string[@pos..-1])
176
- width = m.end(0)
177
- @pos += width
178
- return true
179
- end
180
-
181
- return nil
182
- end
183
-
184
- if "".respond_to? :ord
185
- def get_byte
186
- if @pos >= @string_size
187
- return nil
188
- end
189
-
190
- s = @string[@pos].ord
191
- @pos += 1
192
- s
193
- end
194
- else
195
- def get_byte
196
- if @pos >= @string_size
197
- return nil
198
- end
199
-
200
- s = @string[@pos]
201
- @pos += 1
202
- s
203
- end
204
- end
205
-
206
- def parse(rule=nil)
207
- # We invoke the rules indirectly via apply
208
- # instead of by just calling them as methods because
209
- # if the rules use left recursion, apply needs to
210
- # manage that.
211
-
212
- if !rule
213
- apply(:_root)
214
- else
215
- method = rule.gsub("-","_hyphen_")
216
- apply :"_#{method}"
217
- end
218
- end
219
-
220
- class MemoEntry
221
- def initialize(ans, pos)
222
- @ans = ans
223
- @pos = pos
224
- @result = nil
225
- @set = false
226
- @left_rec = false
227
- end
228
-
229
- attr_reader :ans, :pos, :result, :set
230
- attr_accessor :left_rec
231
-
232
- def move!(ans, pos, result)
233
- @ans = ans
234
- @pos = pos
235
- @result = result
236
- @set = true
237
- @left_rec = false
238
- end
239
- end
240
-
241
- def external_invoke(other, rule, *args)
242
- old_pos = @pos
243
- old_string = @string
244
-
245
- set_string other.string, other.pos
246
-
247
- begin
248
- if val = __send__(rule, *args)
249
- other.pos = @pos
250
- other.result = @result
251
- else
252
- other.set_failed_rule "#{self.class}##{rule}"
253
- end
254
- val
255
- ensure
256
- set_string old_string, old_pos
257
- end
258
- end
259
-
260
- def apply_with_args(rule, *args)
261
- memo_key = [rule, args]
262
- if m = @memoizations[memo_key][@pos]
263
- @pos = m.pos
264
- if !m.set
265
- m.left_rec = true
266
- return nil
267
- end
268
-
269
- @result = m.result
270
-
271
- return m.ans
272
- else
273
- m = MemoEntry.new(nil, @pos)
274
- @memoizations[memo_key][@pos] = m
275
- start_pos = @pos
276
-
277
- ans = __send__ rule, *args
278
-
279
- lr = m.left_rec
280
-
281
- m.move! ans, @pos, @result
282
-
283
- # Don't bother trying to grow the left recursion
284
- # if it's failing straight away (thus there is no seed)
285
- if ans and lr
286
- return grow_lr(rule, args, start_pos, m)
287
- else
288
- return ans
289
- end
290
-
291
- return ans
292
- end
293
- end
294
-
295
- def apply(rule)
296
- if m = @memoizations[rule][@pos]
297
- @pos = m.pos
298
- if !m.set
299
- m.left_rec = true
300
- return nil
301
- end
302
-
303
- @result = m.result
304
-
305
- return m.ans
306
- else
307
- m = MemoEntry.new(nil, @pos)
308
- @memoizations[rule][@pos] = m
309
- start_pos = @pos
310
-
311
- ans = __send__ rule
312
-
313
- lr = m.left_rec
314
-
315
- m.move! ans, @pos, @result
316
-
317
- # Don't bother trying to grow the left recursion
318
- # if it's failing straight away (thus there is no seed)
319
- if ans and lr
320
- return grow_lr(rule, nil, start_pos, m)
321
- else
322
- return ans
323
- end
324
-
325
- return ans
326
- end
327
- end
328
-
329
- def grow_lr(rule, args, start_pos, m)
330
- while true
331
- @pos = start_pos
332
- @result = m.result
333
-
334
- if args
335
- ans = __send__ rule, *args
336
- else
337
- ans = __send__ rule
338
- end
339
- return nil unless ans
340
-
341
- break if @pos <= m.pos
342
-
343
- m.move! ans, @pos, @result
344
- end
345
-
346
- @result = m.result
347
- @pos = m.pos
348
- return m.ans
349
- end
350
-
351
- class RuleInfo
352
- def initialize(name, rendered)
353
- @name = name
354
- @rendered = rendered
355
- end
356
-
357
- attr_reader :name, :rendered
358
- end
359
-
360
- def self.rule_info(name, rendered)
361
- RuleInfo.new(name, rendered)
362
- end
363
-
364
-
365
- # :startdoc:
366
- # :stopdoc:
367
- def setup_foreign_grammar; end
368
-
369
- # Alphanumeric = /\p{Word}/
370
- def _Alphanumeric
371
- _tmp = scan(/\A(?-mix:\p{Word})/)
372
- set_failed_rule :_Alphanumeric unless _tmp
373
- return _tmp
374
- end
375
-
376
- # AlphanumericAscii = /[A-Za-z0-9]/
377
- def _AlphanumericAscii
378
- _tmp = scan(/\A(?-mix:[A-Za-z0-9])/)
379
- set_failed_rule :_AlphanumericAscii unless _tmp
380
- return _tmp
381
- end
382
-
383
- # LowerAlphabetAscii = /[a-z]/
384
- def _LowerAlphabetAscii
385
- _tmp = scan(/\A(?-mix:[a-z])/)
386
- set_failed_rule :_LowerAlphabetAscii unless _tmp
387
- return _tmp
388
- end
389
-
390
- # Digit = /[0-9]/
391
- def _Digit
392
- _tmp = scan(/\A(?-mix:[0-9])/)
393
- set_failed_rule :_Digit unless _tmp
394
- return _tmp
395
- end
396
-
397
- # BOM = "uFEFF"
398
- def _BOM
399
- _tmp = match_string("uFEFF")
400
- set_failed_rule :_BOM unless _tmp
401
- return _tmp
402
- end
403
-
404
- # Newline = /\n|\r\n?|\p{Zl}|\p{Zp}/
405
- def _Newline
406
- _tmp = scan(/\A(?-mix:\n|\r\n?|\p{Zl}|\p{Zp})/)
407
- set_failed_rule :_Newline unless _tmp
408
- return _tmp
409
- end
410
-
411
- # NonAlphanumeric = /\p{^Word}/
412
- def _NonAlphanumeric
413
- _tmp = scan(/\A(?-mix:\p{^Word})/)
414
- set_failed_rule :_NonAlphanumeric unless _tmp
415
- return _tmp
416
- end
417
-
418
- # Spacechar = /\t|\p{Zs}/
419
- def _Spacechar
420
- _tmp = scan(/\A(?-mix:\t|\p{Zs})/)
421
- set_failed_rule :_Spacechar unless _tmp
422
- return _tmp
423
- end
424
-
425
- Rules = {}
426
- Rules[:_Alphanumeric] = rule_info("Alphanumeric", "/\\p{Word}/")
427
- Rules[:_AlphanumericAscii] = rule_info("AlphanumericAscii", "/[A-Za-z0-9]/")
428
- Rules[:_LowerAlphabetAscii] = rule_info("LowerAlphabetAscii", "/[a-z]/")
429
- Rules[:_Digit] = rule_info("Digit", "/[0-9]/")
430
- Rules[:_BOM] = rule_info("BOM", "\"uFEFF\"")
431
- Rules[:_Newline] = rule_info("Newline", "/\\n|\\r\\n?|\\p{Zl}|\\p{Zp}/")
432
- Rules[:_NonAlphanumeric] = rule_info("NonAlphanumeric", "/\\p{^Word}/")
433
- Rules[:_Spacechar] = rule_info("Spacechar", "/\\t|\\p{Zs}/")
434
- # :startdoc:
435
- end