struct statementNode* stmt_list() { struct statementNode* st; // statement struct statementNode* st1; // statement list struct statementNode* no_op; struct statementNode* gt; st = stmt(); if(ttype == RBRACE) { getToken(); } ttype = getToken(); //printf("TTYPE before %d\n",ttype); if (((ttype == ID)||(ttype == WHILE)||(ttype == PRINT)||(ttype == IF))) { //printf("TTYPE after %d\n",ttype); ungetToken(); st1 = stmt_list(); findLast(st)->next = st1; //stmt head stmt_head = st; return st; } else { return st; } }
struct var_declNode* var_decl() { struct var_declNode* varDecl; struct id_listNode* idList; varDecl = make_var_decl(); idList = make_id_list(); int i = 0; varDecl->id_list = NULL; ttype = getToken(); if (ttype == ID) { ungetToken(); varDecl->id_list = id_list(); ttype = getToken(); if (ttype == SEMICOLON) { //printf("ttype %d\n", ttype); return varDecl; } } return varDecl; }
Expression *parseExpression( FILE *source, Expression *lvalue ) { Token token = scanner(source); Expression *expr; switch(token.type){ case PlusOp: expr = (Expression *)malloc( sizeof(Expression) ); (expr->v).type = PlusNode; (expr->v).val.op = Plus; expr->leftOperand = lvalue; expr->rightOperand = parsePreTerm(source); return parseExpressionTail(source, expr); case MinusOp: expr = (Expression *)malloc( sizeof(Expression) ); (expr->v).type = MinusNode; (expr->v).val.op = Minus; expr->leftOperand = lvalue; expr->rightOperand = parsePreTerm(source); return parseExpressionTail(source, expr); case Alphabet: case PrintOp: ungetToken(token); return NULL; case EOFsymbol: return NULL; default: printf("Syntax Error:(parseExpression) Expect a numeric value or an identifier %s\n", token.tok); exit(1); } }
struct ifStatement* ifSt() { struct ifStatement* ifSt; ifSt = make_ifSt(); ttype = getToken(); if (ttype == IF) { ifSt->condition = condition(); ttype = getToken(); if(ttype == LBRACE) { ungetToken(); ifSt->stmt_list = body(); return ifSt; } else { return NULL; } } else { return NULL; } }
struct id_listNode* id_list() { struct id_listNode* idList; idList = make_id_list(); ttype = getToken(); if (ttype == ID) { idList->id = (char*) malloc(tokenLength+1); strcpy(idList->id, token); symAdd(idList->id); ttype = getToken(); if (ttype == COMMA) { idList->id_list = id_list(); return idList; } else { ungetToken(); return idList; } } else { return NULL; } }
bool MacroExpander::isNextTokenLeftParen() { Token token; getToken(&token); bool lparen = token.type == '('; ungetToken(token); return lparen; }
// NAME [outputPath] [BASE=address] bool Parser::parseName(std::string &outputPath, uint64_t &baseaddr) { consumeToken(); if (_tok._kind == Kind::identifier) { outputPath = _tok._range; } else { outputPath = ""; ungetToken(); return true; } consumeToken(); if (_tok._kind == Kind::kw_base) { if (!expectAndConsume(Kind::equal, "'=' expected")) return false; if (!consumeTokenAsInt(baseaddr)) return false; } else { ungetToken(); baseaddr = 0; } return true; }
bool Parser::parseExport(PECOFFLinkingContext::ExportDesc &result) { consumeToken(); if (_tok._kind != Kind::identifier) { ungetToken(); return false; } result.name = _tok._range; consumeToken(); if (_tok._kind == Kind::equal) { consumeToken(); if (_tok._kind != Kind::identifier) return false; result.externalName = result.name; result.name = _tok._range; } else { ungetToken(); } for (;;) { consumeToken(); if (_tok._kind == Kind::identifier && _tok._range[0] == '@') { _tok._range.drop_front().getAsInteger(10, result.ordinal); consumeToken(); if (_tok._kind == Kind::kw_noname) { result.noname = true; } else { ungetToken(); } continue; } if (_tok._kind == Kind::kw_data) { result.isData = true; continue; } ungetToken(); return true; } }
bool Parser::consumeTokenAsInt(uint64_t &result) { consumeToken(); if (_tok._kind != Kind::identifier) { ungetToken(); error(_tok, "Integer expected"); return false; } if (_tok._range.getAsInteger(10, result)) { error(_tok, "Integer expected"); return false; } return true; }
bool readTextChar(Element_Type& ch) { if (!readToken(&ch)) return false; Element_Type ch2 = 0; switch(ch) { case 10: ch = '\n'; if (readToken(&ch2) && ch2 != 13) ungetToken(ch2); break; case 13: ch = '\n'; if (readToken(&ch2) && ch2 != 10) ungetToken(ch2); break; } return true; }
// HEAPSIZE/STACKSIZE reserve[,commit] bool Parser::parseMemorySize(uint64_t &reserve, uint64_t &commit) { if (!consumeTokenAsInt(reserve)) return false; consumeToken(); if (_tok._kind != Kind::comma) { ungetToken(); commit = 0; return true; } if (!consumeTokenAsInt(commit)) return false; return true; }
/*---------------------------------------------------------------------*//** 次のトークンを得る(ポインタは次へ進めないでそのまま) 次のトークンをのぞき見るときに使う **//*---------------------------------------------------------------------*/ EsTokenType EsTokenParser::peekToken() { EsTokenType tt = TKN_NULL; if(_tb->isSave()) { tt = _tb->curSave()->getType(); } else { tt = nextToken(); ungetToken(); } return tt; }
/*-------------------------------------------------------------------- PARSING AND BUILDING PARSE TREE ---------------------------------------------------------------------*/ struct programNode* program() { struct programNode* prog; prog = make_programNode(); ttype = getToken(); if (ttype == VAR) { ungetToken(); prog->decl = decl(); prog->body = body(); return prog; } else { return NULL; } }
struct statementNode* stmt_list() { struct statementNode* st; // statement struct statementNode* st1; // statement list struct statementNode* no_op; struct gotoStatement* gt; st = stmt(); st1 = NULL; no_op = NULL; //call makestmt? ttype = getToken(); if (!stmt_head && (ttype == ID)|(ttype == WHILE)|(ttype == PRINT)|(ttype == IF)) { ungetToken(); st1 = stmt_list(); if (st->stmtType == IFSTMT) { st->ifSt->stmt_list->next = no_op; st->ifSt->condition->falseBranch = no_op; st->ifSt->condition->trueBranch = st->ifSt->stmt_list; //true? st->next = no_op; //append no_op to st? no_op->next = st1; } if(st->stmtType == WHILE) { gt->target = st; st->whileSt->stmt_list->next = gt->target; st->whileSt->condition->falseBranch = no_op; st->whileSt->condition->trueBranch = st->whileSt->stmt_list; st->next = no_op; no_op->next = st1; } st->next = st1; //stmt head stmt_head = st; return st; } else { return st; } }
Declarations *parseDeclarations( FILE *source ) { Token token = scanner(source); Declaration decl; Declarations *decls; switch(token.type){ case FloatDeclaration: case IntegerDeclaration: decl = parseDeclaration(source, token); decls = parseDeclarations(source); return makeDeclarationTree( decl, decls ); case PrintOp: case Alphabet: ungetToken(token); return NULL; case EOFsymbol: return NULL; default: printf("Syntax Error: Expect declarations %s\n", token.tok); exit(1); } }
bool MacroExpander::collectMacroArgs(const Macro ¯o, const Token &identifier, std::vector<MacroArg> *args, SourceLocation *closingParenthesisLocation) { Token token; getToken(&token); assert(token.type == '('); args->push_back(MacroArg()); for (int openParens = 1; openParens != 0; ) { getToken(&token); if (token.type == Token::LAST) { mDiagnostics->report(Diagnostics::PP_MACRO_UNTERMINATED_INVOCATION, identifier.location, identifier.text); // Do not lose EOF token. ungetToken(token); return false; } bool isArg = false; // True if token is part of the current argument. switch (token.type) { case '(': ++openParens; isArg = true; break; case ')': --openParens; isArg = openParens != 0; *closingParenthesisLocation = token.location; break; case ',': // The individual arguments are separated by comma tokens, but // the comma tokens between matching inner parentheses do not // seperate arguments. if (openParens == 1) args->push_back(MacroArg()); isArg = openParens != 1; break; default: isArg = true; break; } if (isArg) { MacroArg &arg = args->back(); // Initial whitespace is not part of the argument. if (arg.empty()) token.setHasLeadingSpace(false); arg.push_back(token); } } const Macro::Parameters ¶ms = macro.parameters; // If there is only one empty argument, it is equivalent to no argument. if (params.empty() && (args->size() == 1) && args->front().empty()) { args->clear(); } // Validate the number of arguments. if (args->size() != params.size()) { Diagnostics::ID id = args->size() < macro.parameters.size() ? Diagnostics::PP_MACRO_TOO_FEW_ARGS : Diagnostics::PP_MACRO_TOO_MANY_ARGS; mDiagnostics->report(id, identifier.location, identifier.text); return false; } // Pre-expand each argument before substitution. // This step expands each argument individually before they are // inserted into the macro body. for (std::size_t i = 0; i < args->size(); ++i) { MacroArg &arg = args->at(i); TokenLexer lexer(&arg); MacroExpander expander(&lexer, mMacroSet, mDiagnostics, mParseDefined); arg.clear(); expander.lex(&token); while (token.type != Token::LAST) { arg.push_back(token); expander.lex(&token); } } return true; }
int main() { //obsah souboru nas zajimat nebude FILE* f = fopen("test-1.txt", "r"); tToken t; printDescription("Do fronty tlacim bool = true"); t = malloc(sizeof(struct stToken)); t->typ = TYPE_BOOL; t->value.boolVal = true; ungetToken(&t); printDescription("Zkusim zavolat scanner ocekavam bool = true"); getToken(&t, f); if (t->typ == TYPE_BOOL && t->value.boolVal) { printDescription("TEST OK"); } else { printDescription("TEST FAILED"); } freeTokenMem(t); printDescription("Od ted testuji jen pomoci fce void TQDequeue(tToken*);"); printDescription("protoze jestli se vola skrz scanner j*z vime"); printDescription("Do fronty tlacim int = 42"); t = malloc(sizeof(struct stToken)); t->typ = TYPE_INTEGER; t->value.intVal = 42; ungetToken(&t); printDescription("Do fronty tlacim KEYW_RETURN"); t = malloc(sizeof(struct stToken)); t->typ = KEYW_RETURN; ungetToken(&t); printDescription("Ocekavam int = 42 fronta by nemela byt deinicializovana"); TQDequeue(&t); if (t->typ == TYPE_INTEGER && t->value.intVal == 42 && TQueue) { printDescription("TEST OK"); } else { printDescription("TEST FAILED"); } freeTokenMem(t); printDescription("Ocekavam return keyword fronta by mela byt deinicializovana"); TQDequeue(&t); if (t->typ == KEYW_RETURN && !TQueue) { printDescription("TEST OK"); } else { printDescription("TEST FAILED"); } freeTokenMem(t); printDescription("Do fronty tlacim string = 'HuaHuaString'"); t = malloc(sizeof(struct stToken)); t->typ = TYPE_STRING; strInit(&t->value.stringVal); strConConstString(&t->value.stringVal, "HuaHuaString"); ungetToken(&t); printDescription("Ocekavam string = 'HuaHuaString' fronta by mela byt deinicializovana"); string s; strInit(&s); strConConstString(&s, "HuaHuaString"); TQDequeue(&t); if (t->typ == TYPE_STRING && !strCmpString(&t->value.stringVal, &s) && !TQueue) { printDescription("TEST OK"); } else { printDescription("TEST FAILED"); } strFree(&s); freeTokenMem(t); printDescription("Zavolam void freeTokenMem(tToken); nad NULL"); printDescription("Nemela by nastat chyba"); printDescription("Test zrusen je to blbost"); //freeTokenMem(t); printDescription("Mam deinicializovanou frontu zkusim z ni neco vytahnout"); printDescription("behem programu nebude volano, ale pro jistotu"); TQDequeue(&t); if (!TQueue/* && !t*/) { printDescription("TEST OK"); } else { printDescription("TEST FAILED"); } //freeTokenMem(t);//pro jistotu getchar(); fclose(f); return 0; }
bool MacroExpander::collectMacroArgs(const Macro ¯o, const Token &identifier, std::vector<MacroArg> *args, SourceLocation *closingParenthesisLocation) { Token token; getToken(&token); ASSERT(token.type == '('); args->push_back(MacroArg()); // Defer reenabling macros until args collection is finished to avoid the possibility of // infinite recursion. Otherwise infinite recursion might happen when expanding the args after // macros have been popped from the context stack when parsing the args. ScopedMacroReenabler deferReenablingMacros(this); int openParens = 1; while (openParens != 0) { getToken(&token); if (token.type == Token::LAST) { mDiagnostics->report(Diagnostics::PP_MACRO_UNTERMINATED_INVOCATION, identifier.location, identifier.text); // Do not lose EOF token. ungetToken(token); return false; } bool isArg = false; // True if token is part of the current argument. switch (token.type) { case '(': ++openParens; isArg = true; break; case ')': --openParens; isArg = openParens != 0; *closingParenthesisLocation = token.location; break; case ',': // The individual arguments are separated by comma tokens, but // the comma tokens between matching inner parentheses do not // seperate arguments. if (openParens == 1) args->push_back(MacroArg()); isArg = openParens != 1; break; default: isArg = true; break; } if (isArg) { MacroArg &arg = args->back(); // Initial whitespace is not part of the argument. if (arg.empty()) token.setHasLeadingSpace(false); arg.push_back(token); } } const Macro::Parameters ¶ms = macro.parameters; // If there is only one empty argument, it is equivalent to no argument. if (params.empty() && (args->size() == 1) && args->front().empty()) { args->clear(); } // Validate the number of arguments. if (args->size() != params.size()) { Diagnostics::ID id = args->size() < macro.parameters.size() ? Diagnostics::PP_MACRO_TOO_FEW_ARGS : Diagnostics::PP_MACRO_TOO_MANY_ARGS; mDiagnostics->report(id, identifier.location, identifier.text); return false; } // Pre-expand each argument before substitution. // This step expands each argument individually before they are // inserted into the macro body. size_t numTokens = 0; for (auto &arg : *args) { TokenLexer lexer(&arg); if (mAllowedMacroExpansionDepth < 1) { mDiagnostics->report(Diagnostics::PP_MACRO_INVOCATION_CHAIN_TOO_DEEP, token.location, token.text); return false; } MacroExpander expander(&lexer, mMacroSet, mDiagnostics, mAllowedMacroExpansionDepth - 1); arg.clear(); expander.lex(&token); while (token.type != Token::LAST) { arg.push_back(token); expander.lex(&token); numTokens++; if (numTokens + mTotalTokensInContexts > kMaxContextTokens) { mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token.location, token.text); return false; } } } return true; }
struct statementNode* stmt() { struct statementNode* stm; struct printStatement* prt; struct varNode* temp; ttype = getToken(); if (ttype == ID) // assign_stmt { printf("stmt ID: %d\n",ttype); stm = make_stmt(ASSIGNSTMT); printf("token: %s\n",token); stm->assignSt = assignment(token); stm->stmtType = ASSIGNSTMT; ttype = getToken(); if (ttype == SEMICOLON) { printf("SEMICOLON: %d\n",ttype); return stm; } else { return NULL; } } else if (ttype == WHILE) // while_stmt { ungetToken(); stm = make_stmt(WHILESTMT); stm->whileSt = whileStatement(); stm->stmtType = WHILESTMT; ttype = getToken(); if(ttype = RBRACE) { return stm; } else { return NULL; } } else if (ttype == IF) { ungetToken(); stm = make_stmt(IFSTMT); stm->ifSt = ifSt(); stm->stmtType = IFSTMT; ttype = getToken(); if(ttype = RBRACE) { return stm; } else { return NULL; } } else if (ttype == PRINT) { printf("stmt PRINT: %d\n",ttype); stm = make_stmt(PRINTSTMT); ttype = getToken(); printf("token: %s\n",token); temp = symSearch(token); stm->stmtType = PRINTSTMT; if(temp != NULL) { prt = make_printSt(temp); stm->printSt = prt; ttype = getToken(); if(ttype == SEMICOLON) { return stm; } else { return NULL; } } else { return NULL; } //return stm; } else { return NULL; } }
struct assignNode* assignment() { struct assignNode* assign; struct varNode* var; struct varNode* op; int oper; var = symSearch(token); if(var != NULL) { //printf("var: %s\n",var->vID); assign = make_assign(var); ttype = getToken(); if(ttype == EQUAL) { //printf("EQUAL: %d\n",ttype); //assign = expr(assign); ttype = getToken(); if (ttype == NUM) { //printf("NUM: %d\n",ttype); op = make_var(); if(symSearch(token) == NULL) { symAdd(op); } assign->op1 = symSearch(token); /*assign->op1 = primary(assign->op1); ttype = getToken(); if ((ttype == PLUS) | (ttype == MINUS) | (ttype == MULT) | (ttype == DIV)) { assign->oper = ttype; //op is set + - * / assign->op2 = primary(assign->op2); } ungetToken(); return assign;*/ } else if (ttype == ID) { assign->op1 = symSearch(token); //printf("assign->op1->vValue %d\n", assign->op1->vValue); /*printf("ID: %d\n",ttype); assign->op1 = primary(assign->op1); printf("ASSIGN ID %s\n", assign->op1->id); ttype = getToken(); printf("PLUS: %d\n",ttype); if ((ttype == PLUS) | (ttype == MINUS) | (ttype == MULT) | (ttype == DIV)) { assign->oper = ttype; ttype = getToken(); if(ttype == ID) { printf("ID: %d\n",ttype); assign->op2 = primary(assign->op2); return assign; } else { ungetToken(); } } else { return NULL; } */ } ttype = getToken(); //printf("SIGN %d\n", ttype); if ((ttype == PLUS) | (ttype == MINUS) | (ttype == MULT) | (ttype == DIV)) { assign->oper = ttype; ttype = getToken(); if (ttype == NUM) { //printf("NUM: %d\n",ttype); op = make_var(); if(symSearch(token) == NULL) { symAdd(op); } assign->op2 = symSearch(token); /*assign->op1 = primary(assign->op1); ttype = getToken(); if ((ttype == PLUS) | (ttype == MINUS) | (ttype == MULT) | (ttype == DIV)) { assign->oper = ttype; //op is set + - * / assign->op2 = primary(assign->op2); } ungetToken(); return assign;*/ } else if (ttype == ID) { assign->op2 = symSearch(token); //printf("assign->op2->vValue %d\n", assign->op2->vValue); /*printf("ID: %d\n",ttype); assign->op1 = primary(assign->op1); printf("ASSIGN ID %s\n", assign->op1->id); ttype = getToken(); printf("PLUS: %d\n",ttype); if ((ttype == PLUS) | (ttype == MINUS) | (ttype == MULT) | (ttype == DIV)) { assign->oper = ttype; ttype = getToken(); if(ttype == ID) { printf("ID: %d\n",ttype); assign->op2 = primary(assign->op2); return assign; } else { ungetToken(); } } else { return NULL; } */ } return assign; } else { ungetToken(); return assign; } } else { return NULL; } } else { return NULL; } }
struct assignNode* expr(struct assignNode* assign) { struct varNode* oper1; struct varNode* oper2; int oper; ttype = getToken(); if (ttype == NUM) { printf("NUM: %d\n",ttype); assign->op1 = primary(); ttype = getToken(); if ((ttype == PLUS) | (ttype == MINUS) | (ttype == MULT) | (ttype == DIV)) { assign->oper = ttype; //op is set + - * / assign->op2 = primary(); } ungetToken(); return assign; } else if (ttype == ID) { printf("ID: %d\n",ttype); //oper1 = symSearch(token); /*if(oper1 != NULL) //{ //assign->op1->id = oper1->vID;*/ assign->op1 = primary(); printf("ASSIGN ID %s\n", assign->op1->id); ttype = getToken(); printf("PLUS: %d\n",ttype); if ((ttype == PLUS) | (ttype == MINUS) | (ttype == MULT) | (ttype == DIV)) { assign->oper = ttype; ttype = getToken(); if(ttype == ID) { printf("ID: %d\n",ttype); /*oper2 = symSearch(token); //printf("oper2: %s\n",oper2->vID); //if(oper2 != NULL) //{ //assign->op2 = oper2; //assign->op2->id = oper1->vID; */ /*ttype = getToken(); printf("SEMICOLON: %d\n",ttype); if(ttype == SEMICOLON) { //ungetToken(); */ assign->op2 = primary(); return assign; /*} else { return NULL; } */ /*} //else //{ // return NULL; //} */ } else { ungetToken(); } } else { return NULL; } //} } }
struct statementNode* stmt() { struct statementNode* stm; struct printStatement* prt; struct varNode* temp; ttype = getToken(); if (ttype == ID) // assign_stmt { stm = make_stmt(ASSIGNSTMT); stm->assignSt = assignment(); //printf("assignSt->op1->vValue: %d\n",stm->assignSt->op1->vValue); stm->stmtType = ASSIGNSTMT; ttype = getToken(); if (ttype == SEMICOLON) { //printf("SEMICOLON: %d\n",ttype); return stm; } else { return NULL; } } else if (ttype == WHILE) // while_stmt { //struct gotoStatment* tempstm; //tempstm = (struct gotoStatement*) malloc(sizeof(struct gotoStatement)); struct statementNode* loop; struct statementNode* noop; struct gotoStatement* gt; stm = make_stmt(WHILESTMT); stm->whileSt = whileStatement(); stm->stmtType = WHILESTMT; //target/goto loop = make_stmt(GOTOSTMT); gt = make_gotoSt(); gt->target = stm; loop->gotoSt = gt; findLast(stm->whileSt->stmt_list)->next = loop; //noop noop = make_stmt(NOOPSTMT); stm->next = noop; findLast(stm->whileSt->stmt_list)->next = stm->next; //false stm->whileSt->condition->falseBranch = stm->next; ungetToken(); if(ttype == RBRACE) { return stm; } } else if (ttype == IF) { stm = make_stmt(IFSTMT); stm->ifSt = ifSt(); stm->stmtType = IFSTMT; //noop stm->next = stm->ifSt->condition->falseBranch; ungetToken(); if(ttype == RBRACE) { return stm; } else { return NULL; } } else if (ttype == PRINT) { //printf("stmt PRINT: %d\n",ttype); stm = make_stmt(PRINTSTMT); ttype = getToken(); //printf("token: %s\n",token); temp = symSearch(token); stm->stmtType = PRINTSTMT; if(temp != NULL) { prt = make_printSt(temp); stm->printSt = prt; ttype = getToken(); //printf ("SEMICOLON 22: %d \n", ttype); if(ttype == SEMICOLON) { return stm; } else { return NULL; } } else { return NULL; } } else { return NULL; } }
/*---------------------------------------------------------------------*//** トークンが一致するかどうか判定する (一致した場合はポインタを進め、一致しなかった場合は戻す) ⇒ js_MatchToken **//*---------------------------------------------------------------------*/ bool EsTokenParser::matchToken(EsTokenType tt) { if(tt == nextToken()) { return true; } ungetToken(); return false; }
struct conditionNode* condition() { struct conditionNode* cNode; struct varNode* op1; struct varNode* op2; struct statementNode* tBranch; struct statementNode* fBranch; int op; cNode = make_condition(); ttype = getToken(); if ((ttype == ID)|(ttype == NUM)) { ungetToken(); //ungetToken since it still be parsed cNode->op1 = primary(); //left operand of a condition is a primary ttype = getToken(); if ((ttype == GREATER)|(ttype == GTEQ)|(ttype == LESS) |(ttype == NOTEQUAL)|(ttype == LTEQ)) { cNode->operator = ttype; //relop is set to >, <, etc. ttype = getToken(); if ((ttype == ID)|(ttype == NUM)) { ungetToken(); //ungetToken since it still be parsed cNode->op2 = primary(); //right operand of a condition is a primary ttype = getToken(); if(ttype == RPAREN) { ttype = getToken(); if(ttype == THEN) { cNode->trueBranch = stmt_list(); return cNode; } else { return NULL; } } else { return NULL; } } else { return NULL; } } else { return NULL; } } else { return NULL; } }