In Files

  • ruby-3.1.2/ext/racc/cparse/cparse.c
  • ruby-3.1.2/lib/racc/parser.rb

Files

Class/Module Index [+]

Quicksearch

Racc::Parser

Public Instance Methods

_racc_do_parse_rb(arg, in_debug) click to toggle source
 
               # File ruby-3.1.2/lib/racc/parser.rb, line 281
def _racc_do_parse_rb(arg, in_debug)
  action_table, action_check, action_default, action_pointer,
  _,            _,            _,              _,
  _,            _,            token_table,    * = arg

  _racc_init_sysvars
  tok = act = i = nil

  catch(:racc_end_parse) {
    while true
      if i = action_pointer[@racc_state[-1]]
        if @racc_read_next
          if @racc_t != 0   # not EOF
            tok, @racc_val = next_token()
            unless tok      # EOF
              @racc_t = 0
            else
              @racc_t = (token_table[tok] or 1)   # error token
            end
            racc_read_token(@racc_t, tok, @racc_val) if @yydebug
            @racc_read_next = false
          end
        end
        i += @racc_t
        unless i >= 0 and
               act = action_table[i] and
               action_check[i] == @racc_state[-1]
          act = action_default[@racc_state[-1]]
        end
      else
        act = action_default[@racc_state[-1]]
      end
      while act = _racc_evalact(act, arg)
        ;
      end
    end
  }
end
            
_racc_do_reduce(arg, act) click to toggle source
 
               # File ruby-3.1.2/lib/racc/parser.rb, line 481
def _racc_do_reduce(arg, act)
  _,          _,            _,            _,
  goto_table, goto_check,   goto_default, goto_pointer,
  nt_base,    reduce_table, _,            _,
  _,          use_result,   * = arg

  state = @racc_state
  vstack = @racc_vstack
  tstack = @racc_tstack

  i = act * -3
  len       = reduce_table[i]
  reduce_to = reduce_table[i+1]
  method_id = reduce_table[i+2]
  void_array = []

  tmp_t = tstack[-len, len] if @yydebug
  tmp_v = vstack[-len, len]
  tstack[-len, len] = void_array if @yydebug
  vstack[-len, len] = void_array
  state[-len, len]  = void_array

  # tstack must be updated AFTER method call
  if use_result
    vstack.push __send__(method_id, tmp_v, vstack, tmp_v[0])
  else
    vstack.push __send__(method_id, tmp_v, vstack)
  end
  tstack.push reduce_to

  racc_reduce(tmp_t, reduce_to, tstack, vstack) if @yydebug

  k1 = reduce_to - nt_base
  if i = goto_pointer[k1]
    i += state[-1]
    if i >= 0 and (curstate = goto_table[i]) and goto_check[i] == k1
      return curstate
    end
  end
  goto_default[k1]
end
            
_racc_evalact(act, arg) click to toggle source

common

 
               # File ruby-3.1.2/lib/racc/parser.rb, line 384
def _racc_evalact(act, arg)
  action_table, action_check, _, action_pointer,
  _,            _,            _, _,
  _,            _,            _, shift_n,
  reduce_n,     * = arg
  nerr = 0   # tmp

  if act > 0 and act < shift_n
    #
    # shift
    #
    if @racc_error_status > 0
      @racc_error_status -= 1 unless @racc_t <= 1 # error token or EOF
    end
    @racc_vstack.push @racc_val
    @racc_state.push act
    @racc_read_next = true
    if @yydebug
      @racc_tstack.push @racc_t
      racc_shift @racc_t, @racc_tstack, @racc_vstack
    end

  elsif act < 0 and act > -reduce_n
    #
    # reduce
    #
    code = catch(:racc_jump) {
      @racc_state.push _racc_do_reduce(arg, act)
      false
    }
    if code
      case code
      when 1 # yyerror
        @racc_user_yyerror = true   # user_yyerror
        return -reduce_n
      when 2 # yyaccept
        return shift_n
      else
        raise '[Racc Bug] unknown jump code'
      end
    end

  elsif act == shift_n
    #
    # accept
    #
    racc_accept if @yydebug
    throw :racc_end_parse, @racc_vstack[0]

  elsif act == -reduce_n
    #
    # error
    #
    case @racc_error_status
    when 0
      unless arg[21]    # user_yyerror
        nerr += 1
        on_error @racc_t, @racc_val, @racc_vstack
      end
    when 3
      if @racc_t == 0   # is $
        # We're at EOF, and another error occurred immediately after
        # attempting auto-recovery
        throw :racc_end_parse, nil
      end
      @racc_read_next = true
    end
    @racc_user_yyerror = false
    @racc_error_status = 3
    while true
      if i = action_pointer[@racc_state[-1]]
        i += 1   # error token
        if  i >= 0 and
            (act = action_table[i]) and
            action_check[i] == @racc_state[-1]
          break
        end
      end
      throw :racc_end_parse, nil if @racc_state.size <= 1
      @racc_state.pop
      @racc_vstack.pop
      if @yydebug
        @racc_tstack.pop
        racc_e_pop @racc_state, @racc_tstack, @racc_vstack
      end
    end
    return act

  else
    raise "[Racc Bug] unknown action #{act.inspect}"
  end

  racc_next_state(@racc_state[-1], @racc_state) if @yydebug

  nil
