/*************************************************************** * Function: CodeParser::parseParamExpr() * Purpose : Parse the XML code of a parameterized expression * Initial : Maxime Chevalier-Boisvert on November 7, 2008 **************************************************************** Revisions and bug fixes: */ Expression* CodeParser::parseParamExpr(const XML::Element* pElement) { // Parse the symbol expression Expression* pExpr = parseExpression(pElement->getChildElement(0)); // Compute the number of arguments size_t numArgs = pElement->getNumChildren() - 1; // Declare a vector for the arguments ParamExpr::ExprVector arguments; // For each child element for (size_t i = 0; i < numArgs; ++i) { // Parse this argument arguments.push_back(parseExpression(pElement->getChildElement(i + 1))); } // Create and return the new parameterized expression return new ParamExpr( pExpr, arguments ); }
SymbolTableEntry* Parser::parseVariablePrime(SymbolTableEntry* prevEntry){ if(isNext(tc_LBRACKET)){ match(tc_LBRACKET); parseExpression(); match(tc_RBRACKET); if(m_parserError){ TokenCode synch[] = {tc_RBRACKET, tc_END, tc_ASSIGNOP, tc_MULOP, tc_RELOP, tc_THEN, tc_DO, tc_COMMA, tc_RPAREN, tc_NONE}; recover(synch); // if(isNext(tc_RBRACKET)){ // match(tc_RBRACKET); // } } } return prevEntry; }
/*! * rule ::= 'id' ( '::=' | '->' ) expression */ RuleNode* Parser::parseRule() { std::string name = token_value_; consumeToken(); if (token_ != Lexer::Token::coloncolonequal && token_ != Lexer::Token::minusgreater) { return static_cast<RuleNode*>(errorNode("missing terminating character \"::=\" or\" ->\"")); } consumeToken(); Node* node = parseExpression(); return new RuleNode(name, node); }
shared_ptr<Expression> Parser::parseFactor() { if (it->tag == IDENT || it->tag == INT || it->tag == FLOAT) { auto exp = make_shared<Expression>(); exp->value = *it; return exp; } else if (it->tag == OpenBracket) { auto exp = parseExpression(); match(CloseBracket); return exp; } }
Symbol parseExpressionStatement(CharacterSource* source) { CharacterSource s = *source; Symbol expression = parseExpression(&s); if (!expression.valid()) return Symbol(); Span span; if (!Space::parseCharacter(&s, ';', &span)) return Symbol(); *source = s; if (expression.atom() != atomFunctionCall) source->location().throwError("Statement has no effect"); return Symbol(atomExpressionStatement, expression, newSpan(spanOf(expression) + span)); }
void parseArrayDefineNode(std::string&result,ArrayDefineNode*seg){ if(seg == NULL){ return; } char numStr[N_INT_CHAR]; sprintf(numStr, "%d", ++lineno); result+="{\"name\":\"" + std::string(numStr) + ": array define\",\"children\":["; result+="{\"name\":\"" + std::string(seg->type) + "\"},"; result+="{\"name\":\"" + std::string(seg->name) + "\"},"; result += "{\"name\":\"nElement\",\"children\":[{\"name\":\""; parseExpression(result, seg->exp); result += "\"}]}"; result+="]}"; }
static bool parseFunctionCall(MemoryStack* stack, LexerCarriage* carriage, Array<SyntaxError>* errors, ASTNode* result) { LexerCarriage tmpCarriage = *carriage; if (tmpCarriage.topToken.type == TOK_IDENTIFIER) { Token identifier = tmpCarriage.topToken; parseNextToken(&tmpCarriage); if (tmpCarriage.topToken.type == TOK_OPEN_BRACKET) { parseNextToken(&tmpCarriage); result->nodeType = AST_FUNCTION_CALL; result->functionCall.lineNumber = carriage->currentLineNumber; result->functionCall.identifier = identifier.identifierValue; result->functionCall.arguments = { }; if (tmpCarriage.topToken.type != TOK_CLOSE_BRACKET) { ASTNode argument; do { if (parseExpression(stack, &tmpCarriage, errors, &argument)) { *pushElement(&result->functionCall.arguments, stack) = argument; if (tmpCarriage.topToken.type == TOK_COMMA) parseNextToken(&tmpCarriage); else break; } else { pushBack(errors, SyntaxError{ SET_EXPRESSION_EXPECTED }); break; } } while (true); } expectAndEat(&tmpCarriage, TOK_CLOSE_BRACKET, errors); *carriage = tmpCarriage; return true; } } return false; }
IfNode* Parser::parseIf() { uint32_t token = _currentTokenIndex; ensureKeyword("if"); ensureToken(tLPAREN); AstNode* ifExpr = parseExpression(); ensureToken(tRPAREN); BlockNode* thenBlock = parseBlock(true); BlockNode* elseBlock = 0; if (currentTokenValue() == "else") { consumeToken(); elseBlock = parseBlock(true); } return new IfNode(token, ifExpr, thenBlock, elseBlock); }
/*** Parse a return statement ***/ Return* Parser::parseReturn() { if(!hasTokens() || peekToken().getType() != T_RETURN) throw ParserSyntaxException(getToken(), "Expected \"return\" command!"); Token tok = getToken(); std::auto_ptr<Return> ret(new Return()); ret->setLineNumber(tok.getLineNumber()); ret->setColumnNumber(tok.getColumnNumber()); if(!hasTokens() || peekToken().getType() == T_EOL) return ret.release(); std::auto_ptr<Object> expr(parseExpression()); ret->setExpression(expr.release()); return ret.release(); }
int main() { TTable mujTable; table = &mujTable; tableInit(table); tableInsertFunction(table, strCreateString("fce")); functionInsertVar(table->lastAddedFunc, strCreateString("x")); functionInsertVar(table->lastAddedFunc, strCreateString("y")); functionInsertVar(table->lastAddedFunc, strCreateString("z")); printf("\nJedna funkce: \n"); tablePrintOrder(*table); printf("\n----------------------------\n"); //tiskniPrecTab(); FILE *f = fopen("testy/test-expr2.txt","r"); setSourceFile(f); strInit(&attr); listInit(&table->lastAddedFunc->tmpVar); int err = EOK; TVar *x = NULL; int test = 1; token = 1; while(token != END_OF_FILE) { token = getNextToken(&attr); x = NULL; err = parseExpression(table, &x); printf("Test %d skoncil s chybou: %d a vysledkem: %d \n", test,err, (int)x); test++; while (token != END_OF_FILE && token != L_SEMICOLON) { token = getNextToken(&attr); } } tiskniList(&table->lastAddedFunc->instructions); listDataDelete(&table->lastAddedFunc->tmpVar); listDispose(&table->lastAddedFunc->tmpVar); fclose(f); tableClear(table); strFree(&attr); return EXIT_SUCCESS; }
// <parenexpr> ::= '(' <expression> ')' IAstExpression *Parser::parseParenExpression() { if (_curTokenType != '(') { return Error("Expected '('."); } next(); // eat '(' IAstExpression *expr = parseExpression(); if (expr == nullptr) { return nullptr; } if (_curTokenType != ')') { return Error("Expected ')'."); } next(); // eat ')' return expr; }
PrintNode* Parser::parsePrint() { uint32_t token = _currentToken; ensureKeyword("print"); ensureToken(tLPAREN); PrintNode* result = new PrintNode(token); while (currentToken() != tRPAREN) { AstNode* operand = parseExpression(); result->add(operand); if (currentToken() == tCOMMA) { consumeToken(); } } ensureToken(tRPAREN); ensureToken(tSEMICOLON); return result; }
// <primary> ::= <parenexpr> // | <identifier> // | <string> // | <bool> // | <number> IAstExpression *Parser::parsePrimary() { if (_curToken->IsUnaryOperator()) { IAstExpression *unary = parsePrefixUnaryExpr(); if (unary != nullptr) { return unary; } } switch (_curTokenType) { default: return nullptr; case '(': return parseParenExpression(); case ';': next(); return parseExpression(); case tok_identifier: return parseIdentifierExpression(); case tok_string: return parseStringExpression(); case tok_bool: return parseBooleanExpression(); case tok_number: return parseNumberExpression(); } }
/*** Parse an assign statement ***/ Assign* Parser::parseAssign() { if(!hasTokens() || peekToken().getType() != T_IDENTIFIER) throw ParserSyntaxException(getToken(), "Expected variable identifier!"); std::auto_ptr<Variable> target(new Variable(getToken().getLexeme())); if(!hasTokens() || peekToken().getType() != T_ASSIGN) throw ParserSyntaxException(getToken(), "Expected ':='!"); Token tok = getToken(); std::auto_ptr<Object> expr(parseExpression()); Assign* as = new Assign(target.release(), expr.release()); as->setLineNumber(tok.getLineNumber()); as->setColumnNumber(tok.getColumnNumber()); return as; }
static PSmmAstNode parseAssignment(PSmmParser parser, PSmmAstNode lval) { PSmmToken eqToken = parser->curToken; getNextToken(parser); PSmmAstNode val = parseExpression(parser); if (val == &errorNode) { findToken(parser, ';'); return &errorNode; } if (val->kind == nkSmmParamDefinition) return val; PSmmAstNode assignment = smmNewAstNode(nkSmmAssignment, parser->a); assignment->left = lval; assignment->right = val; assignment->type = lval->type; assignment->token = eqToken; return assignment; }
Symbol parseIncrementDecrementStatement(CharacterSource* source) { Span span; Symbol function; if (Space::parseOperator(source, increment, &span)) function = Symbol(atomIncrement); else if (Space::parseOperator(source, decrement, &span)) function = Symbol(atomDecrement); else return Symbol(); CharacterSource s = *source; Symbol lValue = parseExpression(&s); *source = s; Span span2; Space::assertCharacter(source, ';', &span2); return Symbol(atomFunctionCall, function, SymbolArray(lValue), newSpan(span + span2)); }
void Parser::parseStatementPrime(SymbolTableEntry* prevEntry){ if(isNext(tc_LBRACKET) || isNext(tc_ASSIGNOP)){ SymbolTableEntry* var = parseVariablePrime(prevEntry); match(tc_ASSIGNOP); if(m_parserError){ TokenCode synch[] = {tc_ID, tc_NUMBER, tc_LPAREN, tc_NOT, tc_ADDOP, tc_NONE}; recover(synch); // if(isNext(tc_ASSIGNOP)){ // match(tc_ASSIGNOP); // } } SymbolTableEntry* exp = parseExpression(); m_code->generate(cd_ASSIGN, exp, NULL, var); } else{ parseProcedureStatementPrime(prevEntry); } }
Ptr<AST::Declaration> Parser::parseDeclaration () { AST::Declaration *declaration = nullptr; Token declarator = m_lexer.curr(); if (!declarator.is(TT::KeywordBool) && !declarator.is(TT::KeywordInt) && !declarator.is(TT::KeywordReal)) { return nullptr; } m_lexer.pop(); Token identifier = m_lexer.curr(); if (!identifier.is(TT::Identifier)) { return nullptr; } m_lexer.pop(); if (!m_lexer.curr().is(TT::Assignment)) { return nullptr; } m_lexer.pop(); AST::Expression *expression = parseExpression(); if (expression == nullptr) { return nullptr; } if (!m_lexer.curr().is(TT::StatementSep)) { return nullptr; } m_lexer.pop(); return declaration; }
AstNode* Parser::parseUnary() { if (isUnaryOp(currentToken())) { TokenKind op = currentToken(); consumeToken(); return new UnaryOpNode(_currentTokenIndex, op, parseUnary()); } else if (currentToken() == tIDENT && lookaheadToken(1) == tLPAREN) { AstNode* expr = parseCall(); return expr; } else if (currentToken() == tIDENT) { AstVar* var = _currentScope->lookupVariable(currentTokenValue()); if (var == 0) { error("undeclared variable: %s", currentTokenValue().c_str()); } LoadNode* result = new LoadNode(_currentTokenIndex, var); consumeToken(); return result; } else if (currentToken() == tDOUBLE) { DoubleLiteralNode* result = new DoubleLiteralNode(_currentTokenIndex, parseDouble(currentTokenValue())); consumeToken(); return result; } else if (currentToken() == tINT) { IntLiteralNode* result = new IntLiteralNode(_currentTokenIndex, parseInt(currentTokenValue())); consumeToken(); return result; } else if (currentToken() == tSTRING) { StringLiteralNode* result = new StringLiteralNode(_currentTokenIndex, currentTokenValue()); consumeToken(); return result; } else if (currentToken() == tLPAREN) { consumeToken(); AstNode* expr = parseExpression(); ensureToken(tRPAREN); return expr; } else { error("Unexpected token: %s", tokenStr(currentToken())); return 0; } }
Symbol parseAssignmentStatement(CharacterSource* source) { CharacterSource s = *source; Symbol lValue = parseExpression(&s); Location operatorLocation = s.location(); if (!lValue.valid()) return Symbol(); Symbol function; Span span; if (Space::parseCharacter(&s, '=', &span)) function = Symbol(atomAssignment); else if (Space::parseOperator(&s, addAssignment, &span)) function = Symbol(atomAddAssignment); else if (Space::parseOperator(&s, subtractAssignment, &span)) function = Symbol(atomSubtractAssignment); else if (Space::parseOperator(&s, multiplyAssignment, &span)) function = Symbol(atomMultiplyAssignment); else if (Space::parseOperator(&s, divideAssignment, &span)) function = Symbol(atomDivideAssignment); else if (Space::parseOperator(&s, moduloAssignment, &span)) function = Symbol(atomModuloAssignment); else if (Space::parseOperator(&s, shiftLeftAssignment, &span)) function = Symbol(atomShiftLeftAssignment); else if (Space::parseOperator(&s, shiftRightAssignment, &span)) function = Symbol(atomShiftRightAssignment); else if (Space::parseOperator(&s, bitwiseAndAssignment, &span)) function = Symbol(atomBitwiseAndAssignment); else if (Space::parseOperator(&s, bitwiseOrAssignment, &span)) function = Symbol(atomBitwiseOrAssignment); else if (Space::parseOperator(&s, bitwiseXorAssignment, &span)) function = Symbol(atomBitwiseXorAssignment); else if (Space::parseOperator(&s, powerAssignment, &span)) function = Symbol(atomPowerAssignment); if (!function.valid()) return Symbol(); *source = s; Symbol e = parseExpressionOrFail(source); Space::assertCharacter(source, ';', &span); return Symbol(atomFunctionCall, function, SymbolArray(Symbol(atomAddressOf, lValue), e), new ExpressionCache(spanOf(lValue) + span)); }
ExprAST *Parser::parseString (const std::string &f) { formula = parseBuffer = f; getNextToken (); ExprAST *result = parseExpression (); // If there's any junk left over after an otherwise // successful parse, there's an error if (result && (currentToken != TOKEN_END || parseBuffer != "")) { error ("Parsed a complete expression, but content still remains in the formula!"); delete result; return NULL; } return result; }
ExprAST *Parser::parseUnaryMinusExpr () { // Eat the unary minus getNextToken (); // Another unary minus can't immediately follow a unary minus // (the only such restriction) if (currentToken == TOKEN_OPERATOR && strToken == "-") { error ("Two unary minus operators cannot be in immediate succession. " "If this is what you intend, use parentheses."); return NULL; } ExprAST *child = parseExpression (); if (!child) return NULL; return new UnaryMinusExprAST (child); }
/** * Compiles a field declaration */ int CodeParser::parseField( Scope* scope, const char* name, TypeReference* type, TokenStack* stack ) { int errorCode = 0; Token *t1, *t2; const char* data; // create the field, and attach it to the class Field* field = new Field( name, type, this->modifiers ); printf( "field '%s' type='%s' modifiers = %s\n", name, type->getName(), toBinary( this->modifiers ) ); // reset the modifier for the current scope this->modifiers = 0; // is there also an assignment? if( stack->hasNext() && !strcmp( stack->peek()->getText(), "=" ) ) { // capture the t1 = stack->next(); // there must be another token if( !( t2 = stack->next() ) ) { SYNTAX_ERROR( "Unexpected end of statement", t1 ); return NULL; } switch( t2->getType() ) { case tok::SQUOTE_TEXT:; case tok::DQUOTE_TEXT: data = t2->getText(); setupAssignment( scope, field, data ); break; default: parseExpression( scope, stack ); } } // add the field to the scope if( !errorCode ) { scope->addField( field ); } // TODO there may be an expression: int x = 5 * y + 1; return errorCode; }
CallNode* Parser::parseCall() { uint32_t tokenIndex = _currentTokenIndex; assert(currentToken() == tIDENT); const string& callee = currentTokenValue(); consumeToken(); ensureToken(tLPAREN); vector<AstNode*> args; while (currentToken() != tRPAREN) { args.push_back(parseExpression()); if (currentToken() == tCOMMA) { consumeToken(); } else { break; } } ensureToken(tRPAREN); return new CallNode(tokenIndex, callee, args); }
/*! * factor ::= ( 'id' | 'text' | '(' expression ')' ) ( '+' | '*' | ) */ Node* Parser::parseFactor() { Node* n = 0; switch (token_) { case Lexer::Token::identifier: n = new SymbolNode(token_value_); consumeToken(); break; case Lexer::Token::text: n = new TerminalNode(token_value_.substr(1, token_value_.size() - 2)); consumeToken(); break; case Lexer::Token::l_paren: consumeToken(); n = new ParenNode(parseExpression()); if (token_ != Lexer::Token::r_paren) { return errorNode("missing terminating character \")\""); } consumeToken(); break; default: assert(false && "unexpected token"); break; } switch (token_) { case Lexer::Token::plus: consumeToken(); n = new PlusNode(n); break; case Lexer::Token::star: consumeToken(); n = new StarNode(new PlusNode(n)); break; default: break; } return n; }
shared_ptr<AssignStmt> Parser::parseAssign() { auto assign = make_shared<AssignStmt>(); auto exp = make_shared<Expression>(); exp->value = *it; assign->left = exp; it++; match(BIND); assign->value = *it; it++; assign->right = parseExpression(); //it++; if (!(find(SEMI) || find(TO))) { Error err("syntax error", *it); errList.push_back(err); } //记录赋值表达式的id到符号表 return assign; }
void Parser::parseFormals() { Token t = lex.peek(); if (t.type != Token::RPAREN) while (1) { parseFormalType(); parseExpression(); t = lex.peek(); if (t.type == Token::SEMI) { lex.consume(Token::SEMI); t = lex.peek(); } else break; if (t.type == Token::RPAREN) break; } }
ExprAST* Parser::handleTopLevelExpr() { switch (lexer->token) { case '[': return handleVarDef(); case Lexer::TOK_RETURN: return handleReturn(); case Lexer::TOK_IF: return handleCondition(); case Lexer::TOK_FOR: return handleForLoop(); case Lexer::TOK_BREAK: lexer->NextToken(); return new BreakAST(); case Lexer::TOK_CONTINUE: lexer->NextToken(); return new ContinueAST(); default: return parseExpression(); } }
Expression *ASTBuilder::parseTopLevelStatement() { // get the type Token *type = getNextToken(); if(type == NULL) return NULL; Token *symbolName = getCurrentToken(); if(symbolName == NULL) return NULL; if(!isSymbol(symbolName->getData())) { cout << "Error: astbuilder.cpp:33" << endl; } // next need to check what comes after, // an equals => variable assigment, // an argument list => function definition, // another typename => variable definition w/out assigment Token *next = peekNextToken(); // there's not another token if(next == NULL) { return new VarExpression(symbolName->getData()); }else if(!next->getData().compare("=")) { getNextToken(); // eat the name Token *t = getNextToken(); // and the '=' return new BinaryExpression('=', new VarExpression(symbolName->getData()), parseExpression()); } else if(!next->getData().compare("|")) { return parseFunctionDefinition(); } else if(isBuiltinTypeName(next->getData())) { getNextToken(); return new VarExpression(symbolName->getData()); } return NULL; }
/*** Parse a do statement ***/ Do* Parser::parseDo() { if(!hasTokens() || peekToken().getType() != T_DO) ParserSyntaxException(getToken(), "Expected do command!"); Token tok = getToken(); // Parse any newlines while(hasTokens() && peekToken().getType() == T_EOL) getToken(); std::auto_ptr<Do> result(new Do()); result->setLineNumber(tok.getLineNumber()); result->setColumnNumber(tok.getColumnNumber()); // Add commands until "od" or "until" is found std::auto_ptr<NodeList> doStmts(new NodeList()); while(hasTokens() && !(peekToken().getType() == T_OD || peekToken().getType() == T_UNTIL)) { doStmts->pushNode(parseStatement()); parseSeparation(); } if(hasTokens() && peekToken().getType() == T_OD) { getToken(); result->setStatements(doStmts.release()); return result.release(); } else if(hasTokens() && peekToken().getType() == T_UNTIL) { getToken(); std::auto_ptr<Object> until(parseExpression()); result->setStatements(doStmts.release()); result->setUntilCondition(until.release()); return result.release(); } else throw ParserSyntaxException(getToken(), "Expected \"od\" or \"until\" command!"); return 0; }