core/src/main/java/org/jruby/parser/RubyParser.java
public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
    int yystate = 0;
    Object yyVal = null;
    ProductionState[] yystates = new ProductionState[YYMAX];        // stack of states and values.
    initializeStates(yystates, 0, yystates.length);
    int yytoken = NEEDS_TOKEN;     // current token
    int yyErrorFlag = 0;           // #tokens to shift
    int start = 0;
    int end = 0;

    yyLoop: for (int yytop = 0;; yytop++) {
      if (yytop + 1 >= yystates.length) {			// dynamically increase
          ProductionState[] newStates = new ProductionState[yystates.length+YYMAX];
          System.arraycopy(yystates, 0, newStates, 0, yystates.length);
          initializeStates(newStates, yystates.length, newStates.length - yystates.length);
          yystates = newStates;
      }

      yystates[yytop].state = yystate;
      yystates[yytop].value = yyVal;
      yystates[yytop].start = start;
      yystates[yytop].end = end;
   //         printstates(yytop, yystates);

      if (yydebug != null) yydebug.push(yystate, yyVal);

      yyDiscarded: for (;;) {	// discarding a token does not change stack
        int yyn = yyDefRed[yystate];
        if (yyn == DEFAULT) {	//ja else [default] reduce (yyn)
            if (yytoken == NEEDS_TOKEN) {
                yytoken = yyLex.nextToken();
                if (yydebug != null) yydebug.lex(yystate, yytoken, yyName(yytoken), yyLex.value());
            }

            yyn = yySindex[yystate];
            if (yyn != 0 &&
                (yyn += yytoken) >= 0 &&
                yyn < yyTable.length &&
                yyCheck[yyn] == yytoken) {
                if (yydebug != null) yydebug.shift(yystate, yyTable[yyn], yyErrorFlag-1);
                yystate = yyTable[yyn];		// shift to yyn
                yyVal = yyLex.value();
                start = yyLex.start;
                end = yyLex.end;
                yytoken = NEEDS_TOKEN;
                if (yyErrorFlag > 0) --yyErrorFlag;
                continue yyLoop;
            }

            yyn = yyRindex[yystate];
            if (yyn != 0 &&
                (yyn += yytoken) >= 0 &&
                 yyn < yyTable.length &&
                 yyCheck[yyn] == yytoken) {
                yyn = yyTable[yyn];			// reduce (yyn)
            } else {
                switch (yyErrorFlag) {
  
                case 0:
                    support.yyerror("syntax error", yyExpecting(yystate), yyNames[yytoken]);
                    if (yydebug != null) yydebug.error("syntax error");
                    // falls through...
                case 1: case 2:
                    yyErrorFlag = 3;
                    do {
                        yyn = yySindex[yystates[yytop].state];
                        if (yyn != 0 &&
                            (yyn += yyErrorCode) >= 0 &&
                            yyn < yyTable.length &&
                            yyCheck[yyn] == yyErrorCode) {
                            if (yydebug != null) yydebug.shift(yystates[yytop].state, yyTable[yyn], 3);
                            yystate = yyTable[yyn];
                            yyVal = yyLex.value();
                            continue yyLoop;
                        }
                        if (yydebug != null) yydebug.pop(yystates[yytop].state);
                    } while (--yytop >= 0);
                    if (yydebug != null) yydebug.reject();
                    support.yyerror("irrecoverable syntax error"); // throws
                case 3:
                    if (yytoken == 0) {
                        if (yydebug != null) yydebug.reject();
                        support.yyerror("irrecoverable syntax error at end-of-file");
                    }
                    if (yydebug != null) yydebug.discard(yystate, yytoken, yyName(yytoken), yyLex.value());
                    yytoken = NEEDS_TOKEN;
                    continue yyDiscarded; // leave stack alone
                }
            }
        }

        if (yydebug != null) yydebug.reduce(yystate, yystates[yytop-yyLen[yyn]].state, yyn, yyRule[yyn], yyLen[yyn]);

        ParserState parserState = states[yyn];
        if (parserState == null) {
            yyVal = yyLen[yyn] > 0 ? yystates[yytop - yyLen[yyn] + 1].value : null;
        } else {
            int count = yyLen[yyn];
            start = yystates[yytop - count + 1].start;
            end = yystates[yytop].end;
            yyVal = parserState.execute(support, lexer, yyVal, yystates, yytop, count);
        }
// ACTIONS_END (line used by optimize_parser)
        yytop -= yyLen[yyn];
        yystate = yystates[yytop].state;
        int yyM = yyLhs[yyn];
        if (yystate == 0 && yyM == 0) {
            if (yydebug != null) yydebug.shift(0, yyFinal);
            yystate = yyFinal;
            if (yytoken == NEEDS_TOKEN) {
                yytoken = yyLex.nextToken();
                if (yydebug != null) yydebug.lex(yystate, yytoken,yyName(yytoken), yyLex.value());
            }
            if (yytoken == 0) {
                if (yydebug != null) yydebug.accept(yyVal);
                return yyVal;
            }
            continue yyLoop;
        }
        yyn = yyGindex[yyM];
        if (yyn != 0 &&
            (yyn += yystate) >= 0 &&
            yyn < yyTable.length &&
            yyCheck[yyn] == yystate) {
            yystate = yyTable[yyn];
        } else {
            yystate = yyDgoto[yyM];
        }

        if (yydebug != null) yydebug.shift(yystates[yytop].state, yystate);
        continue yyLoop;
      }
    }
  }
