예제 #1
0
std::string TreeBuilder::getExpectedTokensGrammar() const
{
	std::vector<std::string> tokens = getExpectedTokens();
	if (tokens.empty())
		return "No productions expected";
	std::string result(tokens.at(0));
	if (tokens.size() > 1)
	{
		result += ": [\n";
		for (std::size_t i = 1; i < tokens.size(); ++i)
		{
			result += "\t" + tokens[i] + ",\n";
		}
		result.erase(result.end() - 1);
		return result + "\n]";
	}
	return result;
}
예제 #2
0
void PlSqlParser::correctError(int *token, ParsingTableRow *row, ParsingTableAction **actionOnCurrentToken)
{
    //qDebug("--------started error recovery--------------");
    bool reservedWord = parsingTable->isReservedWord(scanner->getTokenLexeme());

    if(*token!=PLS_SEMI){
        *actionOnCurrentToken=row->actions->value(PLS_NOT_SEMI, 0);

        if(!reservedWord){
            replaceKeywordWithIdentifier(*token, row, actionOnCurrentToken);
        }
    }

    if(*actionOnCurrentToken == 0 && !this->strict){ //try to recognize major constructs
        //read input until we encounter one of (first of) PLS_SEMI, END opt_identifier PLS_SEMI
        //while reading add all read tokens to token stack
        QList<TokenInfo*> reduceTokens;
        bool hasNonUsedReduceTokens = false;
        do{
            if(!reservedWord || countOnLastPosition>maxStayCountOnSamePosition){
                reduceTokens.prepend(createTokenInfo(*token));
                hasNonUsedReduceTokens = true;
            }

            if(*token == PLS_SEMI || reservedWord){
                int reducedConstruct = 0;
                QList<int> expectedTerminals = getExpectedTokens(row).first;
                //bool waitingForSemicolon = (expectedTerminals.size()==1 && expectedTerminals[0]==PLS_SEMI);
                bool waitingForSemicolon = expectedTerminals.contains(PLS_SEMI);
                if(reservedWord && countOnLastPosition<=maxStayCountOnSamePosition &&
                        !waitingForSemicolon){ //if current token is reserved word, try to reduce expression first
                    int constuctsToCheck[] = {R_EXPRESSION, R_DECLARATION, R_STATEMENT};
                    reducedConstruct = reduceMajorConstruct(reduceTokens, constuctsToCheck, 3);
                }else{ //on semicolon try to reduce declaration or statement
                    int constuctsToCheck[] = {R_DECLARATION, R_STATEMENT};
                    reducedConstruct = reduceMajorConstruct(reduceTokens, constuctsToCheck, 2);
                }
                if(reducedConstruct){
                    //read next token for parser to operate
                    if(!reservedWord || countOnLastPosition>maxStayCountOnSamePosition){
                        *token = scanner->getNextToken();
                        if(*token == PLS_SEMI){
                            correctError(token, row, actionOnCurrentToken);
                        }
                    }
                    ParsingTableRow *newRow=parsingTable->rows.at(stack.top()); //reduceMajorConstruct pushed new gotoState into stack
                    *actionOnCurrentToken=(*newRow->actions).value(*token, 0);

                    replaceKeywordWithIdentifier(*token, newRow, actionOnCurrentToken);
                }else{
                    qDeleteAll(reduceTokens);
                }
                hasNonUsedReduceTokens = false;

                break;
            }

            *token = scanner->getNextToken();
            reservedWord = parsingTable->isReservedWord(scanner->getTokenLexeme());
        }while(*token != PLS_E_O_F);

        if(hasNonUsedReduceTokens){
            qDeleteAll(reduceTokens);
        }
    }

    if(scanner->getTokenStartPos() == lastErrorPosition){
        ++countOnLastPosition;
    }else if(countOnLastPosition > 0){
        countOnLastPosition = 0;
    }
    lastErrorPosition = scanner->getTokenStartPos();

        //qDebug("--------completed error recovery--------------");
}