packcr 0.0.4 → 0.0.6
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 +4 -4
- data/exe/packcr +3 -0
- data/lib/packcr/broadcast.rb +17 -0
- data/lib/packcr/cli.rb +25 -0
- data/lib/packcr/code_block.rb +2 -3
- data/lib/packcr/context.rb +59 -56
- data/lib/packcr/generator.rb +13 -11
- data/lib/packcr/node/action_node.rb +14 -5
- data/lib/packcr/node/alternate_node.rb +20 -12
- data/lib/packcr/node/capture_node.rb +11 -11
- data/lib/packcr/node/charclass_node.rb +37 -13
- data/lib/packcr/node/eof_node.rb +23 -0
- data/lib/packcr/node/error_node.rb +17 -12
- data/lib/packcr/node/expand_node.rb +11 -5
- data/lib/packcr/node/predicate_node.rb +15 -24
- data/lib/packcr/node/quantity_node.rb +23 -18
- data/lib/packcr/node/reference_node.rb +21 -5
- data/lib/packcr/node/root_node.rb +60 -0
- data/lib/packcr/node/rule_node.rb +26 -3
- data/lib/packcr/node/sequence_node.rb +46 -31
- data/lib/packcr/node/string_node.rb +12 -12
- data/lib/packcr/node.rb +35 -4
- data/lib/packcr/parser.rb +2939 -2661
- data/lib/packcr/stream.rb +8 -13
- data/lib/packcr/templates/context/header.c.erb +29 -0
- data/lib/packcr/templates/context/source.c.erb +1292 -0
- data/lib/packcr/templates/context/source.rb.erb +406 -0
- data/lib/packcr/templates/node/action.c.erb +16 -0
- data/lib/packcr/templates/node/action.rb.erb +21 -0
- data/lib/packcr/templates/node/alternate.c.erb +34 -0
- data/lib/packcr/templates/node/alternate.rb.erb +40 -0
- data/lib/packcr/templates/node/capture.c.erb +17 -0
- data/lib/packcr/templates/node/capture.rb.erb +14 -0
- data/lib/packcr/templates/node/charclass.c.erb +47 -0
- data/lib/packcr/templates/node/charclass.rb.erb +49 -0
- data/lib/packcr/templates/node/charclass_any.c.erb +5 -0
- data/lib/packcr/templates/node/charclass_any.rb.erb +7 -0
- data/lib/packcr/templates/node/charclass_fail.c.erb +1 -0
- data/lib/packcr/templates/node/charclass_fail.rb.erb +1 -0
- data/lib/packcr/templates/node/charclass_one.c.erb +19 -0
- data/lib/packcr/templates/node/charclass_one.rb.erb +23 -0
- data/lib/packcr/templates/node/charclass_utf8.c.erb +49 -0
- data/lib/packcr/templates/node/charclass_utf8.rb.erb +50 -0
- data/lib/packcr/templates/node/charclass_utf8_reverse.rb.erb +51 -0
- data/lib/packcr/templates/node/eof.c.erb +1 -0
- data/lib/packcr/templates/node/eof.rb.erb +3 -0
- data/lib/packcr/templates/node/error.c.erb +28 -0
- data/lib/packcr/templates/node/error.rb.erb +34 -0
- data/lib/packcr/templates/node/expand.c.erb +16 -0
- data/lib/packcr/templates/node/expand.rb.erb +16 -0
- data/lib/packcr/templates/node/predicate.c.erb +30 -0
- data/lib/packcr/templates/node/predicate.rb.erb +28 -0
- data/lib/packcr/templates/node/predicate_neg.c.erb +23 -0
- data/lib/packcr/templates/node/predicate_neg.rb.erb +22 -0
- data/lib/packcr/templates/node/quantify_many.c.erb +45 -0
- data/lib/packcr/templates/node/quantify_many.rb.erb +47 -0
- data/lib/packcr/templates/node/quantify_one.c.erb +21 -0
- data/lib/packcr/templates/node/quantify_one.rb.erb +23 -0
- data/lib/packcr/templates/node/reference.c.erb +5 -0
- data/lib/packcr/templates/node/reference.rb.erb +9 -0
- data/lib/packcr/templates/node/reference_reverse.rb.erb +9 -0
- data/lib/packcr/templates/node/rule.c.erb +19 -0
- data/lib/packcr/templates/node/rule.rb.erb +23 -0
- data/lib/packcr/templates/node/sequence.c.erb +12 -0
- data/lib/packcr/templates/node/sequence.rb.erb +12 -0
- data/lib/packcr/templates/node/string_many.c.erb +11 -0
- data/lib/packcr/templates/node/string_many.rb.erb +10 -0
- data/lib/packcr/templates/node/string_one.c.erb +8 -0
- data/lib/packcr/templates/node/string_one.rb.erb +10 -0
- data/lib/packcr/tokenizer.rb +2948 -0
- data/lib/packcr/util.rb +0 -8
- data/lib/packcr/version.rb +1 -1
- data/lib/packcr.rb +1 -2
- metadata +87 -8
- data/lib/packcr/buffer.rb +0 -47
| @@ -0,0 +1,406 @@ | |
| 1 | 
            +
            # A packrat parser generated by PackCR <%= Packcr::VERSION %>
         | 
| 2 | 
            +
            <%- if !code(:source).empty? -%>
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            <%-   code(:source).each do |code| -%>
         | 
| 5 | 
            +
            <%=     stream.get_code_block(code, 0, @iname) -%>
         | 
| 6 | 
            +
            <%-   end -%>
         | 
| 7 | 
            +
            <%- end -%>
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            class <%= class_name %>
         | 
| 10 | 
            +
              def initialize(<% if @auxil_type %><%= auxil_type %>, <% end %>debug: false)
         | 
| 11 | 
            +
                <%- if @utf8 -%>
         | 
| 12 | 
            +
                @buffer = +""
         | 
| 13 | 
            +
                <%- else -%>
         | 
| 14 | 
            +
                @buffer = +"".b
         | 
| 15 | 
            +
                <%- end %>
         | 
| 16 | 
            +
                @pos = 0
         | 
| 17 | 
            +
                @cur = 0
         | 
| 18 | 
            +
                @level = 0
         | 
| 19 | 
            +
                @lrstack = []
         | 
| 20 | 
            +
                @thunk = ThunkNode.new([], nil, 0)
         | 