/** the generated parser.
      Maintains a dynamic state and value stack.
      @param yyLex scanner.
      @return result of the last reduction, if any.
    */
the generated parser.
Maintains a dynamic state and value stack.
the generated parser . Maintains a dynamic state and value stack .
public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
    int yystate = 0;
    Object yyVal = null;
    ProductionState[] yystates = new ProductionState[YYMAX];        
    initializeStates(yystates, 0, yystates.length);
    int yytoken = NEEDS_TOKEN;     
    int yyErrorFlag = 0;           
    int start = 0;
    int end = 0;
    yyLoop: for (int yytop = 0;; yytop++) {
      if (yytop + 1 >= yystates.length) {			
          ProductionState[] newStates = new ProductionState[yystates.length+YYMAX];
          System.arraycopy(yystates, 0, newStates, 0, yystates.length);
          initializeStates(newStates, yystates.length, newStates.length - yystates.length);
          yystates = newStates;
      }
      yystates[yytop].state = yystate;
      yystates[yytop].value = yyVal;
      yystates[yytop].start = start;
      yystates[yytop].end = end;
      if (yydebug != null) yydebug.push(yystate, yyVal);
      yyDiscarded: for (;;) {	
        int yyn = yyDefRed[yystate];
        if (yyn == DEFAULT) {	
            if (yytoken == NEEDS_TOKEN) {
                yytoken = yyLex.nextToken();
                if (yydebug != null) yydebug.lex(yystate, yytoken, yyName(yytoken), yyLex.value());
            }
            yyn = yySindex[yystate];
            if (yyn != 0 &&
                (yyn += yytoken) >= 0 &&
                yyn < yyTable.length &&
                yyCheck[yyn] == yytoken) {
                if (yydebug != null) yydebug.shift(yystate, yyTable[yyn], yyErrorFlag-1);
                yystate = yyTable[yyn];		
                yyVal = yyLex.value();
                start = yyLex.start;
                end = yyLex.end;
                yytoken = NEEDS_TOKEN;
                if (yyErrorFlag > 0) --yyErrorFlag;
                continue yyLoop;
            }
            yyn = yyRindex[yystate];
            if (yyn != 0 &&
                (yyn += yytoken) >= 0 &&
                 yyn < yyTable.length &&
                 yyCheck[yyn] == yytoken) {
                yyn = yyTable[yyn];			
            } else {
                switch (yyErrorFlag) {
                case 0:
                    support.yyerror("syntax error", yyExpecting(yystate), yyNames[yytoken]);
                    if (yydebug != null) yydebug.error("syntax error");
                case 1: case 2:
                    yyErrorFlag = 3;
                    do {
                        yyn = yySindex[yystates[yytop].state];
                        if (yyn != 0 &&
                            (yyn += yyErrorCode) >= 0 &&
                            yyn < yyTable.length &&
                            yyCheck[yyn] == yyErrorCode) {
                            if (yydebug != null) yydebug.shift(yystates[yytop].state, yyTable[yyn], 3);
                            yystate = yyTable[yyn];
                            yyVal = yyLex.value();
                            continue yyLoop;
                        }
                        if (yydebug != null) yydebug.pop(yystates[yytop].state);
                    } while (--yytop >= 0);
                    if (yydebug != null) yydebug.reject();
                    support.yyerror("irrecoverable syntax error"); 
                case 3:
                    if (yytoken == 0) {
                        if (yydebug != null) yydebug.reject();
                        support.yyerror("irrecoverable syntax error at end-of-file");
                    }
                    if (yydebug != null) yydebug.discard(yystate, yytoken, yyName(yytoken), yyLex.value());
                    yytoken = NEEDS_TOKEN;
                    continue yyDiscarded; 
                }
            }
        }
        if (yydebug != null) yydebug.reduce(yystate, yystates[yytop-yyLen[yyn]].state, yyn, yyRule[yyn], yyLen[yyn]);
        ParserState parserState = states[yyn];
        if (parserState == null) {
            yyVal = yyLen[yyn] > 0 ? yystates[yytop - yyLen[yyn] + 1].value : null;
        } else {
            int count = yyLen[yyn];
            start = yystates[yytop - count + 1].start;
            end = yystates[yytop].end;
            yyVal = parserState.execute(support, lexer, yyVal, yystates, yytop, count);
        }
        yytop -= yyLen[yyn];
        yystate = yystates[yytop].state;
        int yyM = yyLhs[yyn];
        if (yystate == 0 && yyM == 0) {
            if (yydebug != null) yydebug.shift(0, yyFinal);
            yystate = yyFinal;
            if (yytoken == NEEDS_TOKEN) {
                yytoken = yyLex.nextToken();
                if (yydebug != null) yydebug.lex(yystate, yytoken,yyName(yytoken), yyLex.value());
            }
            if (yytoken == 0) {
                if (yydebug != null) yydebug.accept(yyVal);
                return yyVal;
            }
            continue yyLoop;
        }
        yyn = yyGindex[yyM];
        if (yyn != 0 &&
            (yyn += yystate) >= 0 &&
            yyn < yyTable.length &&
            yyCheck[yyn] == yystate) {
            yystate = yyTable[yyn];
        } else {
            yystate = yyDgoto[yyM];
        }
        if (yydebug != null) yydebug.shift(yystates[yytop].state, yystate);
        continue yyLoop;
      }
    }
  }
