review-peg 0.1.3 → 0.2.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.
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