//13.<分支语句>—> if <布尔表达式> then <语句> //| if <布尔表达式> then <语句> else <语句> void switchStatement(){ if (lookahead == IF){ match(IF); TFexit tf = booleaexpression();//真假出口 match(THEN); //填真出口 BackPatch(tf.TC, sno); statementlists(); if (lookahead == ELSE){ // 1 无条件跳转 int j = sno; quadruples.push_back(Quadruple(sno++, 0,Val(),Val())); match(ELSE); //回填假出口 BackPatch(tf.FC, sno); statementlists(); //回填 1 无条件跳转 BackPatch(j, sno); } else { // 回填假出口 BackPatch(tf.FC, sno); } } else{ error(24); } }
// This generates some fairly heavy trampolines, but it doesn't really hurt. // Only instructions that access I/O will get these, and there won't be that // many of them in a typical program/game. bool Jitx86Base::HandleFault(uintptr_t access_address, SContext* ctx) { // TODO: do we properly handle off-the-end? const auto base_ptr = reinterpret_cast<uintptr_t>(Memory::physical_base); if (access_address >= base_ptr && access_address < base_ptr + 0x100010000) return BackPatch(static_cast<u32>(access_address - base_ptr), ctx); const auto logical_base_ptr = reinterpret_cast<uintptr_t>(Memory::logical_base); if (access_address >= logical_base_ptr && access_address < logical_base_ptr + 0x100010000) return BackPatch(static_cast<u32>(access_address - logical_base_ptr), ctx); return false; }
//14.<循环语句>—> while <布尔表达式> do <语句> void loopStatement(){ match(WHILE); //int boolId = 序号全局变量 int boolId = sno; TFexit tf = booleaexpression();//真假出口 match(DO); //回填真出口 BackPatch(tf.TC, sno); statementlists(); //(j boolId) quadruples.push_back(Quadruple(sno++, 0, Val(), Val(), boolId)); //回填假出口 BackPatch(tf.FC, sno); }
TParseTables* GenerateParseTables(void) { size_t IP, IPStart; int NNonTerms, NSymbols; int iRule, iTerminal; SymIt NonTerm; TSymbol* Symbol; TParseTables* Tables; SYMBOLS LLNonTerms; int Reduced; int TerminalsEmitted; printf("GenerateParseTables() begins\n"); Tables = NEW(TParseTables); assert(Tables != NULL); Tables->LLNonTerms = LLNonTerms = GetLLNonTerms(); /* get list of only nonterminals we care about */ /* assign integers to any undefined tokens */ DefineTokens(Tables); IP = BLC_HDR_SIZE; /* skip over initial header containing 5 two-byte table sizes */ NNonTerms = SymbolListCount(LLNonTerms); /* generate terminal symbol table */ IPStart = IP; TerminalsEmitted = 0; for(iTerminal=Tables->MinTokenVal; iTerminal <= Tables->MaxTokenVal; ++iTerminal) { Symbol = SymbolFromValue(iTerminal); if(Symbol) { /* store token ID, followed by its null-terminated string */ IP = Store8(Tables, IP, iTerminal); IP = StoreStr(Tables, IP, SymbolStr(Symbol)); ++TerminalsEmitted; } } IP = Store8(Tables, IP, 0); /* sentinel byte */ Store16(Tables, BLC_HDR_TERMSYMTAB_SIZE, IP - IPStart); /* generate nonterminal symbol table */ IPStart = IP; NonTerm = SymItNew(LLNonTerms); while(SymbolIterate(&NonTerm)) { IP = StoreStr(Tables, IP, SymbolStr(NonTerm.Symbol)); } IP = Store8(Tables, IP, 0); /* sentinel byte */ Store16(Tables, BLC_HDR_NONTERMSYMTAB_SIZE, IP - IPStart); /* for each production of <start>, add an entry point */ IPStart = IP; Symbol = SymbolStart(); assert(Symbol != NULL); for(iRule = 0; iRule < RuleCount(Symbol); ++iRule) { /* actual value will have to be backpatched */ MarkPatch(IP, AddRule(Tables, Symbol->Rules[iRule], Symbol)); IP = Store16(Tables, IP, 0); } Store16(Tables, BLC_HDR_ENTRYTABLE_SIZE, IP - IPStart); /* for each nonterminal, generate its SELECT body*/ IPStart = IP; Tables->SelSectOfs = IPStart; NonTerm = SymItNew(LLNonTerms); while(SymbolIterate(&NonTerm)) IP = GenerateSelect(Tables, IP, NonTerm.Symbol); Store16(Tables, BLC_HDR_SELECTTABLE_SIZE, IP - IPStart); Dump("Generate opcodes for each unique rule\n"); /* generate opcodes for each unique rule */ IPStart = IP; Tables->RuleSectOfs = IPStart; for(iRule = 0; iRule < Tables->NRules; ++iRule) { int iProdItem; TRule* Rule = Tables->Rules[iRule]; IntAdd(&Tables->RuleOffsets, IP); Reduced = FALSE; /* have not performed a reduction for this rule yet */ NSymbols = SymbolListCount(Rule->Symbols); fprintf(stdout, "-> "); SymbolListDump(stdout, Rule->Symbols, " "); fprintf(stdout, "\n"); for(iProdItem = 0; iProdItem < NSymbols; ++iProdItem) { TSymbol* Symbol = SymbolListGet(Rule->Symbols, iProdItem); if(SymbolGetBit(Symbol, SYM_TERMINAL)) { IP = Store8(Tables, IP, BLCOP_MATCH); IP = Store8(Tables, IP, Symbol->Value); if(Symbol == SymbolFind(EOFToken)) { IP = Store8(Tables, IP, BLCOP_HALT); Reduced = TRUE; } } else if(SymbolIsAction(Symbol)) { int FinalAction, ArgCount; assert(Rule->RuleId < 255); assert(iProdItem < 255); FinalAction = FALSE; if(iProdItem == NSymbols-1) FinalAction = TRUE; else if(Rule->TailRecursive && iProdItem == NSymbols-2) FinalAction = TRUE; ArgCount = iProdItem; if(Rule->TailRecursive == 2) ++ArgCount; fprintf(stdout, "iProdItem=%d, NSymbols=%d,TailRecursive=%d,FinalAction=%d\n", iProdItem, NSymbols, Rule->TailRecursive, FinalAction); IP = Store8(Tables, IP, FinalAction?BLCOP_ACTRED:BLCOP_ACTION8); IP = Store8(Tables, IP, Symbol->Action->Number); IP = Store8(Tables, IP, ArgCount); Symbol->Action->ArgCount = ArgCount; if(FinalAction) Reduced = TRUE; } else if(SymbolListContains(LLNonTerms, Symbol)) /* non-terminal */ { int iSymbol = SymbolListContains(LLNonTerms, Symbol); if(RuleCount(Symbol) > 1) { if(Symbol->Name.Text[0] == '`') /* if a tail recursive rule... */ { IP = Store8(Tables, IP, BLCOP_TAILSELECT); IP = Store8(Tables, IP, iProdItem); Reduced = TRUE; /* TAILSELECT opcode must do the reducing to shuffle stack correctly */ } else IP = Store8(Tables, IP, BLCOP_LLSELECT); IP = Store16(Tables, IP, Symbol->SelectOffset); } /* else, only 1 rule to choose from, so just transfer control to that rule! */ else { int iRule = AddRule(Tables, Symbol->Rules[0], Symbol); IP = Store8(Tables, IP, BLCOP_CALL); IP = MarkPatch(IP, iRule); } assert(iSymbol>0); /* ???TODO why is this???*/ } else // else, it's an operator trigger { assert(Symbol->LR0 != NULL); fprintf(stderr, "watch out: we don't handle LR(0) yet!\n"); } } if(!Reduced) { IP = Store8(Tables, IP, BLCOP_REDUCE); IP = Store8(Tables, IP, NSymbols); } } Store16(Tables, BLC_HDR_RULEOPCODE_SIZE, IP - IPStart); DumpVerbose("Backpatch opcode addresses.\n"); for(iRule = 0; iRule < Tables->NRules; ++iRule) BackPatch(Tables, iRule, Tables->RuleOffsets.v[iRule] - IPStart); DumpVerbose("Backpatching complete.\n"); assert(IP < (1024*64)); // Opcodes = realloc(Opcodes, IP * sizeof(Opcodes[0])); Tables->NOpcodes = IP; Dump("GenerateParseTables() returns after %d opcodes\n", Tables->NOpcodes); return Tables; }