| 21 | 
            +
                @heads = {}
         | 
| 22 | 
            +
                @memos = LrMemoTable.new
         | 
| 23 | 
            +
                @debug = debug
         | 
| 24 | 
            +
                @global_values = {}
         | 
| 25 | 
            +
                <%- if @location -%>
         | 
| 26 | 
            +
                @pos_loc = Location.new
         | 
| 27 | 
            +
                @cur_loc = Location.new
         | 
| 28 | 
            +
                <%- end -%>
         | 
| 29 | 
            +
                <%- code(:init).each do |code| -%>
         | 
| 30 | 
            +
                <%- %><%= stream.get_code_block(code, 4, @iname) -%>
         | 
| 31 | 
            +
                <%- end -%>
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              def debug
         | 
| 35 | 
            +
                yield if @debug
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              def getc
         | 
| 39 | 
            +
                <%- if @utf8 -%>
         | 
| 40 | 
            +
                $stdin.getc
         | 
| 41 | 
            +
                <%- else -%>
         | 
| 42 | 
            +
                $stdin.getc&.b
         | 
| 43 | 
            +
                <%- end -%>
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
              def refill_buffer(num, mode = nil)
         | 
| 47 | 
            +
                len = @buffer.length
         | 
| 48 | 
            +
                if len >= @cur + num
         | 
| 49 | 
            +
                  return len - @cur
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
                while len < @cur + num
         | 
| 52 | 
            +
                  c = getc
         | 
| 53 | 
            +
                  break if !c
         | 
| 54 | 
            +
                  @buffer << c
         | 
| 55 | 
            +
                  len = @buffer.length
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
                return len - @cur
         | 
| 58 | 
            +
              end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
              def commit_buffer
         | 
| 61 | 
            +
                @buffer = @buffer[@cur, @buffer.length - @cur]
         | 
| 62 | 
            +
                @pos += @cur
         | 
| 63 | 
            +
                @heads.clear
         | 
| 64 | 
            +
                @memos.clear
         | 
| 65 | 
            +
                @cur = 0
         | 
| 66 | 
            +
                <%- if @location -%>
         | 
| 67 | 
            +
                @pos_loc = @pos_loc + @cur_loc
         | 
| 68 | 
            +
                @cur_loc = Location.new
         | 
| 69 | 
            +
                <%- end -%>
         | 
| 70 | 
            +
              end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
              def parse
         | 
| 73 | 
            +
                pos = @pos
         | 
| 74 | 
            +
                <%- if !@root.rules.empty? -%>
         | 
| 75 | 
            +
                if apply_rule(:evaluate_rule_<%= @root.rules[0].name %>, @thunk.thunks, nil, 0)
         | 
| 76 | 
            +
                  @thunk.do_action(self, nil, 0)
         | 
| 77 | 
            +
                else
         | 
| 78 | 
            +
                  raise SyntaxError, "can't parse"
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
                commit_buffer
         | 
| 81 | 
            +
                <%- end -%>
         | 
| 82 | 
            +
                @thunk.clear
         | 
| 83 | 
            +
                refill_buffer(1) >= 1 && pos != @pos
         | 
| 84 | 
            +
              end
         | 
| 85 | 
            +
             | 
| 86 | 
            +
              def run
         | 
| 87 | 
            +
                nil while parse
         | 
| 88 | 
            +
              end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
              <%- @root.rules.each do |rule| -%>
         | 
| 91 | 
            +
              <%-   rule.codes.each do |code| -%>
         | 
| 92 | 
            +
              def action_<%= rule.name %>_<%= code.index %>(__pcc_in, __pcc_vars, __pcc_index)
         | 
| 93 | 
            +
                ____ = (__pcc_vars[__pcc_index] ||= Value.new).value if __pcc_vars
         | 
| 94 | 
            +
                <%-   code.vars.each do |ref| -%>
         | 
| 95 | 
            +
                <%= ref.var %> = (__pcc_in.value_refs[<%= ref.index %>]  ||= Value.new).value
         | 
| 96 | 
            +
                <%-   end -%>
         | 
| 97 | 
            +
                __0 = __pcc_in.capt0.capture_string(@buffer)
         | 
| 98 | 
            +
                __0s = @pos + __pcc_in.capt0.range_start
         | 
| 99 | 
            +
                __0e = @pos + __pcc_in.capt0.range_end
         | 
| 100 | 
            +
                <%-   if @location -%>
         | 
| 101 | 
            +
                __0sl = @pos_loc + __pcc_in.capt0.start_loc
         | 
| 102 | 
            +
                __0el = @pos_loc + __pcc_in.capt0.end_loc
         | 
| 103 | 
            +
                <%-   end -%>
         | 
| 104 | 
            +
                <%-   if @capture_in_code -%>
         | 
| 105 | 
            +
                __0c = __pcc_in.capt0
         | 
| 106 | 
            +
                <%-   end -%>
         | 
| 107 | 
            +
                <%-   code.capts.each do |capture| -%>
         | 
| 108 | 
            +
                __<%= capture.index + 1 %> = __pcc_in.capts[<%= capture.index %>].capture_string(@buffer)
         | 
| 109 | 
            +
                __<%= capture.index + 1 %>s = @pos + __pcc_in.capts[<%= capture.index %>].range_start
         | 
| 110 | 
            +
                __<%= capture.index + 1 %>e = @pos + __pcc_in.capts[<%= capture.index %>].range_end
         | 
| 111 | 
            +
                <%-     if @location -%>
         | 
| 112 | 
            +
                __<%= capture.index + 1 %>sl = @pos_loc + __pcc_in.capts[<%= capture.index %>].start_loc
         | 
| 113 | 
            +
                __<%= capture.index + 1 %>el = @pos_loc + __pcc_in.capts[<%= capture.index %>].end_loc
         | 
| 114 | 
            +
                <%-     end -%>
         | 
| 115 | 
            +
                <%-     if @capture_in_code -%>
         | 
| 116 | 
            +
                __<%= capture.index + 1 %>c = __pcc_in.capts[<%= capture.index %>]
         | 
| 117 | 
            +
                <%-     end -%>
         | 
| 118 | 
            +
                <%-   end -%>
         | 
| 119 | 
            +
                <%- %><%=   stream.get_code_block(code.code, 4, @iname) -%>
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                __pcc_vars[__pcc_index].value = ____ if __pcc_vars
         | 
