Class: Racc::Parser

### Home Classes Methods

### In Files

- lib/racc/parser.rb

### Parent

Object

### Methods

- #_racc_do_parse_rb
- #_racc_do_reduce
- #_racc_evalact
- #_racc_init_sysvars
- #_racc_setup
- #_racc_yyparse_rb
- #do_parse
- #next_token
- #on_error
- #racc_accept
- #racc_e_pop
- #racc_next_state
- #racc_print_stacks
- #racc_print_states
- #racc_read_token
- #racc_reduce
- #racc_shift
- #racc_token2str
- #token_to_str
- #yyaccept
- #yyerrok
- #yyerror
- #yyparse

### Files

- Manifest.txt
- README.rdoc
- pre-setup
- NEWS.en.rdoc
- grammar.en.rdoc

### Class/Module Index

Quicksearch

- Racc
- Racc::Accept
- Racc::ActionTable
- Racc::CompileError
- Racc::DebugFlags
- Racc::Error
- Racc::Goto
- Racc::Grammar
- Racc::Grammar::DefinitionEnv
- Racc::Grammar::PrecedenceDefinitionEnv
- Racc::GrammarFileParser
- Racc::GrammarFileParser::Result
- Racc::GrammarFileScanner
- Racc::ISet
- Racc::Item
- Racc::LocationPointer
- Racc::LogFileGenerator
- Racc::OrMark
- Racc::ParseError
- Racc::ParseError
- Racc::Parser
- Racc::ParserClassGenerator
- Racc::ParserFileGenerator
- Racc::ParserFileGenerator::Params
- Racc::Prec
- Racc::RRconflict
- Racc::Reduce
- Racc::Rule
- Racc::SRconflict
- Racc::Shift
- Racc::SourceText
- Racc::State
- Racc::StateTransitionTable
- Racc::StateTransitionTableGenerator
- Racc::States
- Racc::Sym
- Racc::SymbolTable
- Racc::UserAction
- Object
- Object::ParseError
- Array

No matching classes.

# Racc::Parser

### Constants

Racc_Runtime_Core_Revision_C

  Racc_Runtime_Core_Version_C = (defined in extention)

Racc_Runtime_Core_Revision_R
Racc_Runtime_Core_Version_R
Racc_Runtime_Revision
Racc_Runtime_Version

### Public Instance Methods

_racc_do_parse_rb(arg, in_debug) click to toggle source

    # File lib/racc/parser.rb, line 286
    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 lib/racc/parser.rb, line 482
    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 lib/racc/parser.rb, line 387
    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
        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 $
            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 lib/racc/parser.rb, line 241
    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 lib/racc/parser.rb, line 229
    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 lib/racc/parser.rb, line 334
    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

do_parse() click to toggle source

The entry point of the parser. This method is used with next_token. If Racc wants to get token (and its value), calls next_token.

Example:

    def parse
      @q = [[1,1],
            [2,2],
            [3,3],
            [false, '$']]
      do_parse
    end

    def next_token
      @q.shift
    end

    # File lib/racc/parser.rb, line 270
    def do_parse
      __send__(Racc_Main_Parsing_Routine, _racc_setup(), false)
    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 lib/racc/parser.rb, line 282
    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 lib/racc/parser.rb, line 538
    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 lib/racc/parser.rb, line 587
    def racc_accept
      @racc_debug_out.puts 'accept'
      @racc_debug_out.puts
    end

racc_e_pop(state, tstack, vstack) click to toggle source

    # File lib/racc/parser.rb, line 592
    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 lib/racc/parser.rb, line 599
    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 lib/racc/parser.rb, line 605
    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 lib/racc/parser.rb, line 614
    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 lib/racc/parser.rb, line 561
    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 lib/racc/parser.rb, line 574
    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 lib/racc/parser.rb, line 568
    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 lib/racc/parser.rb, line 621
    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 lib/racc/parser.rb, line 627
    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 lib/racc/parser.rb, line 551
    def yyaccept
      throw :racc_jump, 2
    end

yyerrok() click to toggle source

Leave error recovering mode.

    # File lib/racc/parser.rb, line 556
    def yyerrok
      @racc_error_status = 0
    end

yyerror() click to toggle source

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

    # File lib/racc/parser.rb, line 545
    def yyerror
      throw :racc_jump, 1
    end

yyparse(recv, mid) click to toggle source

Another entry point for the parser. If you use this method, you must implement RECEIVER#METHOD_ID method.

RECEIVER#METHOD_ID is a method to get next token. It must 'yield' the token, which format is [TOKEN-SYMBOL, VALUE].

    # File lib/racc/parser.rb, line 330
    def yyparse(recv, mid)
      __send__(Racc_YY_Parse_Method, recv, mid, _racc_setup(), false)
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.