end
            
_racc_init_sysvars() click to toggle source
 
               # File ruby-3.1.2/lib/racc/parser.rb, line 234
def _racc_init_sysvars
  @racc_state  = [0]
  @racc_tstack = []
  @racc_vstack = []

  @racc_t = nil
  @racc_val = nil

  @racc_read_next = true

  @racc_user_yyerror = false
  @racc_error_status = 0
end
            
_racc_setup() click to toggle source
 
               # File ruby-3.1.2/lib/racc/parser.rb, line 222
def _racc_setup
  @yydebug = false unless self.class::Racc_debug_parser
  @yydebug = false unless defined?(@yydebug)
  if @yydebug
    @racc_debug_out = $stderr unless defined?(@racc_debug_out)
    @racc_debug_out ||= $stderr
  end
  arg = self.class::Racc_arg
  arg[13] = true if arg.size < 14
  arg
end
            
_racc_yyparse_rb(recv, mid, arg, c_debug) click to toggle source
 
               # File ruby-3.1.2/lib/racc/parser.rb, line 331
def _racc_yyparse_rb(recv, mid, arg, c_debug)
  action_table, action_check, action_default, action_pointer,
  _,            _,            _,              _,
  _,            _,            token_table,    * = arg

  _racc_init_sysvars

  catch(:racc_end_parse) {
    until i = action_pointer[@racc_state[-1]]
      while act = _racc_evalact(action_default[@racc_state[-1]], arg)
        ;
      end
    end
    recv.__send__(mid) do |tok, val|
      unless tok
        @racc_t = 0
      else
        @racc_t = (token_table[tok] or 1)   # error token
      end
      @racc_val = val
      @racc_read_next = false

      i += @racc_t
      unless i >= 0 and
             act = action_table[i] and
             action_check[i] == @racc_state[-1]
        act = action_default[@racc_state[-1]]
      end
      while act = _racc_evalact(act, arg)
        ;
      end

      while !(i = action_pointer[@racc_state[-1]]) ||
            ! @racc_read_next ||
            @racc_t == 0  # $
        unless i and i += @racc_t and
               i >= 0 and
               act = action_table[i] and
               action_check[i] == @racc_state[-1]
          act = action_default[@racc_state[-1]]
        end
        while act = _racc_evalact(act, arg)
          ;
        end
      end
    end
  }
end
            
next_token() click to toggle source

The method to fetch next token. If you use do_parse method, you must implement next_token.

The format of return value is [TOKEN_SYMBOL, VALUE]. token-symbol is represented by Ruby's symbol by default, e.g. :IDENT for 'IDENT'. “;” (String) for ';'.

The final symbol (End of file) must be false.

 
               # File ruby-3.1.2/lib/racc/parser.rb, line 277
def next_token
  raise NotImplementedError, "#{self.class}\#next_token is not defined"
end
            
on_error(t, val, vstack) click to toggle source

This method is called when a parse error is found.

ERROR_TOKEN_ID is an internal ID of token which caused error. You can get string representation of this ID by calling token_to_str.

ERROR_VALUE is a value of error token.

value_stack is a stack of symbol values. DO NOT MODIFY this object.

This method raises ParseError by default.

If this method returns, parsers enter “error recovering mode”.

 
               # File ruby-3.1.2/lib/racc/parser.rb, line 537
def on_error(t, val, vstack)
  raise ParseError, sprintf("\nparse error on value %s (%s)",
                            val.inspect, token_to_str(t) || '?')
end
            
racc_accept() click to toggle source
 
               # File ruby-3.1.2/lib/racc/parser.rb, line 586
def racc_accept
  @racc_debug_out.puts 'accept'
  @racc_debug_out.puts
end
            
racc_e_pop(state, tstack, vstack) click to toggle source
 
               # File ruby-3.1.2/lib/racc/parser.rb, line 591
def racc_e_pop(state, tstack, vstack)
  @racc_debug_out.puts 'error recovering mode: pop token'
  racc_print_states state
  racc_print_stacks tstack, vstack
  @racc_debug_out.puts
end
            
racc_next_state(curstate, state) click to toggle source
 
               # File ruby-3.1.2/lib/racc/parser.rb, line 598
def racc_next_state(curstate, state)
  @racc_debug_out.puts  "goto    #{curstate}"
  racc_print_states state
  @racc_debug_out.puts