| 122 | 
            +
              end
         | 
| 123 | 
            +
             | 
| 124 | 
            +
              <%-   end -%>
         | 
| 125 | 
            +
              <%- end -%>
         | 
| 126 | 
            +
              <%- @root.rules.each do |rule| -%>
         | 
| 127 | 
            +
              def evaluate_rule_<%= rule.name %>
         | 
| 128 | 
            +
                answer = ThunkChunk.new
         | 
| 129 | 
            +
                answer.pos = @cur
         | 
| 130 | 
            +
                <%-   if @location -%>
         | 
| 131 | 
            +
                answer.pos_loc = @cur_loc
         | 
| 132 | 
            +
                <%-   end -%>
         | 
| 133 | 
            +
                <%-   gen = ::Packcr::Generator.new(rule, @ascii, @location, :rb) -%>
         | 
| 134 | 
            +
                <%-   -%><%= gen.generate_code(rule, 0, 4, false) -%>
         | 
| 135 | 
            +
              end
         | 
| 136 | 
            +
             | 
| 137 | 
            +
              <%- end -%>
         | 
| 138 | 
            +
              def setup_lr(rule, lr)
         | 
| 139 | 
            +
                lr.head ||= LrHead.new(rule)
         | 
| 140 | 
            +
                @lrstack.reverse_each do |lrentry|
         | 
| 141 | 
            +
                  if lrentry.head == lr.head
         | 
| 142 | 
            +
                    break
         | 
| 143 | 
            +
                  end
         | 
| 144 | 
            +
                  lrentry.head = lr.head
         | 
| 145 | 
            +
                  lr.head.involved_set[lrentry.rule] = true
         | 
| 146 | 
            +
                end
         | 
| 147 | 
            +
              end
         | 
| 148 | 
            +
             | 
| 149 | 
            +
              def grow_lr(rule, memo, head, pos<% if @location %>, p_loc<% end %>)
         | 
| 150 | 
            +
                @heads[pos] = head
         | 
| 151 | 
            +
                while true
         | 
| 152 | 
            +
                  @cur = pos - @pos
         | 
| 153 | 
            +
                  <%- if @location -%>
         | 
| 154 | 
            +
                  @cur_loc = p_loc - @pos_loc
         | 
| 155 | 
            +
                  <%- end -%>
         | 
| 156 | 
            +
                  head.involved_set_to_eval_set
         | 
| 157 | 
            +
                  answer = public_send(rule)
         | 
| 158 | 
            +
                  if !answer || @pos + @cur <= memo.pos
         | 
| 159 | 
            +
                    break
         | 
| 160 | 
            +
                  end
         | 
| 161 | 
            +
                  memo.answer = answer
         | 
| 162 | 
            +
                  memo.pos = @pos + @cur
         | 
| 163 | 
            +
                  <%- if @location -%>
         | 
| 164 | 
            +
                  memo.pos_loc = @pos_loc + @cur_loc
         | 
| 165 | 
            +
                  <%- end -%>
         | 
| 166 | 
            +
                end
         | 
| 167 | 
            +
                @heads[pos] = nil
         | 
| 168 | 
            +
                @cur = memo.pos - @pos
         | 
| 169 | 
            +
                <%- if @location -%>
         | 
| 170 | 
            +
                @cur_loc = memo.pos_loc - @pos_loc
         | 
| 171 | 
            +
                <%- end -%>
         | 
| 172 | 
            +
                memo.answer
         | 
| 173 | 
            +
              end
         | 
| 174 | 
            +
             | 
| 175 | 
            +
              def lr_answer(rule, memo, pos<% if @location %>, p_loc<% end %>)
         | 
| 176 | 
            +
                head = memo.lr.head
         | 
| 177 | 
            +
                if head.rule_name != rule
         | 
| 178 | 
            +
                  return memo.lr.seed
         | 
| 179 | 
            +
                end
         | 
| 180 | 
            +
             | 
| 181 | 
            +
                memo.answer = memo.lr.seed
         | 
| 182 | 
            +
                if !memo.answer
         | 
| 183 | 
            +
                  return nil
         | 
| 184 | 
            +
                end
         | 
| 185 | 
            +
                grow_lr(rule, memo, head, pos<% if @location %>, p_loc<% end %>)
         | 
| 186 | 
            +
              end
         | 
| 187 | 
            +
             | 
| 188 | 
            +
              def rule_answer(rule)
         | 
| 189 | 
            +
                pos = @pos + @cur
         | 
| 190 | 
            +
                <%- if @location -%>
         | 
| 191 | 
            +
                p_loc = @pos_loc + @cur_loc
         | 
| 192 | 
            +
                <%- end -%>
         | 
| 193 | 
            +
                memo = @memos[pos, rule]
         | 
| 194 | 
            +
                head = @heads[pos]
         | 
| 195 | 
            +
             | 
| 196 | 
            +
                if head
         | 
| 197 | 
            +
                  if !memo && rule != head.rule_name && !head.involved_set[rule]
         | 
| 198 | 
            +
                    return nil
         | 
| 199 | 
            +
                  end
         | 
| 200 | 
            +
                  if head.eval_set.delete(rule)
         | 
| 201 | 
            +
                    return public_send(rule)
         | 
| 202 | 
            +
                  end
         | 
| 203 | 
            +
                end
         | 
| 204 | 
            +
             | 
| 205 | 
            +
                if memo
         | 
| 206 | 
            +
                  @cur = memo.pos - @pos
         | 
| 207 | 
            +
                  <%- if @location -%>
         | 
| 208 | 
            +
                  @cur_loc = memo.pos_loc - @pos_loc
         | 
| 209 | 
            +
                  <%- end -%>
         | 
| 210 | 
            +
                  if !memo.lr
         | 
| 211 | 
            +
                    return memo.answer
         | 
| 212 | 
            +
                  end
         | 
| 213 | 
            +
                  setup_lr(rule, memo.lr)
         | 
| 214 | 
            +
                  return memo.lr.seed
         | 
| 215 | 
            +
                end
         | 
| 216 | 
            +
             | 
| 217 | 
            +
                lr = LrEntry.new
         | 
| 218 | 
            +
                lr.rule = rule
         | 
| 219 | 
            +
                @lrstack.push(lr)
         | 
| 220 | 
            +
                memo = LrMemo.new(lr, pos<% if @location %>, p_loc<% end %>)
         | 
