Stmt *ParseIfStmt(int (*ParseDetails)(Stmt **stmt)) { Stmt *stmt; IfData *id; if((stmt = NewStmt()) != NULL) { if((id = (IfData *)calloc(1, sizeof(IfData))) != NULL) { stmt->procs = &if_stmt_procs; stmt->data = (void *)id; if((id->expr = ExprParse()) != NULL) { id->block = ParseBlock("if", ParseDetails); if(GetToken() == TK_ELSE) { id->elseblock = ParseBlock("else", ParseDetails); } else { UngetToken(); id->elseblock = NULL; } return stmt; } } else LogMemError("if"); } DeleteStmt(stmt); return NULL; }
sptr<Node> Parser::ParseStatement() { if (currToken == nullptr) { return sptr<EmptyNode>(new EmptyNode()); } sptr<Node> root = nullptr; Types t = currToken->type; switch (t) { case IDENT: root = ParseIdent(); if (Match(POINTER, DOT, OPENBRACSQ, ASSIGN, -1)) { return ParseAssign(dynamic_pointer_cast<VarNode>(root)); } else { return ParseFuncCall(root); } case BEGIN: return ParseBlock(); case IF: return ParseConditional(); case WITH: return ParseWith(); case WHILE: return ParseWhileLoop(); case REPEAT: return ParseRepeatUntil(); case FOR : return ParseForLoop(); case CASE: return ParseSwitchCase(); default: return sptr<EmptyNode>(new EmptyNode()); } }
QString OrganiseFormat::ParseBlock(QString block, const Song& song, bool* any_empty) const { QRegExp tag_regexp(kTagPattern); QRegExp block_regexp(kBlockPattern); // Find any blocks first int pos = 0; while ((pos = block_regexp.indexIn(block, pos)) != -1) { // Recursively parse the block bool empty = false; QString value = ParseBlock(block_regexp.cap(1), song, &empty); if (empty) value = ""; // Replace the block's value block.replace(pos, block_regexp.matchedLength(), value); pos += value.length(); } // Now look for tags bool empty = false; pos = 0; while ((pos = tag_regexp.indexIn(block, pos)) != -1) { QString value = TagValue(tag_regexp.cap(1), song); if (value.isEmpty()) empty = true; block.replace(pos, tag_regexp.matchedLength(), value); pos += value.length(); } if (any_empty) *any_empty = empty; return block; }
QString OrganiseFormat::GetFilenameForSong(const Song &song) const { QString filename = ParseBlock(format_, song); if (replace_spaces_) filename.replace(QRegExp("\\s"), "_"); if (replace_non_ascii_) { QString stripped; for (int i=0 ; i<filename.length() ; ++i) { const QCharRef c = filename[i]; if (c < 128) stripped.append(c); else { const QString decomposition = c.decomposition(); if (!decomposition.isEmpty() && decomposition[0] < 128) stripped.append(decomposition[0]); else stripped.append("_"); } } filename = stripped; } return filename; }
SymProc* Parser::ParseProcDecl(string name, vector<string>* argNames, SymTable* argTable, bool isFunc, SymType* Type) { SymTable* locTab = new SymTable; TableStack.PushTable(locTab); table = TableStack.GetTopTable(); SymProc* proc = NULL; if (isFunc) { argTable->insert_vo(pair<string, Symbol*>("result", new SymVarParam("result", Type))); proc = new SymFunc(name, argNames, argTable, NULL, false, Type); } else proc = new SymProc(name, argNames, argTable, NULL, false); proc->print(os, false); if (mainTable->find(name) != mainTable->end()) mainTable->delete_element(name); mainTable->insert(pair<string, SymProc*> (name, proc)); ParseDecl(); locTab->MakeLocals(); proc->SetBody(ParseBlock()); proc->SetLocTab(locTab); TableStack.PopTable(); TableStack.PopTable(); table = TableStack.GetTopTable(); return proc; }
sptr<Node> Parser::ParseBodyBlock() { ParseConstDecl(); ParseTypeDecl(); ParseVarDecl(); return ParseBlock(); }
NodeStatement* Parser::ParseCode() { NodeStatement* ret = NULL; ret = ParseBlock(); if (t.GetValue() != ".") throw Error("\".\" expected", t); return ret; }
IfStatement *Parser :: ParseIf(){ errorIf(symStack->size() < 2, "Can not use \"if\" at the global field", scan.Get()); errorIf(!isEq(scan.GetNext(), _SEPARATION, "("), "Opening bracket expected", scan.Get()); scan.Next(); ExprNode *condition = ParseExpr(); errorIf(!isEq(scan.Get(), _SEPARATION, ")"), "Closing bracket expected", scan.Get()); scan.Next(); Block *if_branch = ParseBlock(); Block *else_branch = 0; scan.Next(); if(scan.Get()->Value == "else"){ scan.Next(); else_branch = ParseBlock(); scan.Next(); } return new IfStatement(condition, if_branch, else_branch); }
sptr<Node> Parser::ParseRepeatUntil() { sptr<StmntNode> root(new StmntNode(currToken)); NextToken(); root->PushChild(ParseBlock(0)); Expect(UNTIL, -1); root->PushChild(ParseExp()); return root; }
void CfgParser::ParseBlock(const char *&p,TreeFileRef &tree) { string name, value; int index; while(1) { SkipWhitesNL(p); if(*p=='\0' || *p=='}') break; if(!ReadName(p,name,index)) { SkipError(p); continue; } if(*p=='{') { p++; ParseBlock(p,tree.SerChild(name.c_str(),index)); } else { if(!ReadValue(p,value)) SkipError(p); else { map<string,string>::iterator f = defines.find(value); if(f!=defines.end()) value = f->second; if(name.c_str()[0]=='@') defines[name.c_str()+1] = value; else if(name.c_str()[0]=='$') { if(name == "$include") { CfgParser included; string path = base_dir + value; included.auto_index = auto_index; included.defines = defines; included.Load(path.c_str(),tree,*filesystem); defines = included.defines; auto_index = included.auto_index; } } else { tree.SerString(name.c_str(),value,"",index); } } } } if(*p=='}') p++; }
ParsingResult Parser::ParseFuncDecl(TokIterator& it) { if(it->value_ != "def") { return NOT_MATCHED; } FuncCreator func_creator; ParsingResult func_res = ParseFuncDeclHeader(func_creator, ++it); if(func_res != CORRECT) { return INCORRECT; } InstructionBlock body; if(!ParseBlock(body, it)) { return INCORRECT; } func_creator.CreateWithBody(body); return CORRECT; }
int main( int argc, char *argv[] ) { //BOOL bUseStartup, bGotCmd; BOOL bGotCmd; BLOCK bCmd; //char c; RESULTt rResult; setbuf(stdout,NULL); strcpy( GsProgramName, argv[0] ); BasicsInitialize(); GbGraphicalEnvironment = FALSE; ParseArguments( argc, argv ); ParseInit( &rResult ); bGotCmd = FALSE; bCmd = bBlockCreate(); while ( rResult.iCommand != CQUIT ) { char *line=NULL; char *cp; line = tl_getline("> "); cp = stripwhite (line); if (*cp){ gl_histadd(cp); for(; *cp; cp++) (void) bBlockAddChar( bCmd, *cp ); if ( bBlockAddChar( bCmd, '\n' ) ) { ParseBlock( bCmd, &rResult ); BlockEmpty( bCmd ); } } } while ( rResult.iCommand != CQUIT ); ParseShutdown(); LISTUNFREEDMEMORYTOLOGFILE(); exit(0); }
WhileStatement* Parser :: ParseWhile(){ errorIf(symStack->size() < 2, "Can not use \"while\" at the global field", scan.Get()); errorIf(!isEq(scan.GetNext(), _SEPARATION, "("), "Opening bracket expected", scan.Get()); scan.Next(); ExprNode *condition = ParseExpr(); errorIf(!isEq(scan.Get(), _SEPARATION, ")"), "Closing bracket expected", scan.Get()); scan.Next(); Block *body = ParseBlock(); scan.Next(); // isCanUseBreak = false; return new WhileStatement(condition, body); }
// expression // ::= primary binoprhs // ::= primary binoprhs '(' arguments ')' // ::= block ExprAST *Parser::ParseExpression() { if (Lex.tokStr == "{") { return ParseBlock(); } else if (Lex.tok == tok_return) { Lex.gettok(); if (Lex.tokStr == "}" || Lex.tokStr == ";") { return new ReturnAST(Lex.tag(), 0); } else { ExprAST *v = ParseExpression(); return new ReturnAST(Lex.tag(), v); } } else { ExprAST *LHS = ParseBinOpLHS(); return ParseBinOpRHS(0, LHS); } }
void File::ParseDefs(InputStream& s, Reference* pParentRef) { while(s.SkipWhiteSpace(L";") != '}' && s.PeekChar() != Stream::EOS) { NodePriority priority = PNormal; CAtlList<CStringW> types; CStringW name; int c = s.SkipWhiteSpace(); if(c == '*') {s.GetChar(); priority = PLow;} else if(c == '!') {s.GetChar(); priority = PHigh;} ParseTypes(s, types); if(s.SkipWhiteSpace() == '#') { s.GetChar(); ParseName(s, name); } if(types.IsEmpty()) { if(name.IsEmpty()) s.ThrowError(_T("syntax error")); types.AddTail(L"?"); } Reference* pRef = pParentRef; while(types.GetCount() > 1) pRef = CreateRef(CreateDef(pRef, types.RemoveHead())); Definition* pDef = NULL; if(!types.IsEmpty()) pDef = CreateDef(pRef, types.RemoveHead(), name, priority); c = s.SkipWhiteSpace(L":="); if(c == '"' || c == '\'') ParseQuotedString(s, pDef); else if(iswdigit(c) || c == '+' || c == '-') ParseNumber(s, pDef); else if(pDef->IsType(L"@")) ParseBlock(s, pDef); else ParseRefs(s, pDef); } s.GetChar(); }
static void ParseINIFILE () { int token, i, found; for (;;) { SkipWhiteSpace (TRUE); token = GetNextToken (); if (token == TknDONE) return; if (token != TknOPENBLOCK) ShowParserError (); SkipWhiteSpace (FALSE); token = GetNextToken (); found = FALSE; for (i = 0; i < AMOFHEADERS; i++) if (token == Headers[i].header) { found = TRUE; break; } if (!found) ShowParserError (); SkipWhiteSpace (FALSE); token = GetNextToken (); if (token != TknCLOSEBLOCK) ShowParserError (); SkipWhiteSpace (FALSE); if (token == TknDONE) break; if (GetNextToken () != TknRETURN) ShowParserError (); ParseBlock (Headers[i].lvalues, Headers[i].amount); } }
QString OrganiseFormat::GetFilenameForSong(const Song& song) const { QString filename = ParseBlock(format_, song); if (QFileInfo(filename).completeBaseName().isEmpty()) { // Avoid having empty filenames, or filenames with extension only: in this // case, keep the original filename. // We remove the extension from "filename" if it exists, as // song.basefilename() // also contains the extension. filename = Utilities::PathWithoutFilenameExtension(filename) + song.basefilename(); } if (replace_spaces_) filename.replace(QRegExp("\\s"), "_"); if (replace_non_ascii_) { QString stripped; for (int i = 0; i < filename.length(); ++i) { const QCharRef c = filename[i]; if (c < 128) { stripped.append(c); } else { const QString decomposition = c.decomposition(); if (!decomposition.isEmpty() && decomposition[0] < 128) stripped.append(decomposition[0]); else stripped.append("_"); } } filename = stripped; } // Fix any parts of the path that start with dots. QStringList parts = filename.split("/"); for (int i = 0; i < parts.count(); ++i) { QString* part = &parts[i]; for (int j = 0; j < kInvalidPrefixCharactersCount; ++j) { if (part->startsWith(kInvalidPrefixCharacters[j])) { part->replace(0, 1, '_'); break; } } } return parts.join("/"); }
// Sybase ADS WHILE FETCH cur DO loop bool SqlParser::ParseSybaseWhileFetchStatement(Token *while_, Token *fetch, int scope) { // Curson name (it must be already declared) Token *cursor = GetNextIdentToken(); if(cursor == NULL) return false; // DO keyword starts the block Token *do_ = TOKEN_GETNEXTW("DO"); if(_target == SQL_SQL_SERVER) { TOKEN_CHANGE(do_, "BEGIN"); // FETCH the first row PREPEND(while_, "FETCH "); PrependCopy(while_, cursor); PREPEND(while_, " INTO;\n"); TOKEN_CHANGE(fetch, "@@FETCH_STATUS=0"); } ParseBlock(SQL_BLOCK_WHILE, true, scope, NULL); Token *end = TOKEN_GETNEXTW("END"); Token *end_while = (end != NULL) ? TOKEN_GETNEXTW("WHILE") : NULL; if(end != NULL) { if(_target == SQL_SQL_SERVER) { // Fetch the next row at the end of loop PREPEND(end, "FETCH "); PrependCopy(end, cursor); PREPEND(end, " INTO;\n"); Token::Remove(cursor); Token::Remove(end_while); } } return true; }
AST* ParseFunctionDefinition(ParserState* parser) { Match(parser, TOKEN_FUNCTION); Value* name = NULL; if(parser->currentToken.type == TOKEN_ID) { name = Match(parser, TOKEN_ID); } AST* function = CreateASTNode(SEM_FUNCTION, name); Match(parser, TOKEN_LEFTBRACKET); AST* arglist = ParseArgumentList(parser); Match(parser, TOKEN_RIGHTBRACKET); AST* code = ParseBlock(parser); AddASTChild(function, arglist); AddASTChild(function, code); return function; }
NodeStatement* Parser::ParseElement() { if (t.GetValue() == "begin") return ParseBlock(); if (t.GetValue() == "if") return ParseIf(); if (t.GetValue() == "while") return ParseWhile(); if (t.GetValue() == "repeat") return ParseRepeat(); if (t.GetValue() == "for") return ParseFor(); if (t.GetValue() == "write") return ParseWrite(true, false); if (t.GetValue() == "writeln") return ParseWrite(true, true); if (t.GetValue() == "exit") { t = sc.GetNextToken(); return new StatementExit(true); } if (t.GetType() == identifier) { bool found = false; _Table::iterator it = TableStack.Find(t.GetValue(), found); if (found) { if (it->second->IsProc() || it->second->IsFunc()) { t = sc.GetNextToken(); return ParseSub((SymProc*)it->second); } } return ParseAssignment(); } if (t.GetValue() == "(") { return ParseAssignment(); } throw Error("Statement error", t); }
ForStatement* Parser :: ParseFor(){ errorIf(symStack->size() < 2, "Can not use \"for\" at the global field", scan.Get()); ExprNode *first = 0, *second = 0, *third = 0; errorIf((!isEq(scan.GetNext(), _SEPARATION, "(")), "Opening bracket expected", scan.Get()); scan.Next(); first = symStack->find_type(scan.Get()->Value) ? ParseDeclaration() :ParseExpr(); //errorIf(!isEq(scan.Get(), _SEPARATION, ";"), "Semicolon expected", scan.Get()); scan.Next(); second = ParseExpr(); errorIf(!isEq(scan.Get(), _SEPARATION, ";"), "Semicolon expected", scan.Get()); scan.Next(); if(!isEq(scan.Get(), _SEPARATION, ")")) third = ParseExpr(); errorIf(!isEq(scan.Get(), _SEPARATION, ")"), "Closing bracket expected", scan.Get()); scan.Next(); Block *body = ParseBlock(); scan.Next(); // isCanUseBreak = false; return new ForStatement(first, second, third, body); }
DefAST *Parser::ParseFuncDefinition() { FTag tag = Lex.tag(); // definitions usually span several lines, so save tag for now. Lex.gettok(); // eat 'func' if (Lex.tok != tok_identifier) Lex.tag().Throw("Expected identifier after 'func'."); std::string name = Lex.tokStr; Lex.gettok(); // eat function name if (Lex.tokStr != ":") Lex.tag().Throw("Expected ':' in function definition."); Lex.gettok(); FuncTypeAST *type = ParsePrototype(); if (type == 0) return 0; if (Lex.tok == tok_extern) { ExternAST *v = dynamic_cast<ExternAST*>(ParseExtern()); return new ExternFuncDefAST(tag, name, v, type); } else { BlockAST *b = dynamic_cast<BlockAST*>(ParseBlock()); if (b == 0) return 0; return new FuncDefAST(tag, name, new FuncExprAST(tag, type, b)); } }
bool CfgParser::Load(const char *path,TreeFileRef &f,FileSystem &fs) { filesystem = &fs; { const char *p = path; while(*p) p++; while(p>path && *p!='/' && *p!='\\') p--; if(*p=='/' || *p=='\\') p++; base_dir.assign(path,p-path); } vector<unsigned char> data; if(!filesystem->GetFileBytes(path,data)) return false; const char *p = (char*)&data[0]; ParseBlock(p,f); return true; }
AST* ParseOperator(ParserState* parser) { AST* ast; switch(parser->currentToken.type) { case TOKEN_BEGIN: return ParseBlock(parser); case TOKEN_ID: ast = parser->nextToken.type == TOKEN_LEFTBRACKET ? ParseFunctionCall(parser) : ParseAssignment(parser); Match(parser, TOKEN_SEMICOLON); return ast; case TOKEN_LOCAL: ast = ParseAssignment(parser); Match(parser, TOKEN_SEMICOLON); return ast; case TOKEN_WHILE: return ParseWhileCycle(parser); case TOKEN_IF: return ParseIfStatement(parser); case TOKEN_FUNCTION: return ParseFunctionDefinition(parser); case TOKEN_RETURN: ast = ParseReturn(parser); Match(parser, TOKEN_SEMICOLON); return ast; case TOKEN_PRINT: ast = ParsePrint(parser); Match(parser, TOKEN_SEMICOLON); return ast; case TOKEN_INCLUDE: return ParseInclude(parser); case TOKEN_LOAD: ast = ParseLoad(parser); Match(parser, TOKEN_SEMICOLON); return ast; /** TODO: Factor common parts out of switch */ } FailWithUnexpectedToken(parser, parser->currentToken.type, TOKEN_ID); return NULL; }
ParsingResult Parser::ParseControlFlowInstr(InstructionBlock& body, TokIterator& it) { if(it->value_ != "if" && it->value_ != "while") { return NOT_MATCHED; } std::string instruction_type = it->value_; ArithmExpr left_expr; ParsingResult expr_res = ParseExpr(left_expr, ++it); if(expr_res == INCORRECT || expr_res == NOT_MATCHED) { return INCORRECT; } if(it->type_ != COMPARISON_OP) { return INCORRECT; } std::string comp_char = it->value_; ArithmExpr right_expr; expr_res = ParseExpr(right_expr, ++it); InstructionBlock cf_instr_body; if(expr_res == INCORRECT || expr_res == NOT_MATCHED || !ParseBlock(cf_instr_body, it)) { return INCORRECT; } Condition cond(left_expr, right_expr, comp_char); if(instruction_type == "while") { WhileInstr while_instr(cond, cf_instr_body); body.AddInstruction(PtrVisitable(new WhileInstr(while_instr))); } else { IfInstr if_instr(cond, cf_instr_body); body.AddInstruction(PtrVisitable(new IfInstr(if_instr))); } return CORRECT; }
void ParseStatement() { sInt elsemod; if(CheckType()) { NewLine(); ParseDecl(); return; } switch(Token) { case TOK_PRE: Out("\n"); Match(); break; case TOK_WHILE: NewLine(); Match(); Match(TOK_OPEN); ParseAssignExpr(); Match(TOK_CLOSE); ParseCondBlock(); //ParseStatement(); break; case TOK_SWITCH: NewLine(); Match(); Match(TOK_OPEN); ParseAssignExpr(); Match(TOK_CLOSE); ParseSwitchBlock(); break; /* case TOK_CASE: NewLine(-1); Match(); Out(" "); if(Token==TOK_VALUE) { Match(); Match(TOK_COLON); } else if(Token==TOK_LABEL) { Match(); } else { Error("case label"); } break; */ case TOK_BREAK: NewLine(); Match(); Match(TOK_SEMI); break; case TOK_RETURN: NewLine(); Match(); Out(" "); if(Token!=TOK_SEMI) ParseAssignExpr(); Match(TOK_SEMI); break; case TOK_IF: NewLine(); Match(TOK_IF); Match(TOK_OPEN); ParseAssignExpr(); Match(TOK_CLOSE); ParseCondBlock(&elsemod,sFALSE); if(Token==TOK_ELSE) { NewLine(); Match(TOK_ELSE); ParseCondBlock(&elsemod,sTRUE); } else { if(Mode == 1) { NewLine(); OutF("else"); OutBOpen(); NewLine(); OutF("sLekktor_%s.Set(%d);",LekktorName,elsemod); OutBClose(); } } break; case TOK_ASM: NewLine(); Match(TOK_ASM); InlineAssembly(); if(Token==TOK_SEMI) Match(); break; case TOK_FOR: NewLine(); Match(TOK_FOR); Match(TOK_OPEN); if(Token!=TOK_SEMI) { if(CheckType()) { ParseDecl(); } else { ParseAssignExpr(); Match(TOK_SEMI); } } else Match(); if(Token!=TOK_SEMI) ParseAssignExpr(); Match(TOK_SEMI); if(Token!=TOK_CLOSE) ParseAssignExpr(); Match(TOK_CLOSE); ParseCondBlock(); break; case TOK_DO: NewLine(); Match(TOK_DO); ParseCondBlock(); NewLine(); Match(TOK_WHILE); Match(TOK_OPEN); ParseAssignExpr(); Match(TOK_CLOSE); Match(TOK_SEMI); break; case TOK_BOPEN: ParseBlock(); break; case TOK_DELETEA: case TOK_DELETE: NewLine(); Match(); Out(" "); ParseExpr(); Match(TOK_SEMI); break; case TOK_GOTO: NewLine(); Match(TOK_GOTO); Out(" "); Match(TOK_NAME); Match(TOK_SEMI); break; case TOK_SEMI: NewLine(); Match(); break; case TOK_TYPEDEF: NewLine(); Match(); Out(" "); intypedef = sTRUE; gottype = sFALSE; ParseFunctionPtrType(); intypedef = sFALSE; Out(" "); if(Token == TOK_NAME) { AddType(Value); Match(); } else if(!gottype) Error("typedef error"); Match(TOK_SEMI); break; case TOK_NAMESPACE: NewLine(); Match(); Out(" "); if(Token==TOK_NAME) // name may be omitted Match(TOK_NAME); ParseBlock(); break; case TOK_USING: NewLine(); Match(); Out(" "); if(Token==TOK_NAMESPACE) { Match(); Out(" "); } ParseScopedName(); Match(TOK_SEMI); break; case TOK_VCTRY: NewLine(); Match(); ParseStatement(); if(Token == TOK_VCEXCEPT) { NewLine(); Match(); Match(TOK_OPEN); ParseExpr(); Match(TOK_CLOSE); ParseStatement(); } break; case TOK_NAME: if(Peek() == TOK_COLON) { NewLine(); Match(); Match(); break; } // fall-through /*case TOK_LABEL: NewLine(); Match(); break;*/ default: NewLine(); ParseAssignExpr(); Match(TOK_SEMI); break; } }
void ParseType1(sInt withname) { while(Token==TOK_STATIC||Token==TOK_EXTERN||Token==TOK_AUTO||Token==TOK_REGISTER) { if(Token!=TOK_EXTERN) { Match(); Out(" "); } else { Match(); Out(" "); if(Token==TOK_VALUE) { Match(); Out(" "); if(Token==TOK_BOPEN) ParseBlock(); } } } if(Token==TOK_CONST||Token==TOK_VOLATILE) { Match(); Out(" "); } if(Token==TOK_STRUCT||Token==TOK_CLASS||Token==TOK_UNION) { Match(); Out(" "); if(Token==TOK_NAME) { AddType(Value); Match(TOK_NAME); } else { Match(TOK_TYPE); } if(Token==TOK_COLON) { Match(); if(Token==TOK_PROTECTED||Token==TOK_PRIVATE||Token==TOK_PUBLIC) { Match(); Out(" "); } /*else Match(TOK_PUBLIC); // provoke error*/ Match(TOK_TYPE); } if(Token==TOK_BOPEN) { MatchBOpen(); while(Token!=TOK_BCLOSE) { switch(Token) { case TOK_PROTECTED: case TOK_PRIVATE: case TOK_PUBLIC: Out("\n"); Match(); Match(TOK_COLON); break; case TOK_PRE: Out("\n"); Match(); break; default: NewLine(); ParseDecl(); break; } } MatchBClose(); } } else if(Token==TOK_ENUM) { Match(); Out(" "); if(Token==TOK_NAME) { AddType(Value); Match(TOK_NAME); } else { Match(TOK_TYPE); } if(Token==TOK_BOPEN) { MatchBOpen(); ParseInitialiser(); while(Token==TOK_COMMA) { Match(TOK_COMMA); ParseInitialiser(); } MatchBClose(); } } else { sInt gotspec=0; while(Token==TOK_LONG || Token==TOK_SHORT || Token==TOK_SIGNED || Token==TOK_UNSIGNED) { Match(); Out(" "); gotspec=1; } if(Token==TOK_INT||Token==TOK_FLOAT||Token==TOK_CHAR||Token==TOK_FLOAT||Token==TOK_DOUBLE||Token==TOK_TYPE) { Match(); } else if(!gotspec) Error("type error"); } if(withname) Out(" "); while(Token==TOK_MUL) Match(); if(Token==TOK_AND) Match(); if(withname==1) { ParseVarDecl(); } while(Token==TOK_SOPEN) { Match(); if(Token!=TOK_SCLOSE) ParseExpr(); Match(TOK_SCLOSE); } if(withname==2 && Token==TOK_OPEN) { Match(); ParseVarDecl(); Match(TOK_CLOSE); Match(TOK_OPEN); ParseParamList(); Match(TOK_CLOSE); } }
void CTextTraceFile::LoadThread() { HRESULT hr = S_OK; DWORD cbRead; DWORD cbToRead; LARGE_INTEGER liPos; m_pCallback->OnLoadBegin(); for (;; ) { LoadBlock * pNew = nullptr; if (m_bReverse) { ATLASSERT(false); } else { DWORD cbRollover = 0; if (m_Blocks.size() > 0) { LoadBlock * pEnd = m_Blocks.back(); if (pEnd->nFileStop > m_nStop) { return; } // copy end of line from previous buffer // we have to copy page aligned block and record the start of next data assert(pEnd->cbBuf >= pEnd->cbLastFullLineEnd); cbRollover = pEnd->cbBuf - pEnd->cbLastFullLineEnd; DWORD cbRolloverRounded = (cbRollover + m_PageSize - 1) & (~(m_PageSize - 1)); IFC(AllocBlock(cbRolloverRounded + m_BlockSize, &pNew)); pNew->cbFirstFullLineStart = cbRolloverRounded - cbRollover; memcpy(pNew->pbBuf + pNew->cbFirstFullLineStart, pEnd->pbBuf + pEnd->cbLastFullLineEnd, cbRollover); // at this point we can decommit unnecessary pages for unicode // this will waste address space but keep memory usage low // nFileStart is in file offset // cbLastFullLineEnd is in buffer pNew->nFileStart = pEnd->nFileStop; pNew->cbWriteStart = cbRolloverRounded; // if we are in unicode mode, trim previous block if (m_bUnicode) TrimBlock(pEnd); } else { IFC(AllocBlock(m_BlockSize, &pNew)); // we are going forward so start pos is null pNew->cbWriteStart = 0; } pNew->nFileStop = pNew->nFileStart + m_BlockSize; // we actually have data in the buffer, so set cbData pNew->cbData = cbRollover; } liPos.QuadPart = (__int64) pNew->nFileStart; SetFilePointerEx(m_hFile, liPos, NULL, FILE_BEGIN); cbToRead = m_BlockSize; if (m_bReverse) { ATLASSERT(false); } else { // append data after rollover string if (!ReadFile(m_hFile, pNew->pbBuf + pNew->cbWriteStart, cbToRead, &cbRead, NULL)) { hr = HRESULT_FROM_WIN32(GetLastError()); goto Cleanup; } } pNew->cbData = cbRead + pNew->cbData; // parse data IFC(ParseBlock(pNew, pNew->cbFirstFullLineStart, pNew->cbData, &pNew->cbDataEnd, &pNew->cbLastFullLineEnd)); { LockGuard guard(m_Lock); // append block m_Blocks.push_back(pNew); } m_pCallback->OnLoadBlock(); if (cbRead != m_BlockSize) { break; } } Cleanup: m_pCallback->OnLoadEnd(hr); }
/* parse a statement */ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemicolon) { struct Value *CValue; struct Value *LexerValue; struct Value *VarValue; int Condition; struct ParseState PreState; enum LexToken Token; /* if we're debugging, check for a breakpoint */ if (Parser->DebugMode && Parser->Mode == RunModeRun) DebugCheckStatement(Parser); /* take note of where we are and then grab a token to see what statement we have */ ParserCopy(&PreState, Parser); Token = LexGetToken(Parser, &LexerValue, TRUE); switch (Token) { case TokenEOF: return ParseResultEOF; case TokenIdentifier: /* might be a typedef-typed variable declaration or it might be an expression */ if (VariableDefined(Parser->pc, LexerValue->Val->Identifier)) { VariableGet(Parser->pc, Parser, LexerValue->Val->Identifier, &VarValue); if (VarValue->Typ->Base == Type_Type) { *Parser = PreState; ParseDeclaration(Parser, Token); break; } } else { /* it might be a goto label */ enum LexToken NextToken = LexGetToken(Parser, NULL, FALSE); if (NextToken == TokenColon) { /* declare the identifier as a goto label */ LexGetToken(Parser, NULL, TRUE); if (Parser->Mode == RunModeGoto && LexerValue->Val->Identifier == Parser->SearchGotoLabel) Parser->Mode = RunModeRun; CheckTrailingSemicolon = FALSE; break; } #ifdef FEATURE_AUTO_DECLARE_VARIABLES else /* new_identifier = something */ { /* try to guess type and declare the variable based on assigned value */ if (NextToken == TokenAssign && !VariableDefinedAndOutOfScope(Parser->pc, LexerValue->Val->Identifier)) { if (Parser->Mode == RunModeRun) { struct Value *CValue; char* Identifier = LexerValue->Val->Identifier; LexGetToken(Parser, NULL, TRUE); if (!ExpressionParse(Parser, &CValue)) { ProgramFail(Parser, "expected: expression"); } #if 0 PRINT_SOURCE_POS; PlatformPrintf(Parser->pc->CStdOut, "%t %s = %d;\n", CValue->Typ, Identifier, CValue->Val->Integer); printf("%d\n", VariableDefined(Parser->pc, Identifier)); #endif VariableDefine(Parser->pc, Parser, Identifier, CValue, CValue->Typ, TRUE); break; } } } #endif } /* else fallthrough to expression */ /* no break */ case TokenAsterisk: case TokenAmpersand: case TokenIncrement: case TokenDecrement: case TokenOpenBracket: *Parser = PreState; ExpressionParse(Parser, &CValue); if (Parser->Mode == RunModeRun) VariableStackPop(Parser, CValue); break; case TokenLeftBrace: ParseBlock(Parser, FALSE, TRUE); CheckTrailingSemicolon = FALSE; break; case TokenIf: if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) ProgramFail(Parser, "'(' expected"); Condition = ExpressionParseInt(Parser) != 0; if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) ProgramFail(Parser, "')' expected"); if (ParseStatementMaybeRun(Parser, Condition, TRUE) != ParseResultOk) ProgramFail(Parser, "statement expected"); if (LexGetToken(Parser, NULL, FALSE) == TokenElse) { LexGetToken(Parser, NULL, TRUE); if (ParseStatementMaybeRun(Parser, !Condition, TRUE) != ParseResultOk) ProgramFail(Parser, "statement expected"); } CheckTrailingSemicolon = FALSE; break; case TokenWhile: { struct ParseState PreConditional; enum RunMode PreMode = Parser->Mode; if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) ProgramFail(Parser, "'(' expected"); ParserCopyPos(&PreConditional, Parser); do { ParserCopyPos(Parser, &PreConditional); Condition = ExpressionParseInt(Parser) != 0; if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) ProgramFail(Parser, "')' expected"); if (ParseStatementMaybeRun(Parser, Condition, TRUE) != ParseResultOk) ProgramFail(Parser, "statement expected"); if (Parser->Mode == RunModeContinue) Parser->Mode = PreMode; } while (Parser->Mode == RunModeRun && Condition); if (Parser->Mode == RunModeBreak) Parser->Mode = PreMode; CheckTrailingSemicolon = FALSE; } break; case TokenDo: { struct ParseState PreStatement; enum RunMode PreMode = Parser->Mode; ParserCopyPos(&PreStatement, Parser); do { ParserCopyPos(Parser, &PreStatement); if (ParseStatement(Parser, TRUE) != ParseResultOk) ProgramFail(Parser, "statement expected"); if (Parser->Mode == RunModeContinue) Parser->Mode = PreMode; if (LexGetToken(Parser, NULL, TRUE) != TokenWhile) ProgramFail(Parser, "'while' expected"); if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) ProgramFail(Parser, "'(' expected"); Condition = ExpressionParseInt(Parser) != 0; if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) ProgramFail(Parser, "')' expected"); } while (Condition && Parser->Mode == RunModeRun); if (Parser->Mode == RunModeBreak) Parser->Mode = PreMode; } break; case TokenFor: ParseFor(Parser); CheckTrailingSemicolon = FALSE; break; case TokenSemicolon: CheckTrailingSemicolon = FALSE; break; case TokenIntType: case TokenShortType: case TokenCharType: case TokenLongType: case TokenFloatType: case TokenDoubleType: case TokenVoidType: case TokenStructType: case TokenUnionType: case TokenEnumType: case TokenSignedType: case TokenUnsignedType: case TokenStaticType: case TokenAutoType: case TokenRegisterType: case TokenExternType: *Parser = PreState; CheckTrailingSemicolon = ParseDeclaration(Parser, Token); break; case TokenHashDefine: ParseMacroDefinition(Parser); CheckTrailingSemicolon = FALSE; break; #ifndef NO_HASH_INCLUDE case TokenHashInclude: if (LexGetToken(Parser, &LexerValue, TRUE) != TokenStringConstant) ProgramFail(Parser, "\"filename.h\" expected"); IncludeFile(Parser->pc, (char *)LexerValue->Val->Pointer); CheckTrailingSemicolon = FALSE; break; #endif case TokenSwitch: if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) ProgramFail(Parser, "'(' expected"); Condition = (int) ExpressionParseInt(Parser); if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) ProgramFail(Parser, "')' expected"); if (LexGetToken(Parser, NULL, FALSE) != TokenLeftBrace) ProgramFail(Parser, "'{' expected"); { /* new block so we can store parser state */ enum RunMode OldMode = Parser->Mode; int64_t OldSearchLabel = Parser->SearchLabel; Parser->Mode = RunModeCaseSearch; Parser->SearchLabel = Condition; ParseBlock(Parser, TRUE, (OldMode != RunModeSkip) && (OldMode != RunModeReturn)); if (Parser->Mode != RunModeReturn) Parser->Mode = OldMode; Parser->SearchLabel = OldSearchLabel; } CheckTrailingSemicolon = FALSE; break; case TokenCase: if (Parser->Mode == RunModeCaseSearch) { Parser->Mode = RunModeRun; Condition = (int) ExpressionParseInt(Parser); Parser->Mode = RunModeCaseSearch; } else Condition = (int) ExpressionParseInt(Parser); if (LexGetToken(Parser, NULL, TRUE) != TokenColon) ProgramFail(Parser, "':' expected"); if (Parser->Mode == RunModeCaseSearch && Condition == Parser->SearchLabel) Parser->Mode = RunModeRun; CheckTrailingSemicolon = FALSE; break; case TokenDefault: if (LexGetToken(Parser, NULL, TRUE) != TokenColon) ProgramFail(Parser, "':' expected"); if (Parser->Mode == RunModeCaseSearch) Parser->Mode = RunModeRun; CheckTrailingSemicolon = FALSE; break; case TokenBreak: if (Parser->Mode == RunModeRun) Parser->Mode = RunModeBreak; break; case TokenContinue: if (Parser->Mode == RunModeRun) Parser->Mode = RunModeContinue; break; case TokenReturn: if (Parser->Mode == RunModeRun) { if (!Parser->pc->TopStackFrame || Parser->pc->TopStackFrame->ReturnValue->Typ->Base != TypeVoid) { if (!ExpressionParse(Parser, &CValue)) ProgramFail(Parser, "value required in return"); if (!Parser->pc->TopStackFrame) /* return from top-level program? */ PlatformExit(Parser->pc, (int)ExpressionCoerceLong(CValue)); else ExpressionAssign(Parser, Parser->pc->TopStackFrame->ReturnValue, CValue, TRUE, NULL, 0, FALSE); VariableStackPop(Parser, CValue); } else { if (ExpressionParse(Parser, &CValue)) ProgramFail(Parser, "value in return from a void function"); } Parser->Mode = RunModeReturn; } else ExpressionParse(Parser, &CValue); break; case TokenTypedef: ParseTypedef(Parser); break; case TokenGoto: if (LexGetToken(Parser, &LexerValue, TRUE) != TokenIdentifier) ProgramFail(Parser, "identifier expected"); if (Parser->Mode == RunModeRun) { /* start scanning for the goto label */ Parser->SearchGotoLabel = LexerValue->Val->Identifier; Parser->Mode = RunModeGoto; } break; case TokenDelete: { /* try it as a function or variable name to delete */ if (LexGetToken(Parser, &LexerValue, TRUE) != TokenIdentifier) ProgramFail(Parser, "identifier expected"); if (Parser->Mode == RunModeRun) { /* delete this variable or function */ CValue = TableDelete(Parser->pc, &Parser->pc->GlobalTable, LexerValue->Val->Identifier); if (CValue == NULL) ProgramFail(Parser, "'%s' is not defined", LexerValue->Val->Identifier); VariableFree(Parser->pc, CValue); } break; } default: *Parser = PreState; return ParseResultError; } if (CheckTrailingSemicolon) { if (LexGetToken(Parser, NULL, TRUE) != TokenSemicolon) ProgramFail(Parser, "';' expected"); } return ParseResultOk; }
AST* ParseProgram(ParserState* parser) { parser->nextToken = GetNextToken(parser->lex); Advance(parser); return ParseBlock(parser); }