色五月色开心色婷婷色丁香,五月婷婷丁香花综合网,婷婷丁香五月激情综合在线,五月婷婷六月丁香动漫,婷婷丁香五月激情综合在线,丁香花中文字幕在线观看,播五月色五月开心五月网,开心激情综合网,狠狠色丁香婷婷综合最新地址,丁香视频在线观看,狠狠做六月爱婷婷综合av,久久激情五月丁香伊人

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營的一線實(shí)戰(zhàn)洞察。

PL0編譯器設(shè)計(jì)與實(shí)現(xiàn):從詞法分析到中間代碼生成的編譯原理實(shí)驗(yàn)指南

PL0編譯器設(shè)計(jì)與實(shí)現(xiàn):從詞法分析到中間代碼生成的編譯原理實(shí)驗(yàn)指南 簡介這是山東大學(xué)編譯原理課程PL/0編譯器實(shí)驗(yàn)的完整實(shí)現(xiàn)面向計(jì)算機(jī)專業(yè)學(xué)生及編譯原理學(xué)習(xí)者覆蓋詞法分析、語法分析、語義分析與符號(hào)表建立等編譯器前端核心環(huán)節(jié)。壓縮包共94個(gè)文件、約513KB以C/C源碼、CMake構(gòu)建腳本、可執(zhí)行程序、實(shí)驗(yàn)報(bào)告及多組測試輸入與運(yùn)行截圖為主要內(nèi)容便于對照工程結(jié)構(gòu)重新編譯和驗(yàn)證結(jié)果。目前已有104人學(xué)習(xí)下載。資源除完整可運(yùn)行的PL/0編譯器外還包含模塊劃分清晰的工程組織、多組PL/0測試程序如素?cái)?shù)、乘方、公約數(shù)計(jì)算及對應(yīng)截圖可直接用于課程設(shè)計(jì)參考、實(shí)驗(yàn)報(bào)告撰寫和編譯原理備考復(fù)習(xí)。1. PL0-Compiler是什么把編譯原理課程實(shí)驗(yàn)壓成一臺(tái)能跑的小編譯器第一次打開“PL0-Compiler 山東大學(xué)SDU編譯原理課程實(shí)驗(yàn)”這個(gè)項(xiàng)目標(biāo)題時(shí)我差點(diǎn)把它當(dāng)成又一個(gè)普通的課程設(shè)計(jì)。真正動(dòng)手之后才發(fā)現(xiàn)它要求你為一種叫 PL/0 的教學(xué)語言寫一個(gè)完整的小型編譯器從詞法分析到語法分析再到符號(hào)表、語義檢查、中間代碼生成最后還要有一個(gè)解釋器把程序跑起來。PL/0 本質(zhì)上是 Pascal 的極小核心子集只有常量、變量、過程、賦值、if、while、call 這些最基礎(chǔ)的語法單位但恰好把編譯原理課程里最該掌握的主干線全部覆蓋了。所以這篇筆記的服務(wù)對象很明確你要么是剛拿到 PL0-Compiler 實(shí)驗(yàn)、不知道從哪下手要么已經(jīng)寫完一版但總在某幾個(gè)邊界用例上翻車。很多學(xué)校的編譯原理實(shí)驗(yàn)都在 PL/0 上做或大或小的剪裁SDU 的版本也跳不出“語言說明 編譯器框架 解釋器”這個(gè)套路。下文我會(huì)按順序拆開詞法、語法、語義和代碼生成每一步都給出能直接抄的代碼和參數(shù)最后再把我踩過的幾個(gè)坑完整復(fù)述一遍。用 Java 來寫編譯原理實(shí)驗(yàn)是最常見的選型對象化改造也順手這篇就默認(rèn)用 Java 落地。2. 詞法分析先從源文件榨出干凈的 Token 流PL0-Compiler 的地基詞法分析是整個(gè) PL0-Compiler 里最先動(dòng)手的部分也是很多初學(xué)者“看著簡單、寫起來全是暗坑”的地方。PL/0 的詞匯很少十幾個(gè)保留字、一個(gè)標(biāo)識(shí)符、一個(gè)整數(shù)、幾個(gè)運(yùn)算符和界符所以常見做法是只寫一個(gè) getsym() 函數(shù)每次調(diào)用從源代碼里取出下一個(gè) Token。這里有兩個(gè)決策會(huì)直接影響后面所有代碼Token 用什么結(jié)構(gòu)表達(dá)關(guān)鍵字怎么識(shí)別。2.1 Token 結(jié)構(gòu)設(shè)計(jì)枚舉、保留字表和行號(hào)定位我一般會(huì)用枚舉把單詞類型固定下來而不是用 int 常量手寫一堆 0/1/2。原因很簡單后面的遞歸下降解析器里到處要比較sym Kind.IF或者switch(sym)枚舉能讓錯(cuò)誤消息和調(diào)試輸出自然可讀寫的時(shí)候還不會(huì)把 3 和 4 記混。public enum Kind { IDENT(標(biāo)識(shí)符), NUMBER(整數(shù)), CONST(const), VAR(var), PROCEDURE(procedure), BEGIN(begin), END(end), IF(if), THEN(then), ELSE(else), WHILE(while), DO(do), CALL(call), ODD(odd), ASSIGN(:), PLUS(), MINUS(-), TIMES(*), DIV(/), EQ(), NEQ(#), LT(), LE(), GT(), GE(), LPAREN((), RPAREN()), COMMA(,), SEMICOLON(;), PERIOD(.); final String label; Kind(String label) { this.label label; } }這段枚舉基本就是 PL/0 詞法范圍的全集。注意末尾的PERIOD對應(yīng)程序結(jié)束的“.”很多人會(huì)漏掉它結(jié)果語法分析在收尾時(shí)總是報(bào)“缺 .”。除了枚舉之外還需要一個(gè) EOF表示文件讀完放在 Token 類型里比較合適。Token 本身我建議做成一個(gè)小類kind 表示詞性text 保留原始字符intVal 只對 NUMBER 有意義line 用來給后續(xù)報(bào)錯(cuò)定位。public class Token { public Kind kind; public String text; public int intVal; public int line; }這樣一個(gè) Token 對象從詞法階段傳到語法分析再傳進(jìn)符號(hào)表字符串只在最開始保留一份后面全程都用對象引用查錯(cuò)了也知道該把錯(cuò)誤定位到第幾行。2.2 getsym 主循環(huán)先收標(biāo)識(shí)符再查表收編關(guān)鍵字PL/0 的保留字不多但如果你寫成if word.equals(const) else if word.equals(var)這種長串一旦要加關(guān)鍵字或者調(diào)整大小寫策略函數(shù)會(huì)臭不可聞。編譯原理實(shí)驗(yàn)里最穩(wěn)妥的做法是源程序里以字母開頭的連續(xù)串一律先當(dāng)作“可能是標(biāo)識(shí)符”來掃描然后查一個(gè) Map查不到就是 IDENT查得到就改成對應(yīng)保留字。先定義保留字表private static final MapString, Kind KEYWORDS new HashMap(); static { KEYWORDS.put(const, Kind.CONST); KEYWORDS.put(var, Kind.VAR); KEYWORDS.put(procedure, Kind.PROCEDURE); KEYWORDS.put(begin, Kind.BEGIN); KEYWORDS.put(end, Kind.END); KEYWORDS.put(if, Kind.IF); KEYWORDS.put(then, Kind.THEN); KEYWORDS.put(else, Kind.ELSE); KEYWORDS.put(while, Kind.WHILE); KEYWORDS.put(do, Kind.DO); KEYWORDS.put(call, Kind.CALL); KEYWORDS.put(odd, Kind.ODD); }掃描主流程private void getsym() { skipSpaceAndComment(); if (pos source.length()) { token new Token(Kind.EOF, EOF, line); return; } char c source.charAt(pos); if (Character.isLetter(c)) { int start pos; while (pos source.length() (Character.isLetterOrDigit(source.charAt(pos)) || source.charAt(pos) _)) { pos; } String word source.substring(start, pos); Kind kind KEYWORDS.get(word.toLowerCase()); token new Token(kind null ? Kind.IDENT : kind, word, line); } else if (Character.isDigit(c)) { scanNumber(); } else { scanOperatorOrPunctuation(c); } }這段邏輯里我允許了標(biāo)識(shí)符中包含數(shù)字和下劃線這是很多課程實(shí)驗(yàn)會(huì)給的小放寬。如果你拿到的文檔嚴(yán)格規(guī)定“標(biāo)識(shí)符只能以字母開頭后續(xù)只能是字母或數(shù)字”把_的分支去掉就行。大小寫策略也值得提前定好我做了toLowerCase()所以Begin和BEGIN都會(huì)被識(shí)別成 begin如果你們的實(shí)驗(yàn)區(qū)分大小寫刪掉 toLowerCase 并且保證保留字表全小寫也可以。注意關(guān)鍵字識(shí)別采用“先當(dāng)標(biāo)識(shí)符掃再查表改判”的順序比邊掃描邊逐字符匹配要穩(wěn)得多。這樣標(biāo)識(shí)符和關(guān)鍵字共用同一套字符推進(jìn)邏輯少一個(gè)分支就少一類 bug。2.3 三個(gè)容易埋雷的邊界多字符符號(hào)、整數(shù)溢出、非法字符多字符符號(hào)是詞法階段最容易留坑的地方。PL/0 的不等號(hào)是#而不是!小于等于和大于等于分別是、賦值號(hào)是:。每次 getsym 只推進(jìn)一個(gè)字符所以遇到時(shí)必須看一眼下一個(gè)字符是不是是就合成一個(gè) LE同時(shí) pos 要推進(jìn)兩位漏掉這次 peek 的錯(cuò)誤非常難查癥狀是x 2被解析成和兩個(gè)符號(hào)語法分析直接懵掉。數(shù)字掃描我建議用 long 做累加再判溢出不能等 int 已經(jīng)溢出之后再補(bǔ)救private void scanNumber() { int start pos; long v 0; while (pos source.length() Character.isDigit(source.charAt(pos))) { v v * 10 (source.charAt(pos) - 0); if (v Integer.MAX_VALUE) { error(ERR_NUM_TOO_LARGE, 整數(shù)溢出: source.substring(start, pos)); while (pos source.length() Character.isDigit(source.charAt(pos))) { pos; } token new Token(Kind.NUMBER, source.substring(start, pos), line); token.intVal 0; return; } pos; } token new Token(Kind.NUMBER, source.substring(start, pos), line); token.intVal (int) v; }判溢出時(shí)必須把剩余數(shù)字全部消費(fèi)掉否則一個(gè)大整數(shù)會(huì)被拆成兩段數(shù)字后面可能誤判成合法程序。非法字符的處理同理、^、$這類誰都不是的字符如果分支里只報(bào)錯(cuò)不推進(jìn) pos下一輪 getsym 還會(huì)看到同一個(gè)字符輕則錯(cuò)誤刷屏嚴(yán)重時(shí)直接死循環(huán)。正確做法是報(bào)錯(cuò)之后pos繼續(xù)。注釋要不要支持一定要看實(shí)驗(yàn)文檔。有的 PL/0 版本沿用 Wirth 原書的{ }注釋有的學(xué)校改成/* */有的是壓根不要求。如果要求支持我一般只做非嵌套的/* */private void skipSpaceAndComment() { while (pos source.length()) { if (Character.isWhitespace(source.charAt(pos))) { pos; } else if (source.charAt(pos) / pos 1 source.length() source.charAt(pos 1) *) { pos 2; while (pos 1 source.length() !(source.charAt(pos) * source.charAt(pos 1) /)) { pos; } pos 2; } else { break; } } }這段代碼的最大好處是空白和注釋可以交替出現(xiàn)中間不需要反復(fù)調(diào)用 getsym。缺點(diǎn)是注釋不閉合時(shí) pos 會(huì)一路走到文件尾所以主流程里最好檢查一下pos是否已經(jīng)越界并報(bào)“注釋未閉合”。寫完詞法器我建議先跑一個(gè)臨時(shí) main把源文件里的 Token 流打出來看一眼確認(rèn)無誤再往下寫語法分析public static void main(String[] args) { Lexer lexer new Lexer(begin x : 1 2; end.); Token t; while ((t lexer.next()).kind ! Kind.EOF) { System.out.printf(%d\t%s\t%s\t%d%n, t.line, t.kind, t.text, t.intVal); } }這一步能幫你把問題隔離在詞法階段。別急著往后寫Token 流不對后面所有解析結(jié)果都是空中樓閣。3. 語法分析用遞歸下降扣住 PL/0 文法表達(dá)式優(yōu)先級(jí)不再翻車詞法分析把源程序切成 Token 流之后語法分析負(fù)責(zé)按文法把這些 Token 組織成語法結(jié)構(gòu)。PL/0 的文法是經(jīng)典的自上而下文法常見做法是手寫遞歸下降一個(gè)非終結(jié)符對應(yīng)一個(gè)函數(shù)。它和 LL(1) 文法長得幾乎一樣手工實(shí)現(xiàn)也不需要額外的表驅(qū)動(dòng)框架調(diào)試時(shí)還能直接看到調(diào)用鏈最適合作為編譯原理實(shí)驗(yàn)的骨干。3.1 PL/0 的文法全貌先把 block 和 statement 遞歸關(guān)系畫清楚一份標(biāo)準(zhǔn)的 PL/0 文法可以縮寫成下面這套 BNFprogram block . block [constDecl] [varDecl] {procDecl} statement constDecl const ident number {, ident number} ; varDecl var ident {, ident} ; procDecl procedure ident ; block ; statement [ident : expression | call ident | begin statement {; statement} end | if condition then statement [else statement] | while condition do statement] condition odd expression | expression relop expression expression [|-] term {(|-) term} term factor {(*|/) factor} factor ident | number | ( expression ) relop | # | | | | 這套文法里有幾個(gè)地方值得先說破。block是絕對核心它同時(shí)處理常量聲明、變量聲明、過程聲明和一條語句而且過程聲明里又會(huì)遞歸調(diào)用block也就是說過程可以嵌套定義。statement的兩種寫法里if后面可以跟可選的elsebegin...end內(nèi)部是用分號(hào)分隔的語句序列最后一個(gè)分號(hào)可寫可不寫這里最容易產(chǎn)生多余的錯(cuò)誤報(bào)錯(cuò)。函數(shù)劃分不需要什么高深設(shè)計(jì)每個(gè)非終結(jié)符寫一個(gè)私有方法方法名直接叫block、statement、condition、expression、term、factor。程序結(jié)構(gòu)和文法一一對應(yīng)答辯的時(shí)候別人問哪段對應(yīng)哪條產(chǎn)生式你指一下方法名就行。private void block() { table.enterBlock(); int savedVarOffset currentVarOffset; if (sym Kind.CONST) { constDecl(); } if (sym Kind.VAR) { varDecl(); } while (sym Kind.PROCEDURE) { procDecl(); } statement(); currentVarOffset savedVarOffset; table.exitBlock(); }這里的currentVarOffset要格外小心。每個(gè)塊進(jìn)入時(shí)都從某個(gè)固定偏移開始給局部變量分配槽位但這個(gè)偏移不能一直累加否則不同塊的變量地址會(huì)互相踩踏。所以進(jìn)入 block 時(shí)保存舊值塊結(jié)束再恢復(fù)正是這段代碼里savedVarOffset的職責(zé)。3.2 expression/term/factor 的調(diào)用層級(jí)乘除為何排在加減下面表達(dá)式是語法分析里最好檢驗(yàn)優(yōu)先級(jí)的地方。PL/0 的表達(dá)式定義成[加號(hào)|減號(hào)] term { (加號(hào)|減號(hào)) term }term 定義成factor { (乘號(hào)|除號(hào)) factor }factor 才是真正出現(xiàn)標(biāo)識(shí)符、整數(shù)和括號(hào)的那一層。這種分層結(jié)構(gòu)保證了乘除先算、加減后算括號(hào)通過遞歸回到 expression 實(shí)現(xiàn)。private void expression() { if (sym Kind.PLUS || sym Kind.MINUS) { boolean minus sym Kind.MINUS; getsym(); term(); if (minus) { gen(OPR, 0, OPR_NEGATIVE); } } else { term(); } while (sym Kind.PLUS || sym Kind.MINUS) { Kind op sym; getsym(); term(); if (op Kind.PLUS) { gen(OPR, 0, OPR_ADD); } else { gen(OPR, 0, OPR_SUB); } } }這段代碼先處理一元正負(fù)號(hào)再通過 while 循環(huán)把同層級(jí)的加減法運(yùn)算符全部消耗掉。如果沒有最前面的if (sym Kind.PLUS || sym Kind.MINUS)-x1就會(huì)被理解成“負(fù)號(hào)后面缺一個(gè)操作數(shù)”從而誤報(bào)語法錯(cuò)誤。term 的結(jié)構(gòu)和 expression 幾乎一樣區(qū)別只是把因子換成低一層private void term() { factor(); while (sym Kind.TIMES || sym Kind.DIV) { Kind op sym; getsym(); factor(); if (op Kind.TIMES) { gen(OPR, 0, OPR_MUL); } else { gen(OPR, 0, OPR_DIV); } } }factor 是真正查符號(hào)表、生成 LIT 或 LOD 指令的地方private void factor() { if (sym Kind.IDENT) { Symbol s table.find(token.text); if (s null) { error(ERR_UNDEFINED, 未定義標(biāo)識(shí)符 token.text); } else if (s.kind() Kind.CONST) { gen(LIT, 0, s.val()); } else if (s.kind() Kind.VAR) { gen(LOD, levelDiff(myLevel, s.level()), s.addr()); } else { error(ERR_INVALID_EXPR, 過程名不能出現(xiàn)在表達(dá)式中 token.text); } getsym(); } else if (sym Kind.NUMBER) { gen(LIT, 0, token.intVal); getsym(); } else if (sym Kind.LPAREN) { getsym(); expression(); if (sym ! Kind.RPAREN) { error(ERR_RPAREN_EXPECTED, 缺少右括號(hào)); } else { getsym(); } } else { error(ERR_FACTOR_EXPECTED, 因子開始符號(hào)非法); getsym(); } }factor 里的getsym()必須放在每個(gè)分支的公共出口否則解析到非法因子時(shí)會(huì)原地重復(fù)處理同一個(gè) Token遞歸下降立刻被打成死循環(huán)。寫完這三層拿12*3和(12)*3兩個(gè)用例分別驗(yàn)證一個(gè)結(jié)果應(yīng)該對另一個(gè)應(yīng)該不對如果輸出反了多半是 expression 和 term 的層級(jí)倒掛了。3.3 test() 錯(cuò)誤同步語法分析如何從第一個(gè)錯(cuò)里活下來遞歸下降解析器遇到一個(gè)不期望的符號(hào)時(shí)如果只是簡單報(bào)錯(cuò)并 return后續(xù)語句大概率會(huì)被連環(huán)誤報(bào)。經(jīng)典 PL/0 教材里的做法是寫一個(gè)test()函數(shù)它接收一個(gè)期望符號(hào)集合如果當(dāng)前符號(hào)不在集合里就報(bào)錯(cuò)并向前同步直到找到集合中的某個(gè)符號(hào)為止。private void test(int[] expected, int errCode, String msg) { if (!inSet(expected)) { error(errCode, msg); do { getsym(); } while (!inSet(expected) sym ! Kind.EOF); } } private boolean inSet(int[] expected) { for (int s : expected) { if (s sym.ordinal()) { return true; } } return false; }這里的ordinal()是因?yàn)槲矣昧嗣杜e類型如果你用 int 常量表示符號(hào)直接比較數(shù)字即可。調(diào)用方式就像這樣// 解析 statement 前先確認(rèn)當(dāng)前符號(hào)是語句合法的開頭 test(new int[]{Kind.IDENT.ordinal(), Kind.CALL.ordinal(), Kind.BEGIN.ordinal(), Kind.IF.ordinal(), Kind.WHILE.ordinal()}, ERR_STMT_EXPECTED, 語句開始符號(hào)非法);“同步”這個(gè)詞聽起來玄實(shí)際含義就是跳過那些既不屬于當(dāng)前集合、也不像錯(cuò)誤終結(jié)符的 Token直到找到一段可以繼續(xù)分析的結(jié)構(gòu)邊界。比如begin x : ; end里面賦值號(hào)后面缺表達(dá)式expression 會(huì)報(bào)錯(cuò)但同步到end后statement 還能繼續(xù)往下走不會(huì)把“end 后面缺分號(hào)”這種假錯(cuò)誤也報(bào)出來。錯(cuò)誤同步是答辯論時(shí)老師大概率會(huì)問的點(diǎn)它不追求報(bào)錯(cuò)數(shù)量追求報(bào)錯(cuò)質(zhì)量。4. 符號(hào)表與語義動(dòng)作PL0-Compiler 的判斷力藏在這里語法分析只回答“這串 Token 合不合文法”但x : 1里的 x 到底有沒有定義、能不能給常量賦值、過程名能不能當(dāng)變量用這些必須靠符號(hào)表和語義檢查來回答。符號(hào)表就是編譯器的“業(yè)務(wù)現(xiàn)場”所有聲明信息、作用域關(guān)系、變量地址都要在這里落地。4.1 符號(hào)表設(shè)計(jì)按塊管理進(jìn)入和退出 block 時(shí)自動(dòng)清理PL/0 支持過程嵌套所以符號(hào)表必須按塊劃分。常見做法是給每個(gè)符號(hào)記錄一個(gè) blockId進(jìn)入塊時(shí)壓棧并遞增編號(hào)退出塊時(shí)把屬于當(dāng)前塊的符號(hào)全部彈出。public record Symbol(String name, Kind kind, int val, int level, int addr, int blockId) { } public class SymbolTable { private final ListSymbol symbols new ArrayList(); private int currentBlock; private final DequeInteger blockMarks new ArrayDeque(); public void enterBlock() { blockMarks.push(currentBlock); currentBlock; } public void exitBlock() { int mark blockMarks.pop(); while (!symbols.isEmpty() symbols.get(symbols.size() - 1).blockId() mark) { symbols.remove(symbols.size() - 1); } currentBlock blockMarks.peek(); } public Symbol find(String name) { for (int i symbols.size() - 1; i 0; i--) { Symbol s symbols.get(i); if (s.name().equals(name)) { return s; } } return null; } public boolean existsInCurrentBlock(String name) { for (Symbol s : symbols) { if (s.blockId() currentBlock s.name().equals(name)) { return true; } } return false; } }因?yàn)榉?hào)列表是從表尾開始查找的所以內(nèi)層聲明的同名符號(hào)總會(huì)被先找到這正好實(shí)現(xiàn)了內(nèi)層遮蔽外層的語義。退出內(nèi)層塊時(shí)符號(hào)被清理內(nèi)層名稱對外不可見外層名稱重新變回可見。Symbol用 Java record 寫很緊湊val 字段對常量才有意義addr 字段對變量和過程才有意義別在語義檢查里混淆它們。4.2 聲明處理與語義檢查查重、未定義變量、常量賦值攔截處理 const 聲明和 var 聲明時(shí)重復(fù)定義是最需要攔截的錯(cuò)誤。判斷規(guī)則不是“全局唯一”而是“當(dāng)前塊內(nèi)不得重名”。private void constDecl() { getsym(); // 跳過 const do { if (sym ! Kind.IDENT) { error(ERR_IDENT_EXPECTED, 常量聲明缺少標(biāo)識(shí)符); return; } String name token.text; if (table.existsInCurrentBlock(name)) { error(ERR_DUP_DECL, 重復(fù)定義: name); } getsym(); if (sym ! Kind.EQ) { error(ERR_EQ_EXPECTED, 常量聲明缺少 ); getsym(); } else { getsym(); } if (sym ! Kind.NUMBER) { error(ERR_NUM_EXPECTED, 常量值必須是整數(shù)); return; } int val token.intVal; table.add(new Symbol(name, Kind.CONST, val, currentLevel, 0, currentBlock)); getsym(); } while (sym Kind.COMMA); if (sym ! Kind.SEMICOLON) { error(ERR_SEMI_EXPECTED, 常量聲明缺少分號(hào)); } else { getsym(); } }變量聲明類似只是不給值而是分配偏移量。給變量分配地址時(shí)記住一個(gè)原則過程符號(hào)不占用數(shù)據(jù)槽位常量符號(hào)也不占用只有 VAR 才會(huì)讓currentVarOffset遞增。PL/0 的棧式虛擬機(jī)里每個(gè)棧幀通常要留出三個(gè)固定槽給動(dòng)態(tài)鏈、靜態(tài)鏈和返回地址所以局部變量從偏移 3 開始分配是常見約定。如果你沒有這三槽設(shè)計(jì)可以從 0 開始但要保證調(diào)用過程時(shí)棧幀布局和解釋器一致。賦值語句的語義檢查尤其要攔常量賦值private void assignment() { String name token.text; Symbol s table.find(name); if (s null) { error(ERR_UNDEFINED, 未定義變量: name); } else if (s.kind() Kind.CONST) { error(ERR_CONST_ASSIGN, 不能給常量賦值: name); } getsym(); if (sym ! Kind.ASSIGN) { error(ERR_ASSIGN_EXPECTED, 缺少賦值號(hào) :); return; } getsym(); expression(); if (s ! null s.kind() Kind.VAR) { gen(STO, levelDiff(currentLevel, s.level()), s.addr()); } }如果變量未定義語法分析可以繼續(xù)但不應(yīng)生成 STO 指令如果變量其實(shí)是常量就更不能生成存儲(chǔ)指令。語義錯(cuò)誤和代碼生成要分開這類“報(bào)錯(cuò)但不再生成錯(cuò)誤代碼”的處理是實(shí)驗(yàn)評分里很容易被檢查的細(xì)節(jié)。4.3 中間代碼生成一個(gè)指令八條的表驅(qū)動(dòng)虛擬機(jī)PL/0 不生成 x86 匯編而是生成一套精簡的中間指令再由解釋器執(zhí)行。我習(xí)慣用八條指令指令參數(shù)含義LITval整常數(shù)壓棧OPRop對棧頂做運(yùn)算LODlevel offset從指定層取變量壓棧STOlevel offset棧頂存入指定層變量CALlevel offset調(diào)用過程INTsize給當(dāng)前塊分配棧空間JMPaddr無條件跳轉(zhuǎn)JPCaddr棧頂為假時(shí)跳轉(zhuǎn)OPR 的子操作碼屬于內(nèi)部約定你完全可以用自己的一套編號(hào)只需要保證生成器和解釋器一致。我常用0 返回、1 取負(fù)、2 加、3 減、4 乘、5 除、6 判斷奇數(shù)、7 到 12 是六個(gè)比較運(yùn)算、13 讀入、14 輸出。生成代碼時(shí)if 和 while 都要用“先留空地址生成完畢再回填”的 backpatch 技巧// if cond then stmt else stmt condition(); int jpc gen(JPC, 0, 0); // 條件為假時(shí)跳出 then 分支 statement(); if (sym Kind.ELSE) { int jmp gen(JMP, 0, 0); // then 分支執(zhí)行完要跳過 else patch(jpc, pc()); // 回填假跳轉(zhuǎn)到 else 的語句 getsym(); statement(); patch(jmp, pc()); // 回填跳過 else } else { patch(jpc, pc()); // 沒有 else 時(shí)跳到整個(gè)語句之后 }回填的位置差一行就會(huì)讓程序邏輯徹底變樣比如 if 的兩個(gè)分支都執(zhí)行或者 while 循環(huán)永遠(yuǎn)多跑一次。寫完之后把指令流打印出來逐條核對你會(huì)發(fā)現(xiàn)這套虛擬機(jī)對排錯(cuò)非常友好。5. 避坑PL0-Compiler 調(diào)試中我反復(fù)踩的四個(gè)編譯原理實(shí)驗(yàn)坑這門實(shí)驗(yàn)最大的特點(diǎn)是代碼量不大但每類錯(cuò)誤都藏在最不起眼的位置。下面四個(gè)問題是我在類似 PL0-Compiler 實(shí)現(xiàn)里見過最多、自己也踩過的坑全部按“現(xiàn)象 → 原因 → 解決”的順序?qū)憽?.1 詞法死循環(huán)非法字符被吞掉后 getsym 原地打轉(zhuǎn)現(xiàn)象給詞法器一個(gè)包含或者^的測試程序編譯進(jìn)程不退出CPU 卻跑滿有的實(shí)現(xiàn)則表現(xiàn)為錯(cuò)誤消息洪流刷屏到幾乎停不下來。原因getsym 在 popup fallback 里識(shí)別不了這個(gè)字符只是報(bào)錯(cuò)但沒有推進(jìn) pos。下一輪 getsym 還是讀同一個(gè)字符于是無限循環(huán)。有些代碼在錯(cuò)誤分支里調(diào)用了自己卻沒在遞歸前先推進(jìn) pos效果同樣。解決非法字符分支里必須先pos再報(bào)錯(cuò)保證每一次 getsym 調(diào)用最多只處理一個(gè)字符。詞法主函數(shù)里凡是能返回 Token 的分支都必須有明確的字符推進(jìn)動(dòng)作。我在 2.3 節(jié)里把它寫在代碼注釋里就是因?yàn)樗菀茁?.2 優(yōu)先級(jí)翻車12*3 算出 9term 層沒把 factor 包起來現(xiàn)象語法分析沒報(bào)錯(cuò)解釋執(zhí)行的結(jié)果卻不對12*3輸出 9而不是 7。原因expression 里沒有調(diào)用 term而是直接調(diào)用了 factor或者 term 里沒有 while 循環(huán)只解析了一個(gè)因子就 return。遞歸下降的每層函數(shù)都對應(yīng)文法的每一層優(yōu)先級(jí)少一層就退化成完全左結(jié)合或右結(jié)合。解決嚴(yán)格按照expression → term → factor三層來寫。第一層處理加減第二層處理乘除第三層處理標(biāo)識(shí)符、數(shù)字和括號(hào)。調(diào)試時(shí)用12*3、(12)*3、-x1三個(gè)用例同時(shí)驗(yàn)證任何一個(gè)不對都說明層級(jí)關(guān)系有誤。5.3 作用域污染內(nèi)層過程退出后同名變量仍然可見現(xiàn)象內(nèi)層過程聲明了一個(gè)和外層同名的變量返回外層后外層變量居然被內(nèi)層的那個(gè)同名變量遮蔽了更嚴(yán)重的是外層之后訪問這個(gè)變量時(shí)程序行為完全錯(cuò)亂。原因符號(hào)表只做增加不做清理退出內(nèi)層塊時(shí)沒有把本塊符號(hào)彈出去。find 函數(shù)又總是從表尾往前查于是內(nèi)層符號(hào)一直“穿透”作用域屏障。解決用 4.1 節(jié)的 blockId 方案進(jìn)入塊時(shí)記 mark退出塊時(shí)按 mark 彈出本塊符號(hào)。寫完作用域測試用例后最好打印一份符號(hào)表觀察名字和 blockId 的對應(yīng)關(guān)系不要只靠運(yùn)行結(jié)果判斷。5.4 跳轉(zhuǎn)目標(biāo)差一行if/while 的 backpatch 算錯(cuò)位置現(xiàn)象if 的 then 和 else 兩個(gè)分支同時(shí)執(zhí)行或者 while 循環(huán)多執(zhí)行一次、少執(zhí)行一次而詞法、語法、符號(hào)表都查不出問題。原因JPC 或 JMP 的后綴位置填錯(cuò)了。常見做法是把回填時(shí)機(jī)放在 getsym 之后結(jié)果實(shí)際地址已經(jīng)比預(yù)期多跑了一段也有的是把“語句結(jié)束后的地址”當(dāng)成了“else 分支的地址”來填。解決把生成指令的 pc 值打印出來對照中間代碼人工走一遍。沒有 else 時(shí)JPC 應(yīng)跳到整個(gè) if 語句之后有 else 時(shí)JPC 跳到 else 語句首條指令JMP 跳到整個(gè)語句之后。while 的回填目標(biāo)則是條件判斷指令之前形成一個(gè)向后循環(huán)的 JMP。注意不要迷信“程序跑通了就沒問題”。PL0-Compiler 這類實(shí)驗(yàn)的評分點(diǎn)通常很細(xì)建議把中間代碼和符號(hào)表都保留成可打印狀態(tài)答辯時(shí)這些比嘴上講原理更能說明問題。6. 驗(yàn)證 PL0-Compiler從最小用例集到自動(dòng)化 diff 的收尾等到詞法、語法、語義和代碼生成都跑通之后最需要做的不是著急寫完整測試而是建立一套能反復(fù)執(zhí)行的回歸用例集。PL/0 語言小每個(gè)語法成分都不難測真正的風(fēng)險(xiǎn)在于“改動(dòng)一處帶來別處回退”這種問題只有靠自動(dòng)化 diff 才抓得住。6.1 最小用例集每個(gè)語法成分都要有一個(gè)正例和一個(gè)反例我建議準(zhǔn)備這樣一個(gè) cases 目錄每個(gè).pl0文件對應(yīng)一個(gè)測試主題用例文件覆蓋點(diǎn)期望結(jié)果const.pl0常量聲明、常量引用輸出 3var_assign.pl0變量聲明、賦值輸出 2priority.pl012*3與(12)*37 和 9if_else.pl0if/else 分支分支選擇正確while.pl0循環(huán) 0 次和多次輸出累計(jì)結(jié)果nested_proc.pl0過程嵌套、作用域遮蔽內(nèi)外變量互不干擾err_dup.pl0重復(fù)定義編譯期報(bào)錯(cuò)err_undef.pl0未定義標(biāo)識(shí)符編譯期報(bào)錯(cuò)err_const_assign.pl0給常量賦值編譯期報(bào)錯(cuò)每個(gè)用例文件旁邊放一個(gè).out文件保存期望輸出。數(shù)量不用多但每個(gè)語法成分都必須覆蓋到“能跑”和“不能跑”兩個(gè)方向。反向用例的價(jià)值在于驗(yàn)證編譯期的錯(cuò)誤報(bào)告和退出碼而不是看解釋器執(zhí)行。6.2 自動(dòng)化 diff把“好像能跑”變成“回歸全綠”在項(xiàng)目根目錄放一個(gè)run_tests.sh把每一個(gè).pl0文件編譯后執(zhí)行再和期望輸出對拍#!/usr/bin/env bash if ! java -cp . com.sdu.pl0.Main $src real.out 21; then ... fi for src in cases/*.pl0; do base${src%.pl0} java -cp . PL0Compiler $src /dev/null real_${base}.out 21 if [ -f ${base}.out ]; then if ! diff -u ${base}.out real_${base}.out diff.log; then echo FAIL: $src cat diff.log exit 1 fi fi rm -f real_${base}.out done echo test all passed這段腳本的邏輯很簡單編譯產(chǎn)物和期望輸出做diff -u任何不一致都立刻失敗并打印現(xiàn)場。跑一次全綠才算這個(gè)頁面的最小可用版本真正穩(wěn)住了。后續(xù)不管改詞法、改語法還是加新指令集都要重跑一遍這個(gè)腳本而不是只手動(dòng)試一兩個(gè)例子。6.3 一個(gè)看棧的底牌給解釋器加 trace 開關(guān)調(diào)試 PL/0 生成指令時(shí)最抓狂的情況是“我知道結(jié)果不對但不知道是哪一條指令開始不對”。給解釋器加一個(gè)全局布爾變量trace在每條指令執(zhí)行后打印當(dāng)前 pc、操作碼、操作數(shù)和棧頂內(nèi)容if (trace) { System.out.printf(pc%04d op%s level%d addr%d stackTop%d%n, pc - 1, opName(ins.op()), ins.level(), ins.addr(), stack.empty() ? Integer.MIN_VALUE : stack.peek()); }開 trace 之后把12*3的指令序列和手算結(jié)果逐條對照很快就能發(fā)現(xiàn)是1*2先算還是2*3先算。這個(gè)習(xí)慣我當(dāng)時(shí)一直保持到實(shí)驗(yàn)結(jié)束先小用例開 trace 驗(yàn)證指令序列再關(guān)掉 trace 跑完整測試套件兩者配合幾乎沒有排不掉的邏輯錯(cuò)誤。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
亚洲天堂在线怕怕视频| 97er欧美性| 精品人妻一区二区三区日产乱码| 亚洲清纯唯美| 67914在线精品观看| www.久久最新地址| 91欧洲国产成人久久精品网站| 精品乱码久久久久| 丰满人妻一区二区三区四| 国产无码精品高清| 97天堂| 国产av青草| 91精品久久综合熟女| 亚洲色宗合| 国产丝袜高跟美女av免费观看| 97人妻色| 99色在线| 偷看洗澡一二三区美女| 国产综合久| 嗯嗯,好大,好爽,好骚 | 神马久久久久久久久| 国产欧美伊人| 女人爽到高潮潮喷18禁网站| 伦激情人妻另类人妻| 中国91AV| 射综合网| 欧美色宗合| 9.1小视频| 新视频sss国产| 人人爱夜夜爱| 中文字幕艹艹| 欧美九九99久久精品| 国产东北女人在线视频| 亚洲人成网站7777| a在线视频免费观看| 亚洲国产麻豆一区二区三区| 天天搞在线综合网| 天天综合网日韩7799| 一起草高清无码| 中文字幕精品三级久久久| 91久久18禁| 国产13区| 精品成人女人久久| 88在线一区二区三区| 久久久久大香青草精品综合| 97一区二压| 欧美综合色站| 国产精品视频播放| 欧美乱色| 色网1| 亚洲精品国产熟女| 日本性交操一区二区不卡系列| 日日碰视频网| 综合色久欲| 久久久一热在线播放| 精品一区二区亚洲国产| 精品亚洲国产成人AV制服丝袜 | www超碰| 日本性爱网址| 久9热| 99亚洲天堂| 天天爽天天操| 国产高清不卡视频| 九九九九九九九九九九九九九九九女| 人妻五十路在线| 妇女乱色二区| 97超碰中文在线| 男人天堂毛片| 亚洲欧美不卡线| 男人久久天堂| 欧美专区日本专区| 91原创在线观看| 久久久久密| 欧美性区| 18禁在线视频| 99re久久| 大香蕉啪啪啪啪在线| 射丝袜大香蕉| 国产又黄又粗又猛大片| 黄骗免费| www.狠狠干.coom| 欧洲射精91| 亚洲 另类 丝袜 自拍 动漫| 97亚洲精品| 东京热视频网| 9久精品| 97这里只精品| 日日操夜夜操天天操免费观看麻豆| 亚洲国产精品无石码久久 | 国产家庭乱伦表演| 97人人模人人爽人人| 国产剧情一区在线观看| 风月影院男女十八禁| 精人妻一区二区三区| 成人小说视频在线精品欧美| 成功精品影院| 超碰欧美97资源| 襙一襙| 久久性视频| 黄色小说亚洲| 97资源亚洲| 欧美激情另类一区二区| 欧美久久九九| 欧美人妖内射| 高清无码 国产精品| 啊啊啊操一区| 韩日欧亚a级| 国产区91柔拿会所技师| 九九热超碰97亚洲最新香蕉| 一本色道久久综合狠狠操| 人人模人人看| 日本三级久| 亚洲风情综合网| 国产黄色在线播放观看| yirendaxiangjiashipin| 成人草草视频| 99热这里只有精品地址| yy少妇精品久久| 日韩激情毛片一级久久久| 国产后入精品| 舔足天天操天天射| av在线免费一区二区| 伊人黄色片| 久久极品一区二区| 青娱乐老司机视频| 高清不卡国产| 日本不卡一区二区| www.97在线| 98久久| 丁香六月综合激情| 伊人国产成人av网站| 嗯啊不要在线观看嗯啊| 9999久久久| 黄页大片在线观看| 亚洲AV成人精品网站在AV| 久久久精品国产亚洲伊人| 一本大道久| 国产欧美亚洲精品a第2页| 91精品免费| 中文字幕av乱伦| 在线电影亚洲色图| 校园春色 男人天堂 | 99在线精品观看99| 亚洲色阁| 国产福利夜| 亚洲天天做日日做天天谢日日 | 久久天堂网| 丁香五月婷婷基地| 91精品国产91综合久久蜜臀| 91超碰在线播放| 人人摸人人添人人操| 日本精品九九九| 亚洲精品第一| 欧美18 在线观看| 天天干天天日天天射黄色片| 国产成人精品无码久久| 99少妇| 久久黄黄| 免费一级性爱久久| 嫩草 我啊~嗯~在线| 国产男人又猛又粗又爽| 欧美日韩精品久久久久久久久东北老熟妇| 六九九九| 欧美黑人精品在线播放| 人人澡人人澡人人| 欧美亚洲影视| 天天天天操| 久久精品国产亚洲AV清纯| 天操老女人| 丁香五月影院| 无码人妻精品一区二区三区99不卡| 九九热男人天堂| 一类无码操逼视频| 超清福利精品视频在线| 日韩精品一二三| 亚洲精品丝袜| 天天爱天天操| 亚洲国产欧美中文永久| 国产JDAV无码视频在线观看| 亚洲精品 欧美97色色| 五月天激情网站| 在线人成亚洲视频免费观看| 日本久久超碰| 区自美91| 久久婷婷欧美| 日韩专区数据列表-第3230页-精品国产一区二区三区香蕉 久久99熟女人妻中文字 | 黄色av片三级三级三级免费看| 色欲天香天天综合网-成年人三级片网站-欧美乱妇狂野-日韩国产专区-久久久久久 | 老熟女熟妇| 天天天天天干夜夜夜夜夜操| 9久精品| 日韩成人人妻网站| www.91欧美| 婷婷日韩一区二区三区中文字幕在线| 奇米四色影视777久久久| 亚洲情色综合| 最新AV在线| 嗯嗯啊啊的视频| 一区二区精品更新提醒| 久久久人体| 亚洲精品乱码久久久久久蜜桃麻豆| 91搡老女人老妇女老熟女歌词翻译| 天天日天天干天天色| 一二三四区操操Av| 夜夜骑日日| 一区二区三区四区久久视1| 日本人体九九九九九九| 天天日少妇逼AV| 日本三级R| 亚洲女毛多水多21P| 九色精品视频导航1| 密臀在线一区尤物| 在线97视频| 精产品久久| 性生活性生大爱77AV国产| 中文字幕诱惑制服人妻丝袜美丝袜美 | 大香蕉人妻久久| 中文字幕av一区二区三区人妻少妇 | 美日韩成人| 国产精品视频精品一二| 五月天激情小说网| 欧美激情 日韩精品| 国产精品肉丝自拍| 97色色,97综合| 歐美性天天| 99热在线播放| 人妻少妇蜜桃视频欧美一区| 青娱乐亚洲热| www.高清无码诱惑一区.com| 国产25页| 操久久久久| 91色插| 久热一区二区| 欧美日韩中文视频播放| 女性喷水高潮在线观看| 亚洲天堂一区二区久久| 久久亚洲av成人无码国产| 国产超碰| 日韩啪啪啪啪啪| 九九毛片这里只有精品| 一区二区三区蜜桃成人撸久久东京热| 亚熟hd视频在线| 欧美日韩另类字幕中文| 欧美激情亚洲| 100啪啪视频大全| 少妇人妻太紧太深av| 国产99久久99热这里只有精品15 | 午夜性生活av免费在线看| 麻豆国产视频精品观看| 五月天激情小说| 亚洲综合113页| 啊啊啊97视频| 欧美在线电影| 中国操逼无码| 国产欧美日韩在线观看麻豆传媒公司| 成人热久久精品| 另类老少妇| 黑人娇小av在线播放| 啪啪啪东京| 激情五月天色播| 国产精品亚洲四五区在线观看| 美腿丝袜高跟网免费视频免费视频| 美女91在线观看| 一卡二卡三卡| 亚洲啪啪视频一区二区| 色玖玖| 极品内射| 中韩中文字幕在线观看| 久综合国内精品自在自线| av一区二区三区 中文| 熟妇视频一区二区三区在线观看| 久草成人影片| 超碰色男人操熟女| 任我爽视频在线观看| 屁股久久久久久久久| 久久少妇| 激情网五月天| 久久久久久久综合,国产| 97日韩欧美| 操逼网站视频漫画国产| 九九热三级片| 91精品啪在线观看国产城中村| 日韩一级二级| 人妻熟女一区二区三区视频| 亚洲女毛多水多21P| 一区中文字幕二区日韩| 国产日产欧产美韩系列麻豆免费| 亚洲电影中字一区二区| 操九九九九九九| 欧美色另类| 欧美成va视频网站| 射丝袜大香蕉| 久操凹凸视频| 国产精品久久久久久久久久久久久久久| 伊人91| 午夜AV人气不卡| 亚洲成人一二三区| 91在线免费精品视频| 久久精品一区二区三区不卡| 欧美综合综合| 久久综合激情| 大香蕉狠狠爱| 91oumei| 色97干| 99热欧美| yiqicaoav| 91在线视频免费中出| 男人的天堂va在线| 国产原创自拍| 亚洲天天在线| 69精品人人人人| 2018天天日天天日| 日韩少妇在线视频| 黄色区免费观看中文字幕| 欧美色图 人妻| 蜜臀99久| 精品九九九九九九九| 亚洲欧美综合区自拍另类 | 国产在线播放成人免费| 夜夜操91744565| 2017,超碰| 91五月天| 日韩综合成人免费视频| 亚洲熟女乱色一区二区三区久久久| 岛国视频一二三区| 熟女熟妇一区二区三区视频| 婷婷色一区| 亚洲春色欧美激情自拍| 国内精品久9| 蜜桃色色网站视频三区| 成人性爱视频在线看| 98福利在线视频| 大伊香蕉在线视频免费| 亚洲丝袜综合| 人妻激情在线视频| 亚码激情| 色噜噜精品一区二区三| 三及片网站| 欧美亚男人的天堂| www.色婷婷色综合| 日本影视久久免费| 色拍偷亚洲| 亚洲中文日韩欧美大香蕉视频| 国产精品夜夜夜| 亚洲色天堂日韩中| 美女黄频a美女大全免费皮| 老司机香蕉| 欧美少妇性乱| 国色天香av| 插穴性爱视频在线观看| 精品999一区二区| 日本一片一区| 久久一区二区三区入口| 人妻另类 专区 欧美 制服| 操逼短片| 青青草黑寡妇男人天堂| 动漫爆乳3D奶水一区在线观看| 国产偷拍网站| www男人天堂| 欧美久久婷婷| 婷婷色一区| 国产吞精a级片激情电影| 毛片一区二区| 欧美综合色图网| 青青草精品| av天天在线观看| yellow网站免费观看日韩高清无码| 国产欧美精选激情视频| 五月丁香影院| 亚洲成a人片在线观看中文!!!| 久久岛国| 欧美桃色网| 一区二区三区男女操逼黄色小电影| 囯产乱伦一区二区三女| 国产一级特黄大片处女| 在线观看不卡一区二区三区| 天天久久| 蜜臀网 一区| 懂色影视久久| 国产精品九九| 精人妻无码一区二区三区伊人直播| 中文字幕一区 二 区 三 四 五 区日 日 骚| 夜嗨影院| 亚洲天堂人妻熟妇视频| 亚洲国产一区二区日韩专区| 女沟厕偷窥piss小便| 精品一级| 欧亚日韩中文在线| 成人性交午夜免费片| 51一区二区三区| 传媒免费一区二区三区| 激情文学欧美| 亚洲欧洲第二视频在线观看色图| 久久偷拍人| 天天操女人| 中文字幕国产精品1区| 六月激情网| 久久久婷婷婷| 九九av| 婷婷丁香五月综合| 尹人大香蕉视频在线| 99久在线精品99re8热| 在线人人人人人人精品超| 国产偷拍自拍在线视频| 国产吞精a级片激情电影| 天天干天天狼在线视频| 国产综合操逼高清| 五月天激情小说| 女同在线视频一区| 天天夜夜久久| 玖玖超碰熟| 国产熟码AV| 激情在线青青操| 91日韩国产欧美亚洲另类精盘州至城都| 婷婷国产精品一区二区| 色激情综合网站| 亚欧免费观看视频| 女人一区| av久日| 天天干1区2区在线| 淫淫综合网| 国产日本一区二区三区蜜臀在线观看| 极品色| 日韩激情毛片一级久久久| 亚洲人妻在线一区| 天天插天天操| 91欧美偷拍| 蜜桃一区二区三区| 亚洲天堂久久| 国产无码成人无码| 午夜无码精品免费看性色| AV电影在线播放| 乱色视频中文字幕| 欧美综合色站| 97爱爱官网| 偷拍 欧美 日韩| 青椒国产97在线熟女| 96久久精品一二三区色欲| 亚洲高清无码免费观看视频| 亚洲日韩青青草色月| 成人精品水蜜桃久久久久久久| 精品无码少妇| 一区二区三区黄色片a| 狠狠激情综合狠狠操中文字幕| AV天天在线观看| 久久妇| 97精品| 免费A V在线播放| 熟女突然公开看18禁影片 | 大香蕉啪啪啪啪在线| 久久女女| 天天操夜夜操狠很操| 久久曰曰| 欧美九一精品久久久熟妇| 思思热一热婷婷热一热| 好好的日:com久久九九| 久久久久少妇| 色情综合网| 九九热在线精品视频| 97综合久第一页| 操逼日批| 婷婷激情四射| 久久久久久久久久久精| 日本欧美一区二区三区免费| 亚洲情色1区| 国产91美女视频| 黄色网址在线免费观看| 东北女人的毛片| 久草加勒比一区在线| www…国产操逼| 吉川爱美亚洲二区在线 | av在线免费一区二区| 97综合日韩| 99re9| 亚洲成人在线播放| 色欲天香天天综合网-成年人三级片网站-欧美乱妇狂野-日韩国产专区-久久久久久 | 日韩操逼性鲍| 色婷婷成人综合| 亚洲欧美人妻| www.夜夜操| 天美传媒精品久久视频| a在线视频免费观看| 日本久久999| 亚洲黄色a级片| 九一性生活免费视频| 国产成年精品高清在线观看91| 日韩精品人妻系列无码天堂| 家庭乱伦国产| 欧美在线综合| 日韩精品永久在线观看| 精品国产乱码久久久影院| 另类一区| 日韩大香蕉AV影片| 精品四五区| 国产精品96| 日少妇亚洲版| 国产精品呦一区二区三区| 91精品婷婷国产综合久久竹菊| 天堂俺去俺来也www久久婷婷| 中文97国产| 蜜桃视频成a人v在线| 五毛骚逼极品美女怕怕| 99ri视频| 日语五十路和六十路亚洲国产精品| 色呦呦、国产精品| 成 人片 黄色大片| 情色五月天就去干| 日本91白丝| 亚洲性爱成人| 日本性一区| 色色婷| 午夜精品久久一区二区| 欧美日动态视频| 国产情侣自拍在线播放| 五十路熟女人妻一区二区在线观看| 夫妻四区五区六区| 啪一啪免费视频| 青青草字幕AV| 亚洲男人天堂Av| 91精品无码久久久久久久| 中国的操老妇女| 九九Av| 国产福利视频精品视频| 亚洲AV永久无码精品成人调教| 91美女中出| 无码一区二区精品视频久久久春药 | 国产乱不卡| 欧美久久九九| 国产精品成人蜜臀AV在线| 熟妇熟女一区二区三区| 日韩精品大香蕉伊人在线| 亚洲成人综合在线| 亚欧成人综合影院| 91肉丝| 国产中文字幕在线观看| 久久天天躁日日躁狠狠躁| 91人妻Pr| 欧美色网| 久久在肏| 欧美一区二区三区成人性生活| 亚洲高潮少妇| 久久九色| 日本熟妇人妻中出视频| 老司机午夜精品视频| 国产精品日日摸天天碰| 亚洲的天堂网| 美女淫穴| 青青草在线视频人人想人人上| 亚欧国产无码精品在线| 欧美另类精品xxxx| AV在线性爱| 老司机福利青青草| 亚洲天天更新| 精品玖九九久| 亚洲一区中文字幕| 久久精品一区一起草| 狠狠夜色午夜久久综合在线| 国产天天骚| 久久精品小视频| 亚欧性爱在线无码| 天天精品| 免费A V在线| 日韩欧美一级特黄大片| 免费超碰97在线观看| 四虎精品永久在线播放| 91丝袜在线观看| 久久国产乱子伦精品免费女,网站| 欧美久久毛片基地| 欧亚乱色熟一区二区三四区| 亚洲s在线观看| 91精品国产综合久久久蜜臀| 国产女人高潮视频| 日韩AV片| 91大胆欧美| 久久精品视频久久久| 天美麻豆精品视频99| 国产玖玖| 久操B网| 九月AV| 久久久久免费少妇| 美女露胸露屁股| 亚洲国产欧美日韩精品一区二区三区,国产一区二区三区在线看片,欧美性猛交 XXX | 日韩欧美女优电影| 日韩亚洲美女一区久久| 天天综合91在线| 91网站18在线观看| 日本一天色道久久久精品视频| 99re在线观看| 中文字幕文字幕无码一区二区三区电影99 | 色综合中文字幕不卡| 少妇人妻精品| 国产吹潮女在线观看| 狠狠97| 97免费视频在线| 激情综合网亚洲| 欧美激情专区| 无码国产Av| 91色色色| 男人的天堂在线2| 欧美韩日精品资源| 欧美操逼录像国产黄色国产| 97超碰人人模人人拍人人| 日韩乱伦AⅤ| 在线性黄高清免费视频| 97WW精品| 欧美高潮| 国产激情视频一区区三区| 国产精品毛片?v一区二区三区 | 蜜臀久久久国产| 日韩欧美久久婷婷网站| a片自拍直播视频| 蜜桃视频成a人v在线| 凹凸视频特色日本特黄| 中文字幕少妇色 | 丁香六月婷| 国产999精品久久久久久| 另类av天堂| 亚洲欧美骚| 97干97色| 色一色综合网| 午夜精品久久久99| 97视频免费播放| 人人潮人人摸| 熟女丝袜视频| 色哟哟精品1精品2| 亚洲人体视频在线观看| 人妻少妇久久久| 素颜老阿姨乱情色| 亚洲欧美成人网站AAA| 成人性爱电影一区二区| 国产精品欧美激在线| 天天综合色图| 最新日韩黄片| 九九国产热| 2023天天操夜夜操| 亚洲精品丝袜-不卡成人免费…… 久久久久成人蜜桃精品 | 精品一啪| 久日91在线| 偷拍导航视频网站| 中文字幕123| 中文字幕-区二区三区四区视频中国| 91综合无码| 日韩性爱再线视频| 日本新免费二区三区| 人人么人人操| 九九久久久九九| 91亚洲欧美激情| JULIA一区二区三区在线播放| 嗯嗯啊啊好疼| 乱伦一区二区三区‘| 毛片视频白嫩| 欧美夜夜| 伊人综合色网| 青草伊人网| 999岛国大片| 91天天美女| 手机在线人成免费视频| 狠狠2050在线观看| 午夜精品五区| 九九九九精品一区| 国产A v无码专区| 中文字幕第23区| 26uuu最新| 中文字幕色AV| 在线视频日韩欧美国产| 欧美淫乱视频| 97人人模人人爽人人| 久肏视频字幕| 九九热精品在线| 免费男人的天堂| 99久久九九| 欧洲人妻视频| 亚洲AO在线| 亚洲综合在线第一页| 96精品在线| 久久久久久久强迫| 淫乱图区| 中文字幕av亚洲在线| 色哟哟av| 人妻少妇蜜桃视频欧美一区| 亚洲欧美清纯| 91丨国产丨白浆| 欧美性生活男人的天堂| 欧美一级专区免费大片| 日韩AV熟女乱伦| 超碰色97| 五十路熟女工口 | 日韩欧美国产高清视频| 后入综合久久| 大香蕉在线视频15| 一起草欧美| 亚洲色天堂九9| 国产精品久久久亚洲一区| 无码免费在线观看黄色片| 91AV天美在线视频| 久久久久成人蜜桃精品| 激情 欧美 亚洲 小说| 免看60秒涩涩视频| 天美av在线观看| 97精品熟女少妇一区| 2020中文字幕在线| 色九月婷婷| 欧美性爱日韩高清| 青青青草原| 性色高清在线| 99热99色| 亚洲国产91精品一区二区久久| 大香交| 日韩久久超碰色| 日本三级R| 久久久99免费| 高清无码人妻久久久一区二区三区aⅴ| 亚洲av热热色| 亚洲1区| 亚洲婷婷综合网| 国产成人天堂| 精品大久久| 超碰91在线| 青草草免费网站av| 欧美日韩在线小说 | 日本A级视频| 91蜜桃婷婷狠狠久久综合9色| 亚欧性爱无码| 久夜视频| 亚洲色性| 婷婷人妻激情| 精品人妻一区二区蜜桃视频| 天美传媒av在线| 色综合20p| 91黑丝美女| 久久天天躁日日躁狠狠躁| 97WW精品| 熟女丝袜视频| 超碰 97国产熟女| 人妻加勒比东京热| 看看小穴| 国产极品999| AV一二区| 精品97精品97| 牛牛久久国产精品视频一二三| 青青草十区九区爱夜| 青青草视频在线观看一区二区| 人妻精品综合中文字幕在线 | 蜜臀久久99精品久久久| 久久久久久97| 无遮挡又黄又刺激的视频| 草草草视频在线免费看| 欧美人人操人人插| 日韩性爱1级片视频| 日韩无码a片| 国产久久av| 国产精品久久久鸭无码的功能| 成人午夜视频免费播放| 五月婷在线| 久久久久久久久久久97| 99啪啪| 97在线资源| 视频国产欧美在线播放| 色欲Av人妻精品一区二| 91丨豆花丨熟女| 国岛片视频| 91丨九色丨国产打屁股| 亚洲男人天堂Av| 亚洲激情 欧美色图| 97操在线| 操久久久久| 久久久久久网址| 亚洲精品国产专区在线观看| www.国产高潮精品| 青青11操操操操操操操操| 天天享受天天看| 精品制服美女中文一区二区三区| 91天天综合日韩欧美| 日欧操屄| www.超碰在线| 美女淫穴| 久久亚洲日韩熟女精品| 乱伦一二三| www…国产操逼| 天天干2区3区| 日韩欧美中文字亚洲慕| 国产视频人人网| 在线可观看的黄色网址| 小草精彩毛片| 97久久天天综合色天天综合色电影| 天天操天天舔| 国产一级操B视频| 嗯啊免费视频| 久久↗↗| 欧美高清18A片| 高清无码国产亚洲| 狠综合网| 亚洲美女av无码| 久久99精品视频| 97超级欧美| 人妻久久一区二区三区| 日本Xx性爱| 97se综合网| 天天综合中文字幕 91| 国产熟女免费观看久久| 伊人久久亚洲中文字幕| 成人精品久久| 久久一区二区高清免费| 大香蕉 222| 蜜臀一区二区三区亚洲最新章节在线观看 - 高清蜜臀一区二区三区亚洲全集播放 | 婷婷五月天无码| 激情综合网激情综合| av在线资源| 亚洲高清男人天堂| 亚洲国产成人精品无码专区| 日韩性爱视频免费在线| 欧美色66| 97视频在线免费观看| 狠狠色综合网| 欧美淫乱视频| 中文字幕亚洲热播人妻| 神马午夜久久久| 懂色Av| 少妇一线天久久久久久| 欧美色图另类图片| 日本韩欧美在线播放a| 亚洲精品美女操逼| 囯戸精品高潮呻吟旡码| 久久综合乱子伦国产免费| 俞拍久久国应视频| 五月婷婷大香蕉| 欧美日韩人妻精品一区二区三区| 青娱乐国产精品| 亚洲综合贴图91| 免费看黄视频亚洲网站| 欧美 日韩 婷婷 五月| 欧美Aⅴ| 欧美日韩亚洲高清不卡一区二区三区| 婷婷婷婷婷婷久久久久| www四虎| 国产精品爆乳懂色蜜乳| 后入内射蜜桃臀| 三级日韩一区二区三区| 欧洲中文字幕| 中文字幕人成乱码熟女香港| 亚洲国产精品久久久男人的天堂| 欧美1区二区三区公司| 麻豆精品天美| 中文字幕日韩人妻视频一区二区三区| 91 综合 色| 黑人精品成人一区二区三区 | 亚洲国产尤物yw在线观看| 2026国产精品视频| 91操人| 99超碰碰| 亚洲最大黄网| 国产日韩欧美中文在线播放| 中文久久96| 国产AV久久久蜜爱影集| 综合色好色| AV丝袜少妇| 色综合久久88色综合久久天天| www.成人无码| 久久久久久久久久久六六| 欧美 精品国产制服第一页| 日韩电影天堂视频二区三区| 亚洲九月丁香| 日韩小电影| 9精品在线| 国产粉嫩出水在线播放| 亚洲在饯| 天天影视射综合网| av凤凰久久久| 综合操逼| 亚洲 欧美 色图| 骚逼一区二区| 麻豆国产免费影片| 亚洲视频中文一区| 插入粉嫩少妇视频| 爽爽歪在线视频| 韩国黄片aaaa| 欧美加勒比| 欧美青青视频| 日韩精品一二三四| 中国国产精品一区视频| 欧美亚州综合网图片| 天天爽夜夜欢视| 亚洲熟女中文字幕在线| 亚洲日韩人妻中文字幕一区| 日韩久草| 青青色综合| www色色com| 日本三级一区二区 在线| 极品少妇久久久| 啊啊啊好舒服视频在线观看| 99色在线| 性色av网站| 色色色日本| 日本不卡一二区| 91高潮喷水美女| 中文字幕av色| 久久久婷婷婷| 亚洲五码一区二区三区| 韩国免费播放一级毛片| 综合网亚洲在线| 涩涩久久精品| 自拍丝袜美腿人妻| 国产少妇肉丝在线观看| 人人摸人人摸人人干| JIZZJIZZ亚洲女人被躁| 九九九九精品视频| 91老熟女91老女人| 亚洲污污网站| 国产熟妇一区二区| 亚洲AV乱码专区国产噜噜亚洲 | 亚欧美综合网。| 麻豆乱码久久精| 极品五月天噜噜| 九九色逼| 国产尹人在线视频免费| 午夜120视频在线观看| 日本韩国国产精品一区| 午夜爽爽爽| 欧美色九九| 一二三四区电影| 九九九草| 亚洲色图 综合| 欧美国产一区二区三区麻豆传媒| 精品免费1| 亚洲欧美激情另类色图| 久操婷婷| 激情五月婷婷| 人人爱操| 九月丁香| 欧美99| 五月天婷婷久久| 亚洲色综合| 日本99热| 亚洲精品一区中文字幕乱码| 91婷婷| 五月婷婷无码| 色婷婷丁香五月| 伊人久久婷婷| 97色碰| 一区二区三区精品黑丝白丝酒店对鸡 | 91热热色| 熟女熟妇一区二区三四区| 美女爽到高潮91| 欧美韩日精品99综合| 欧美亚州综合网图片| 久久三区四区| 夜夜爽夜夜爽| 久久精品国产欧美日韩亚洲欧美日韩中文久久国产一区 | 天天影视综合网欧美精品| 久操大香蕉手机视频在线看| 爱爱60秒免费视频| 超碰激情808| 夜夜嗷嗷一区二区| 亚洲日韩欧美一区二区| 久久久91福利姬| 性感美女91影视| 久久久久久九九九| CCYY草草影院地址入口| 99国产精品视频尤物| 国产www色在线观看| 无套内射性感少妇视频| 久久久久久国产精品| 男人天堂.AB| 成人十八禁日韩欧美一二三| 色97国产69香蕉| 92一区二区| 变态乱伦伪娘灌肠一区二区| 伊人黄色视频免费观看| 东京热激情视频一二三区| 天天综合欧美综合| 97久久国产精品| 美女久久久久久久久久久| 日本伦乱九九九综合| 中文字幕一区电影在线观看| 涩五月婷婷| 91夜夜蜜桃臀1区2区3区| 台湾佬中文娱乐网久久久久久久久久com | 99热国产| 天天看天天日天天操| 久久成人午夜精品影院| www.狠狠| 97色妞| 黑人嘿嘿嘿超爽免费视频| www久| 亚洲色性| 天堂亚洲精品久久老牛| 色优久久| 国产视频人人网| 五月丁香激情啪啪| 亚洲欧美黄| 99日精品欧美国产| 亚洲本色精品一区二区久久| 婷婷AV一区二区三区| 呻吟 欧美 日本 中出| 日操粉逼逼| 台湾佬中文娱乐网久久久久久久久久com | 一直超碰| 久久国产成人精品国产成人亚洲| 色哟哟国产精品免费网址| 男人的天堂Va| 78久久久| 国产亚洲性生活视频播放| 精品无av| 精品在线78| 色汉综合| 亚洲色性情三级| 国产综合在线视频网站| 天天激清| 国产情色在线| 翔田千里av一区二区三区| 91精品操美女| 亚洲超碰在线| 91少妇高潮| 国产不卡免费在线视频| 日本中文字幕一区| 啪啪视频免费在线观看| 九九亚洲色在线观看| 丰满人妻av一区二区三区| 九九九九九精品| 网页导航五月天免费一二三区| 澳门成人网站久国产日韩| 亚洲Av诱惑| 91精品久久久久久77777| 久久人妻少妇| 18禁精品网站在线看| 中美日韩毛片| 五月婷亚洲精品天堂| 加勒比大香蕉视频在线| 亚洲精品乱码久久久久久蜜桃麻豆| 日本日逼高清| 一区| 1769国内精品视频| 第二页中文字幕| 囯产精品久久久久久久久久梁医生| 色噜噜综合在线| 中文字幕乱亚洲美女精品一区| 超碰免费人人| 97超碰精品图片| 超碰AV在线| 欧洲人妻视频| 东京热亚洲一区二区| 青青青青青手机视频| 99热9| 久久区| 夜夜操老骚逼视频网站| 国产一区二区三区高清视频| 96AV久久久| 午夜操逼不卡| 亚洲综合夜色| 黄片在线免费在线观看| 97操97干| 久久草草欧美精品| 女性91网站| 殴美日韩m| 日韩乱伦AⅤ| 久久机热| 日产狠狠干| 最新日本中文字幕| 热久日综合| 在线无码操| 国产精品丝袜在线| 丝袜熟女2P| 亚川综合视频| 久久久精| 蜜臀久久一区二区| 韩三级a视频在线观看| 久久久久久久久久久久久久久久9| 日韩人妻播放| 97色操| 久久综合精品一区二区三区| 琪琪精品免费一区二区三区 | 自拍第一页| 亚洲黑丝在线| 第四色奇米影视777| 另类欧美| 91超碰人人| 乱伦1色页| www欧美91| 人人妻人人色| 久久丁香五月婷婷| 亚洲av综合伊人久久| 黑人粗大V S日韩女优视频| 色性欧美| 美女极品一区二区三区| 亚洲综合网91| 综合色拍| 91亚洲人电影| 性色av蜜臀av色欲aV| 中国特猛少妇色xxx| 熟女网站最新| 色哟哟的毛片| 国产精品婬乱一级毛片彝族| 国产精品诱惑| 精彩久久中文| GVH-003 母子姦 青木玲-麻豆视频,麻豆视传媒短视频网站入口,麻豆视传媒官网直 | 国产免费久久精品99re韩国| 丁香九月激情啪| 国产三级在线现体验区| 国产激情在线| 亚洲欧洲第二视频在线观看色图| 五月激情综合网| 操逼操逼逼操操逼91| 国产呦精品系列在线观看| 2020中文字幕在线| 日韩激情视频| 999在线电影香蕉| 亚洲黄网在哪免费看| 日本欧美韩国国产在线| 国产精品诱惑| 日韩无码服务区| 日韩噜噜69| 91国产丝袜足交精品视频| 天堂种子在线www网资源| 欧美性爱日韩高清| 久草成人| 揉揉揉夜夜| 久久噜| 热久日综合| 玖玖综合色| 蜜臀久久久久久999| www…国产操逼| 国产91啪| 国产精品原创巨作?v网站| 激情文学88| 日本加勒比无码专区| 亚洲精品乱码久久久久久蜜桃麻豆| 天天综合网1| 干b在线性社区| 7月婷婷综合| 99热综合在线| 99国产人成精品| 91一区二区| 熟妇最新先锋一二三区| 性站| 亚洲一二三四区机械| 熟妇熟女视频一区二区三区| 乱老女人一区二区视频| 国产小u女在线观看| 日本在线不卡v二区| 精品一区二区综合熟妇| 亚洲天堂7777| 手机在线人成免费视频| 操逼啊啊啊91| 欧美性爱视频免费一区一A| av无码av无码专区| 色欲蜜臀AV| 超碰成人最新最好看| 亚洲成人一区二区精品| 操逼片中文| 中文自拍欧美影视| 蜜桃av综合网发布| 91精品黄在线观看| 伊人91| 少妇 综合| 国产suv精品一区二区四| 精品无吗久久| 综合av影片| 色欧美色交综合| 亚洲视频精选| WWW.操逼.COM|