| 221 | 
            +
                @memos[pos, rule] = memo
         | 
| 222 | 
            +
                answer = public_send(rule)
         | 
| 223 | 
            +
                @lrstack.pop
         | 
| 224 | 
            +
                memo.pos = @pos + @cur
         | 
| 225 | 
            +
                <%- if @location -%>
         | 
| 226 | 
            +
                memo.pos_loc = @pos_loc + @cur_loc
         | 
| 227 | 
            +
                <%- end -%>
         | 
| 228 | 
            +
                if !lr.head
         | 
| 229 | 
            +
                  memo.answer = answer
         | 
| 230 | 
            +
                  return answer
         | 
| 231 | 
            +
                end
         | 
| 232 | 
            +
             | 
| 233 | 
            +
                lr.seed = answer
         | 
| 234 | 
            +
                lr_answer(rule, memo, pos<% if @location %>, p_loc<% end %>)
         | 
| 235 | 
            +
              end
         | 
| 236 | 
            +
             | 
| 237 | 
            +
              def apply_rule(rule, thunks, values, index)
         | 
| 238 | 
            +
                answer = rule_answer(rule)
         | 
| 239 | 
            +
                if !answer
         | 
| 240 | 
            +
                  return false
         | 
| 241 | 
            +
                end
         | 
| 242 | 
            +
                values ||= @global_values
         | 
| 243 | 
            +
                thunks << ThunkNode.new(answer.thunks, values, index)
         | 
| 244 | 
            +
                return true
         | 
| 245 | 
            +
              end
         | 
| 246 | 
            +
             | 
| 247 | 
            +
              def do_action(thunks, values, index)
         | 
| 248 | 
            +
                thunks.each do |thunk|
         | 
| 249 | 
            +
                  thunk.do_action(self, values, index)
         | 
| 250 | 
            +
                end
         | 
| 251 | 
            +
              end
         | 
| 252 | 
            +
             | 
| 253 | 
            +
              <%-   code(:location).each do |code| -%>
         | 
| 254 | 
            +
              <%- %><%= stream.get_code_block(code, 2, @iname) -%>
         | 
| 255 | 
            +
             | 
| 256 | 
            +
              <%-   end -%>
         | 
| 257 | 
            +
              class LrMemoTable
         | 
| 258 | 
            +
                def initialize
         | 
| 259 | 
            +
                  @memos = {}
         | 
| 260 | 
            +
                end
         | 
| 261 | 
            +
             | 
| 262 | 
            +
                def clear
         | 
| 263 | 
            +
                  @memos.clear
         | 
| 264 | 
            +
                end
         | 
| 265 | 
            +
             | 
| 266 | 
            +
                def []=(index, rule_name, memo)
         | 
| 267 | 
            +
                  entry = @memos[index] ||= {}
         | 
| 268 | 
            +
                  entry[rule_name] = memo
         | 
| 269 | 
            +
                end
         | 
| 270 | 
            +
             | 
| 271 | 
            +
                def [](index, rule_name)
         | 
| 272 | 
            +
                  @memos.dig(index, rule_name)
         | 
| 273 | 
            +
                end
         | 
| 274 | 
            +
              end
         | 
| 275 | 
            +
             | 
| 276 | 
            +
              class LrHead
         | 
| 277 | 
            +
                attr_accessor :rule_name, :involved_set, :eval_set
         | 
| 278 | 
            +
             | 
| 279 | 
            +
                def initialize(rule_name)
         | 
| 280 | 
            +
                  @rule_name = rule_name
         | 
| 281 | 
            +
                  @involved_set = {}
         | 
| 282 | 
            +
                  @eval_set = {}
         | 
| 283 | 
            +
                end
         | 
| 284 | 
            +
             | 
| 285 | 
            +
                def involved_set_to_eval_set
         | 
| 286 | 
            +
                  @eval_set.clear
         | 
| 287 | 
            +
                  @involved_set.each do |k, v|
         | 
| 288 | 
            +
                    @eval_set[k] = true
         | 
| 289 | 
            +
                  end
         | 
| 290 | 
            +
                end
         | 
| 291 | 
            +
              end
         | 
| 292 | 
            +
             | 
| 293 | 
            +
              class ThunkChunk
         | 
| 294 | 
            +
                attr_accessor :thunks, :capts, :pos, :values
         | 
| 295 | 
            +
                <%- if @location -%>
         | 
| 296 | 
            +
                attr_accessor :pos_loc
         | 
| 297 | 
            +
                <%- end -%>
         | 
| 298 | 
            +
             | 
| 299 | 
            +
                def initialize
         | 
| 300 | 
            +
                  super
         | 
| 301 | 
            +
                  @thunks = []
         | 
| 302 | 
            +
                  @capts = {}
         | 
| 303 | 
            +
                  @pos = 0
         | 
| 304 | 
            +
                  @values = {}
         | 
| 305 | 
            +
                end
         | 
| 306 | 
            +
             | 
| 307 | 
            +
                def resize_captures(len)
         | 
| 308 | 
            +
                  len.times do |i|
         | 
| 309 | 
            +
                    @capts[i] = Capture.new
         | 
| 310 | 
            +
                  end
         | 
| 311 | 
            +
                end
         | 
| 312 | 
            +
              end
         | 
| 313 | 
            +
             | 
| 314 | 
            +
              class Thunk
         | 
| 315 | 
            +
              end
         | 
| 316 | 
            +
             | 
| 317 | 
            +
              class ThunkLeaf < Thunk
         | 
| 318 | 
            +
                attr_accessor :capt0, :capts, :value_refs, :action
         | 
| 319 | 
            +
             | 
| 320 | 
            +
                def initialize(action, capt0 = Capture.new, value_refs = {}, capts = {})
         | 
| 321 | 
            +
                  @value_refs = value_refs
         | 
| 322 | 
            +
                  @capts = capts
         | 
| 323 | 
            +
                  @capt0 = capt0
         | 
| 324 | 
            +
                  @action = action
         | 
| 325 | 
            +
                end
         | 
| 326 | 
            +
             | 
| 327 | 
            +
                def do_action(ctx, values, index)
         | 
| 328 | 
            +
                  ctx.public_send(action, self, values, index)
         | 
| 329 | 
            +
                end
         | 
| 330 | 
            +
              end
         | 
| 331 | 
            +
             | 
| 332 | 
            +
              class ThunkNode < Thunk
         | 