end
            
racc_print_stacks(t, v) click to toggle source
 
               # File ruby-3.1.2/lib/racc/parser.rb, line 604
def racc_print_stacks(t, v)
  out = @racc_debug_out
  out.print '        ['
  t.each_index do |i|
    out.print ' (', racc_token2str(t[i]), ' ', v[i].inspect, ')'
  end
  out.puts ' ]'
end
            
racc_print_states(s) click to toggle source
 
               # File ruby-3.1.2/lib/racc/parser.rb, line 613
def racc_print_states(s)
  out = @racc_debug_out
  out.print '        ['
  s.each {|st| out.print ' ', st }
  out.puts ' ]'
end
            
racc_read_token(t, tok, val) click to toggle source

For debugging output

 
               # File ruby-3.1.2/lib/racc/parser.rb, line 560
def racc_read_token(t, tok, val)
  @racc_debug_out.print 'read    '
  @racc_debug_out.print tok.inspect, '(', racc_token2str(t), ') '
  @racc_debug_out.puts val.inspect
  @racc_debug_out.puts
end
            
racc_reduce(toks, sim, tstack, vstack) click to toggle source
 
               # File ruby-3.1.2/lib/racc/parser.rb, line 573
def racc_reduce(toks, sim, tstack, vstack)
  out = @racc_debug_out
  out.print 'reduce '
  if toks.empty?
    out.print ' <none>'
  else
    toks.each {|t| out.print ' ', racc_token2str(t) }
  end
  out.puts " --> #{racc_token2str(sim)}"
  racc_print_stacks tstack, vstack
  @racc_debug_out.puts
end
            
racc_shift(tok, tstack, vstack) click to toggle source
 
               # File ruby-3.1.2/lib/racc/parser.rb, line 567
def racc_shift(tok, tstack, vstack)
  @racc_debug_out.puts "shift   #{racc_token2str tok}"
  racc_print_stacks tstack, vstack
  @racc_debug_out.puts
end
            
racc_token2str(tok) click to toggle source
 
               # File ruby-3.1.2/lib/racc/parser.rb, line 620
def racc_token2str(tok)
  self.class::Racc_token_to_s_table[tok] or
      raise "[Racc Bug] can't convert token #{tok} to string"
end
            
token_to_str(t) click to toggle source

Convert internal ID of token symbol to the string.

 
               # File ruby-3.1.2/lib/racc/parser.rb, line 626
def token_to_str(t)
  self.class::Racc_token_to_s_table[t]
end
            
yyaccept() click to toggle source

Exit parser. Return value is +Symbol_Value_Stack+.

 
               # File ruby-3.1.2/lib/racc/parser.rb, line 550
def yyaccept
  throw :racc_jump, 2
end
            
yyerrok() click to toggle source

Leave error recovering mode.

 
               # File ruby-3.1.2/lib/racc/parser.rb, line 555
def yyerrok
  @racc_error_status = 0
end
            
yyerror() click to toggle source

Enter error recovering mode. This method does not call on_error.

 
               # File ruby-3.1.2/lib/racc/parser.rb, line 544
def yyerror
  throw :racc_jump, 1
end
            

Private Instance Methods

_racc_do_parse_c(p1, p2) click to toggle source
 
               static VALUE
racc_cparse(VALUE parser, VALUE arg, VALUE sysdebug)
{
    VALUE vparams;
    struct cparse_params *v;

    vparams = TypedData_Make_Struct(CparseParams, struct cparse_params,
                                    &cparse_params_type, v);
    D_puts("starting cparse");
    v->sys_debug = RTEST(sysdebug);
    vparams = initialize_params(vparams, parser, arg, Qnil, Qnil);
    v->lex_is_iterator = FALSE;
    parse_main(v, Qnil, Qnil, 0);

    RB_GC_GUARD(vparams);
    return v->retval;
}
            
_racc_yyparse_c(p1, p2, p3, p4) click to toggle source
 
               static VALUE
racc_yyparse(VALUE parser, VALUE lexer, VALUE lexmid, VALUE arg, VALUE sysdebug)
{
    VALUE vparams;
    struct cparse_params *v;

    vparams = TypedData_Make_Struct(CparseParams, struct cparse_params,
                                    &cparse_params_type, v);
    v->sys_debug = RTEST(sysdebug);
    D_puts("start C yyparse");
    vparams = initialize_params(vparams, parser, arg, lexer, lexmid);
    v->lex_is_iterator = TRUE;
    D_puts("params initialized");
    parse_main(v, Qnil, Qnil, 0);
    call_lexer(v);
    if (!v->fin) {
        rb_raise(rb_eArgError, "%s() is finished before EndOfToken",
                 rb_id2name(v->lexmid));
    }

    RB_GC_GUARD(vparams);
    return v->retval;
}