public Object yyparse ( RubyLexer yyLex ) throws java . io . IOException { int yystate = 0 ; Object yyVal = null ; ProductionState [ ] yystates = new ProductionState [ YYMAX ] ; initializeStates ( yystates , 0 , yystates . length ) ; int yytoken = NEEDS_TOKEN ; int yyErrorFlag = 0 ; int start = 0 ; int end = 0 ; yyLoop : for ( int yytop = 0 ; ; yytop ++ ) { if ( yytop + 1 >= yystates . length ) { ProductionState [ ] newStates = new ProductionState [ yystates . length + YYMAX ] ; System . arraycopy ( yystates , 0 , newStates , 0 , yystates . length ) ; initializeStates ( newStates , yystates . length , newStates . length - yystates . length ) ; yystates = newStates ; } yystates [ yytop ] . state = yystate ; yystates [ yytop ] . value = yyVal ; yystates [ yytop ] . start = start ; yystates [ yytop ] . end = end ; if ( yydebug != null ) yydebug . push ( yystate , yyVal ) ; yyDiscarded : for ( ; ; ) { int yyn = yyDefRed [ yystate ] ; if ( yyn == DEFAULT ) { if ( yytoken == NEEDS_TOKEN ) { yytoken = yyLex . nextToken ( ) ; if ( yydebug != null ) yydebug . lex ( yystate , yytoken , yyName ( yytoken ) , yyLex . value ( ) ) ; } yyn = yySindex [ yystate ] ; if ( yyn != 0 && ( yyn += yytoken ) >= 0 && yyn < yyTable . length && yyCheck [ yyn ] == yytoken ) { if ( yydebug != null ) yydebug . shift ( yystate , yyTable [ yyn ] , yyErrorFlag - 1 ) ; yystate = yyTable [ yyn ] ; yyVal = yyLex . value ( ) ; start = yyLex . start ; end = yyLex . end ; yytoken = NEEDS_TOKEN ; if ( yyErrorFlag > 0 ) -- yyErrorFlag ; continue yyLoop ; } yyn = yyRindex [ yystate ] ; if ( yyn != 0 && ( yyn += yytoken ) >= 0 && yyn < yyTable . length && yyCheck [ yyn ] == yytoken ) { yyn = yyTable [ yyn ] ; } else { switch ( yyErrorFlag ) { case 0 : support . yyerror ( "syntax error" , yyExpecting ( yystate ) , yyNames [ yytoken ] ) ; if ( yydebug != null ) yydebug . error ( "syntax error" ) ; case 1 : case 2 : yyErrorFlag = 3 ; do { yyn = yySindex [ yystates [ yytop ] . state ] ; if ( yyn != 0 && ( yyn += yyErrorCode ) >= 0 && yyn < yyTable . length && yyCheck [ yyn ] == yyErrorCode ) { if ( yydebug != null ) yydebug . shift ( yystates [ yytop ] . state , yyTable [ yyn ] , 3 ) ; yystate = yyTable [ yyn ] ; yyVal = yyLex . value ( ) ; continue yyLoop ; } if ( yydebug != null ) yydebug . pop ( yystates [ yytop ] . state ) ; } while ( -- yytop >= 0 ) ; if ( yydebug != null ) yydebug . reject ( ) ; support . yyerror ( "irrecoverable syntax error" ) ; case 3 : if ( yytoken == 0 ) { if ( yydebug != null ) yydebug . reject ( ) ; support . yyerror ( "irrecoverable syntax error at end-of-file" ) ; } if ( yydebug != null ) yydebug . discard ( yystate , yytoken , yyName ( yytoken ) , yyLex . value ( ) ) ; yytoken = NEEDS_TOKEN ; continue yyDiscarded ; } } } if ( yydebug != null ) yydebug . reduce ( yystate , yystates [ yytop - yyLen [ yyn ] ] . state , yyn , yyRule [ yyn ] , yyLen [ yyn ] ) ; ParserState parserState = states [ yyn ] ; if ( parserState == null ) { yyVal = yyLen [ yyn ] > 0 ? yystates [ yytop - yyLen [ yyn ] + 1 ] . value : null ; } else { int count = yyLen [ yyn ] ; start = yystates [ yytop - count + 1 ] . start ; end = yystates [ yytop ] . end ; yyVal = parserState . execute ( support , lexer , yyVal , yystates , yytop , count ) ; } yytop -= yyLen [ yyn ] ; yystate = yystates [ yytop ] . state ; int yyM = yyLhs [ yyn ] ; if ( yystate == 0 && yyM == 0 ) { if ( yydebug != null ) yydebug . shift ( 0 , yyFinal ) ; yystate = yyFinal ; if ( yytoken == NEEDS_TOKEN ) { yytoken = yyLex . nextToken ( ) ; if ( yydebug != null ) yydebug . lex ( yystate , yytoken , yyName ( yytoken ) , yyLex . value ( ) ) ; } if ( yytoken == 0 ) { if ( yydebug != null ) yydebug . accept ( yyVal ) ; return yyVal ; } continue yyLoop ; } yyn = yyGindex [ yyM ] ; if ( yyn != 0 && ( yyn += yystate ) >= 0 && yyn < yyTable . length && yyCheck [ yyn ] == yystate ) { yystate = yyTable [ yyn ] ; } else { yystate = yyDgoto [ yyM ] ; } if ( yydebug != null ) yydebug . shift ( yystates [ yytop ] . state , yystate ) ; continue yyLoop ; } } }
the generated parser.
the generated parser .
// stack of states and values. // current token // #tokens to shift // dynamically increase //         printstates(yytop, yystates); // discarding a token does not change stack //ja else [default] reduce (yyn) // shift to yyn // reduce (yyn) // falls through... // throws // leave stack alone // ACTIONS_END (line used by optimize_parser)