| 333 | 
            +
                attr_accessor :thunks, :values, :index
         | 
| 334 | 
            +
             | 
| 335 | 
            +
                def initialize(thunks, values, index)
         | 
| 336 | 
            +
                  @thunks = thunks
         | 
| 337 | 
            +
                  @values = values
         | 
| 338 | 
            +
                  @index = index
         | 
| 339 | 
            +
                  values[index] ||= Value.new if values
         | 
| 340 | 
            +
                end
         | 
| 341 | 
            +
             | 
| 342 | 
            +
                def do_action(ctx, _values, _index)
         | 
| 343 | 
            +
                  @thunks.each do |thunk|
         | 
| 344 | 
            +
                    thunk.do_action(ctx, @values, @index)
         | 
| 345 | 
            +
                  end
         | 
| 346 | 
            +
                end
         | 
| 347 | 
            +
             | 
| 348 | 
            +
                def clear
         | 
| 349 | 
            +
                  @thunks.clear
         | 
| 350 | 
            +
                end
         | 
| 351 | 
            +
              end
         | 
| 352 | 
            +
             | 
| 353 | 
            +
              class LrEntry
         | 
| 354 | 
            +
                attr_accessor :rule, :head, :seed
         | 
| 355 | 
            +
              end
         | 
| 356 | 
            +
             | 
| 357 | 
            +
              class Capture
         | 
| 358 | 
            +
                attr_accessor :range_start, :range_end
         | 
| 359 | 
            +
                <%- if @location -%>
         | 
| 360 | 
            +
                attr_accessor :start_loc, :end_loc
         | 
| 361 | 
            +
                <%- end -%>
         | 
| 362 | 
            +
             | 
| 363 | 
            +
                def initialize(range_start = 0, range_end = 0<% if @location %>, start_loc = nil, end_loc = nil<% end%>)
         | 
| 364 | 
            +
                  @range_start = range_start
         | 
| 365 | 
            +
                  @range_end = range_end
         | 
| 366 | 
            +
                  <%- if @location -%>
         | 
| 367 | 
            +
                  @start_loc = start_loc || Location.new
         | 
| 368 | 
            +
                  @end_loc = end_loc || Location.new
         | 
| 369 | 
            +
                  <%- end -%>
         | 
| 370 | 
            +
                end
         | 
| 371 | 
            +
             | 
| 372 | 
            +
                def capture_string(buffer)
         | 
| 373 | 
            +
                  @string ||= buffer[@range_start, @range_end - @range_start]
         | 
| 374 | 
            +
                end
         | 
| 375 | 
            +
              end
         | 
| 376 | 
            +
             | 
| 377 | 
            +
              class LrMemo
         | 
| 378 | 
            +
                attr_accessor :lr, :answer, :pos
         | 
| 379 | 
            +
                <%- if @location -%>
         | 
| 380 | 
            +
                attr_accessor :pos_loc
         | 
| 381 | 
            +
                <%- end -%>
         | 
| 382 | 
            +
             | 
| 383 | 
            +
                def initialize(lr, pos<% if @location %>, pos_loc<% end %>)
         | 
| 384 | 
            +
                  @pos = pos
         | 
| 385 | 
            +
                  <%- if @location -%>
         | 
| 386 | 
            +
                  @pos_loc = pos_loc
         | 
| 387 | 
            +
                  <%- end -%>
         | 
| 388 | 
            +
                  @lr = lr
         | 
| 389 | 
            +
                end
         | 
| 390 | 
            +
             | 
| 391 | 
            +
                def answer=(answer)
         | 
| 392 | 
            +
                  @lr = nil
         | 
| 393 | 
            +
                  @answer = answer
         | 
| 394 | 
            +
                end
         | 
| 395 | 
            +
              end
         | 
| 396 | 
            +
             | 
| 397 | 
            +
              class Value
         | 
| 398 | 
            +
                attr_accessor :value
         | 
| 399 | 
            +
              end
         | 
| 400 | 
            +
            end
         | 
| 401 | 
            +
            <%- if !code(:lsource).empty? -%>
         | 
| 402 | 
            +
             | 
| 403 | 
            +
            <%-   code(:lsource).each do |code| -%>
         | 
| 404 | 
            +
            <%=     stream.get_code_block(code, 0, @iname) -%>
         | 
| 405 | 
            +
            <%-   end -%>
         | 
| 406 | 
            +
            <%- end -%>
         | 
| @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            {
         | 
| 2 | 
            +
                pcc_thunk_t *const thunk = pcc_thunk__create_leaf(ctx->auxil, pcc_action_<%= gen.rule.name %>_<%= index %>, <%= gen.rule.vars.length %>, <%= gen.rule.capts.length %>);
         | 
| 3 | 
            +
            <%- vars.each do |var| -%>
         | 
| 4 | 
            +
                thunk->data.leaf.values.buf[<%= var.index %>] = &(chunk->values.buf[<%= var.index %>]);
         | 
| 5 | 
            +
            <%- end -%>
         | 
| 6 | 
            +
            <%- capts.each do |capt| -%>
         | 
| 7 | 
            +
                thunk->data.leaf.capts.buf[<%= capt.index %>] = &(chunk->capts.buf[<%= capt.index %>]);
         | 
| 8 | 
            +
            <%- end -%>
         | 
| 9 | 
            +
                thunk->data.leaf.capt0.range.start = chunk->pos;
         | 
| 10 | 
            +
                thunk->data.leaf.capt0.range.end = ctx->cur;
         | 
| 11 | 
            +
            <%- if gen.location -%>
         | 
| 12 | 
            +
                thunk->data.leaf.capt0.range.start_loc_ptr = &chunk->pos_loc;
         | 
| 13 | 
            +
                thunk->data.leaf.capt0.range.end_loc_ptr = &ctx->cur_loc;
         | 
| 14 | 
            +
            <%- end -%>
         | 
| 15 | 
            +
                pcc_thunk_array__add(ctx->auxil, &chunk->thunks, thunk);
         | 
| 16 | 
            +
            }
         | 
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            answer.thunks.push(
         | 
| 2 | 
            +
              ThunkLeaf.new(
         | 
| 3 | 
            +
                :action_<%= gen.rule.name %>_<%= index %>,
         | 
| 4 | 
            +
                Capture.new(
         | 
| 5 | 
            +
                  answer.pos, @cur,
         | 
| 6 | 
            +
                  <%- if gen.location -%>
         | 
| 7 | 
            +
                  answer.pos_loc, @cur_loc,
         | 
| 8 | 
            +
                  <%- end -%>
         | 
| 9 | 
            +
                ),
         | 
| 10 | 
            +
                <%- if vars.empty? -%>
         | 
| 11 | 
            +
                {},
         | 
| 12 | 
            +
                <%- else -%>
         | 
| 13 | 
            +
                answer.values.slice(<% vars.each_with_index do |var, i| %><%= ", " if i > 0 %><%= var.index %><% end %>),
         | 
| 14 | 
            +
                <%- end -%>
         | 
| 15 | 
            +
                <%- if capts.empty? -%>
         | 
| 16 | 
            +
                {},
         | 
| 17 | 
            +
                <%- else -%>
         | 
| 18 | 
            +
                answer.capts.slice(<% capts.each_with_index do |capt, i| %><%= ", " if i > 0 %><%= capt.index %><% end %>),
         | 
| 19 | 
            +
                <%- end -%>
         | 
| 20 | 
            +
              )
         | 
| 21 | 
            +
            )
         | 
| @@ -0,0 +1,34 @@ | |
| 1 | 
            +
            <%-   m = gen.next_label -%>
         | 
| 2 | 
            +
            {
         | 
| 3 | 
            +
                const size_t p = ctx->cur;
         | 
| 4 | 
            +
            <%- if gen.location -%>
         | 
| 5 | 
            +
                const pcc_location_t p_loc = ctx->cur_loc;
         | 
| 6 | 
            +
            <%- end -%>
         | 
| 7 | 
            +
                const size_t n = chunk->thunks.len;
         | 
| 8 | 
            +
            <%- nodes.each_with_index do |expr, i| -%>
         | 
| 9 | 
            +
            <%-   c = i + 1 < nodes.length -%>
         | 
| 10 | 
            +
            <%-   l = gen.next_label -%>
         | 
| 11 | 
            +
            <%-   r = expr.reachability -%>
         | 
| 12 | 
            +
            <%-   -%><%= gen.generate_code(expr, l, 4, false) -%>
         | 
| 13 | 
            +
            <%-   if r == Packcr::CODE_REACH__ALWAYS_SUCCEED -%>
         | 
| 14 | 
            +
            <%-     if c -%>
         | 
| 15 | 
            +
                /* unreachable codes omitted */
         | 
| 16 | 
            +
            <%-     end -%>
         | 
| 17 | 
            +
            <%-     break -%>
         | 
| 18 | 
            +
            <%-   else -%>
         | 
| 19 | 
            +
            <%-     if r == Packcr::CODE_REACH__BOTH -%>
         | 
| 20 | 
            +
                goto L<%= "%04d" % m %>;
         | 
| 21 | 
            +
            <%-     end -%>
         | 
| 22 | 
            +
            <%-   end -%>
         | 
| 23 | 
            +
            L<%= "%04d" % l %>:;
         | 
| 24 | 
            +
                ctx->cur = p;
         | 
| 25 | 
            +
            <%- if gen.location -%>
         | 
| 26 | 
            +
                ctx->cur_loc = p_loc;
         | 
| 27 | 
            +
            <%- end -%>
         | 
| 28 | 
            +
                pcc_thunk_array__revert(ctx->auxil, &chunk->thunks, n);
         | 
| 29 | 
            +
            <%-   if !c -%>
         | 
| 30 | 
            +
                goto L<%= "%04d" % onfail %>;
         | 
| 31 | 
            +
            <%-   end -%>
         | 
| 32 | 
            +
            <%- end -%>
         | 
| 33 | 
            +
            L<%= "%04d" % m %>:;
         | 
| 34 | 
            +
            }
         | 
| @@ -0,0 +1,40 @@ | |
| 1 | 
            +
            <%-   m = gen.next_label -%>
         | 
| 2 | 
            +
            catch(<%= m %>) do
         | 
| 3 | 
            +
              pos<%= gen.level %> = @cur
         | 
| 4 | 
            +
              <%- if gen.location -%>
         | 
| 5 | 
            +
              p_loc<%= gen.level %> = @cur_loc
         | 
| 6 | 
            +
              <%- end -%>
         | 
| 7 | 
            +
              n<%= gen.level %> = answer.thunks.length
         | 
| 8 | 
            +
              <%- nodes.each_with_index do |expr, i| -%>
         | 
| 9 | 
            +
              <%-   c = i + 1 < nodes.length -%>
         | 
| 10 | 
            +
              <%- if expr.reversible?(gen) -%>
         | 
| 11 | 
            +
              <%-   r = expr.reachability -%>
         | 
| 12 | 
            +
              <%-   %><%= gen.generate_code(expr, m, 2, false, reverse: true, oncut: onfail) -%>
         | 
| 13 | 
            +
              <%- else -%>
         | 
| 14 | 
            +
              <%-   l = gen.next_label -%>
         | 
| 15 | 
            +
              catch(<%= l %>) do
         | 
| 16 | 
            +
                <%-   r = expr.reachability -%>
         | 
| 17 | 
            +
                <%-   %><%= gen.generate_code(expr, l, 4, false, oncut: onfail) -%>
         | 
| 18 | 
            +
                <%-   if r == Packcr::CODE_REACH__ALWAYS_SUCCEED -%>
         | 
| 19 | 
            +
                <%-     if c -%>
         | 
| 20 | 
            +
                # unreachable codes omitted
         | 
| 21 | 
            +
                <%-     end -%>
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
                <%-     break -%>
         | 
| 24 | 
            +
                <%-   else -%>
         | 
| 25 | 
            +
                <%-     if r == Packcr::CODE_REACH__BOTH -%>
         | 
| 26 | 
            +
                throw(<%= m %>)
         | 
| 27 | 
            +
                <%-     end -%>
         | 
| 28 | 
            +
                <%-   end -%>
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
              <%- end -%>
         | 
| 31 | 
            +
              @cur = pos<%= gen.level %>
         | 
| 32 | 
            +
              <%- if gen.location -%>
         | 
| 33 | 
            +
              @cur_loc = p_loc<%= gen.level %>
         | 
| 34 | 
            +
              <%- end -%>
         | 
| 35 | 
            +
              answer.thunks[n<%= gen.level %>..-1] = []
         | 
| 36 | 
            +
              <%-   if !c -%>
         | 
| 37 | 
            +
              throw(<%= onfail %>)
         | 
| 38 | 
            +
              <%-   end -%>
         | 
| 39 | 
            +
              <%- end -%>
         | 
| 40 | 
            +
            end
         | 
| @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            {
         | 
| 2 | 
            +
                const size_t p = ctx->cur;
         | 
| 3 | 
            +
                size_t q;
         | 
| 4 | 
            +
            <%- if gen.location -%>
         | 
| 5 | 
            +
                pcc_location_t p_loc = ctx->cur_loc;
         | 
| 6 | 
            +
                pcc_location_t q_loc;
         | 
| 7 | 
            +
            <%- end -%>
         | 
| 8 | 
            +
            <%= gen.generate_code(expr, onfail, 4, false) -%>
         | 
| 9 | 
            +
                q = ctx->cur;
         | 
| 10 | 
            +
                chunk->capts.buf[<%= index %>].range.start = p;
         | 
| 11 | 
            +
                chunk->capts.buf[<%= index %>].range.end = q;
         | 
| 12 | 
            +
            <%- if gen.location -%>
         | 
| 13 | 
            +
                q_loc = ctx->cur_loc;
         | 
| 14 | 
            +
                *chunk->capts.buf[<%= index %>].range.start_loc_ptr = p_loc;
         | 
| 15 | 
            +
                *chunk->capts.buf[<%= index %>].range.end_loc_ptr = q_loc;
         | 
| 16 | 
            +
            <%- end -%>
         | 
| 17 | 
            +
            }
         | 
| @@ -0,0 +1,14 @@ | |
| 1 | 
            +
            pos<%= gen.level %> = @cur
         | 
| 2 | 
            +
            <%- if gen.location -%>
         | 
| 3 | 
            +
            p_loc<%= gen.level %> = @cur_loc
         | 
| 4 | 
            +
            <%- end -%>
         | 
| 5 | 
            +
            <%- %><%= gen.generate_code(expr, onfail, 0, false) -%>
         | 
| 6 | 
            +
            q<%= gen.level %> = @cur
         | 
| 7 | 
            +
            capt<%= gen.level %> = answer.capts[<%= index %>]
         | 
| 8 | 
            +
            capt<%= gen.level %>.range_start = pos<%= gen.level %>
         | 
| 9 | 
            +
            capt<%= gen.level %>.range_end = q<%= gen.level %>
         | 
| 10 | 
            +
            <%- if gen.location -%>
         | 
| 11 | 
            +
            q_loc<%= gen.level %> = @cur_loc
         | 
| 12 | 
            +
            capt<%= gen.level %>.start_loc = p_loc<%= gen.level %>
         | 
| 13 | 
            +
            capt<%= gen.level %>.end_loc = q_loc<%= gen.level %>
         | 
| 14 | 
            +
            <%- end -%>
         | 
| @@ -0,0 +1,47 @@ | |
| 1 | 
            +
            {
         | 
| 2 | 
            +
            <%- if !a && charclass =~ /\A[^\\]-.\z/ -%>
         | 
| 3 | 
            +
                char c;
         | 
| 4 | 
            +
                if (pcc_refill_buffer(ctx, 1) < 1) goto L<%= "%04d" % onfail %>;
         | 
| 5 | 
            +
                c = ctx->buffer.buf[ctx->cur];
         | 
| 6 | 
            +
            <%- if a -%>
         | 
| 7 | 
            +
                if (c >= '<%= Packcr.escape_character(charclass[0]) %>' && c <= '<%= Packcr.escape_character(charclass[2]) %>') goto L<%= "%04d" % onfail %>;
         | 
| 8 | 
            +
            <%- else -%>
         | 
| 9 | 
            +
                if (!(c >= '<%= Packcr.escape_character(charclass[0]) %>' && c <= '<%= Packcr.escape_character(charclass[2]) %>')) goto L<%= "%04d" % onfail %>;
         | 
| 10 | 
            +
            <%- end -%>
         | 
| 11 | 
            +
            <%- if gen.location -%>
         | 
| 12 | 
            +
                pcc_location_forward(&ctx->cur_loc, ctx->buffer.buf + ctx->cur, 1);
         | 
| 13 | 
            +
            <%- end -%>
         | 
| 14 | 
            +
                ctx->cur++;
         | 
| 15 | 
            +
            <%- else -%>
         | 
| 16 | 
            +
                char c;
         | 
| 17 | 
            +
                if (pcc_refill_buffer(ctx, 1) < 1) goto L<%= "%04d" % onfail %>;
         | 
| 18 | 
            +
                c = ctx->buffer.buf[ctx->cur];
         | 
| 19 | 
            +
            <%- if a -%>
         | 
| 20 | 
            +
                if (
         | 
| 21 | 
            +
            <%- else -%>
         | 
| 22 | 
            +
                if (!(
         | 
| 23 | 
            +
            <%- end -%>
         | 
| 24 | 
            +
            <%- i = 0 -%>
         | 
| 25 | 
            +
            <%- while i < n -%>
         | 
| 26 | 
            +
            <%-   if charclass[i] == "\\" && i + 1 < n -%>
         | 
| 27 | 
            +
            <%-     i += 1 -%>
         | 
| 28 | 
            +
            <%-   end -%>
         | 
| 29 | 
            +
            <%-   if i + 2 < n && charclass[i + 1] == '-' -%>
         | 
| 30 | 
            +
                    (c >= '<%= Packcr.escape_character(charclass[i]) %>' && c <= '<%= Packcr.escape_character(charclass[i + 2]) %>')<%= (i + 3 == n) ? "" : " ||" %>
         | 
| 31 | 
            +
            <%-     i += 2 -%>
         | 
| 32 | 
            +
            <%-   else -%>
         | 
| 33 | 
            +
                    c == '<%= Packcr.escape_character(charclass[i]) %>'<%= (i + 1 == n) ? "" : " ||" %>
         | 
| 34 | 
            +
            <%-   end -%>
         | 
| 35 | 
            +
            <%-   i += 1 -%>
         | 
| 36 | 
            +
            <%- end -%>
         | 
| 37 | 
            +
            <%- if a -%>
         | 
| 38 | 
            +
                ) goto L<%= "%04d" % onfail %>;
         | 
| 39 | 
            +
            <%- else -%>
         | 
| 40 | 
            +
                )) goto L<%= "%04d" % onfail %>;
         | 
| 41 | 
            +
            <%- end -%>
         | 
| 42 | 
            +
            <%- if gen.location -%>
         | 
| 43 | 
            +
                pcc_location_forward(&ctx->cur_loc, ctx->buffer.buf + ctx->cur, 1);
         | 
| 44 | 
            +
            <%- end -%>
         | 
| 45 | 
            +
                ctx->cur++;
         | 
| 46 | 
            +
            <%- end -%>
         | 
| 47 | 
            +
            }
         | 
| @@ -0,0 +1,49 @@ | |
| 1 | 
            +
            <%- if !a && charclass =~ /\A[^\\]-.\z/ -%>
         | 
| 2 | 
            +
            if refill_buffer(1) < 1
         | 
| 3 | 
            +
              throw(<%= onfail %>)
         | 
| 4 | 
            +
            end
         | 
| 5 | 
            +
            c<%= gen.level %> = @buffer[@cur]
         | 
| 6 | 
            +
            <%-   if a -%>
         | 
| 7 | 
            +
            if c<%= gen.level %> >= "<%= Packcr.escape_character(charclass[0]) %>" && c<%= gen.level %> <= "<%= Packcr.escape_character(charclass[2]) %>"
         | 
| 8 | 
            +
              throw(<%= onfail %>)
         | 
| 9 | 
            +
            end
         | 
| 10 | 
            +
            <%-   else -%>
         | 
| 11 | 
            +
            unless c<%= gen.level %> >= "<%= Packcr.escape_character(charclass[0]) %>" && c<%= gen.level %> <= "<%= Packcr.escape_character(charclass[2]) %>"
         | 
| 12 | 
            +
              throw(<%= onfail %>)
         | 
| 13 | 
            +
            end
         | 
| 14 | 
            +
            <%-   end -%>
         | 
| 15 | 
            +
            <%-   if gen.location -%>
         | 
| 16 | 
            +
            @cur_loc = @cur_loc.forward(@buffer, @cur, 1)
         | 
| 17 | 
            +
            <%-   end -%>
         | 
| 18 | 
            +
            @cur += 1
         | 
| 19 | 
            +
            <%- else -%>
         | 
| 20 | 
            +
            if refill_buffer(1) < 1
         | 
| 21 | 
            +
              throw(<%= onfail %>)
         | 
| 22 | 
            +
            end
         | 
| 23 | 
            +
            c<%= gen.level %> = @buffer[@cur]
         | 
| 24 | 
            +
            <%-   if a -%>
         | 
| 25 | 
            +
            if (
         | 
| 26 | 
            +
            <%-   else -%>
         | 
| 27 | 
            +
            unless (
         | 
| 28 | 
            +
            <%-   end -%>
         | 
| 29 | 
            +
            <%-   i = 0 -%>
         | 
| 30 | 
            +
            <%-   while i < n -%>
         | 
| 31 | 
            +
            <%-     if charclass[i] == "\\" && i + 1 < n -%>
         | 
| 32 | 
            +
            <%-       i += 1 -%>
         | 
| 33 | 
            +
            <%-     end -%>
         | 
| 34 | 
            +
            <%-     if i + 2 < n && charclass[i + 1] == '-' -%>
         | 
| 35 | 
            +
              (c<%= gen.level %> >= "<%= Packcr.escape_character(charclass[i]) %>" && c<%= gen.level %> <= "<%= Packcr.escape_character(charclass[i + 2]) %>")<%= (i + 3 == n) ? "" : " ||" %>
         | 
| 36 | 
            +
            <%-       i += 2 -%>
         | 
| 37 | 
            +
            <%-     else -%>
         | 
| 38 | 
            +
              c<%= gen.level %> == "<%= Packcr.escape_character(charclass[i]) %>"<%= (i + 1 == n) ? "" : " ||" %>
         | 
| 39 | 
            +
            <%-     end -%>
         | 
| 40 | 
            +
            <%-     i += 1 -%>
         | 
| 41 | 
            +
            <%-   end -%>
         | 
| 42 | 
            +
            )
         | 
| 43 | 
            +
              throw(<%= onfail %>)
         | 
| 44 | 
            +
            end
         | 
| 45 | 
            +
            <%-   if gen.location -%>
         | 
| 46 | 
            +
            @cur_loc = @cur_loc.forward(@buffer, @cur, 1)
         | 
| 47 | 
            +
            <%-   end -%>
         | 
| 48 | 
            +
            @cur += 1
         | 
| 49 | 
            +
            <%- end -%>
         | 
| @@ -0,0 +1 @@ | |
| 1 | 
            +
            goto L<%= "%04d" % onfail %>;
         | 
| @@ -0,0 +1 @@ | |
| 1 | 
            +
            throw(<%= onfail %>)
         | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            <%- if a -%>
         | 
| 2 | 
            +
            if (
         | 
| 3 | 
            +
                pcc_refill_buffer(ctx, 1) < 1 ||
         | 
| 4 | 
            +
                ctx->buffer.buf[ctx->cur] == '<%= Packcr.escape_character(charclass[i]) %>'
         | 
| 5 | 
            +
            ) goto L<%= "%04d" % onfail %>;
         | 
| 6 | 
            +
            <%- if gen.location -%>
         | 
| 7 | 
            +
                pcc_location_forward(&ctx->cur_loc, ctx->buffer.buf + ctx->cur, 1);
         | 
| 8 | 
            +
            <%- end -%>
         | 
| 9 | 
            +
            ctx->cur++;
         | 
| 10 | 
            +
            <%- else -%>
         | 
| 11 | 
            +
            if (
         | 
| 12 | 
            +
                pcc_refill_buffer(ctx, 1) < 1 ||
         | 
| 13 | 
            +
                ctx->buffer.buf[ctx->cur] != '<%= Packcr.escape_character(charclass[0]) %>'
         | 
| 14 | 
            +
            ) goto L<%= "%04d" % onfail %>;
         | 
| 15 | 
            +
            <%- if gen.location -%>
         | 
| 16 | 
            +
                pcc_location_forward(&ctx->cur_loc, ctx->buffer.buf + ctx->cur, 1);
         | 
| 17 | 
            +
            <%- end -%>
         | 
| 18 | 
            +
            ctx->cur++;
         | 
| 19 | 
            +
            <%- end -%>
         |