<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                廣義而言,語言是一套采用共同符號、表達方式與處理規則。就編程語言而言,編程語言也是特定規則的符號,用來傳達特定的信息,自然語言是人與人之間溝通的渠道,而編程語言則是機器之間,人與機器之間的溝通渠道。人有非常復雜的語言能力,語言本身也在不斷的進化,人之間能夠理解復雜的語言規則,而計算機并沒有這么復雜的系統,它們只能接受指令執行操作,編程語言則是機器和人(準確說是程序員)之間的橋梁,編程語言的作用就是將語言的特定符號和處理規則進行翻譯,由編程語言來處理這些規則, 目前有非常多的編程語言,不管是靜態語言還是動態語言都有固定的工作需要做:將代碼編譯為目標指令,而編譯過程就是根據語言的語法規則來進行翻譯,我們可以選擇手動對代碼進行解析,但這是一個非常枯燥而容易出錯的工作,尤其是對于一個完備的編程語言而言,由此就出現了像lex/yacc這類的編譯器生成器。 編程語言的編譯器(compiler)或解釋器(interpreter)一般包括兩大部分: 1. 讀取源程序,并處理語言結構。 1. 處理語言結構并生成目標程序。 Lex和Yacc可以解決第一個問題。第一個部分也可以分為兩個部分: 1. 將代碼切分為一個個的標記(token)。 1. 處理程序的層級結構(hierarchical structure)。 很多編程語言都使用lex/yacc或他們的變體(flex/bison)來作為語言的詞法語法分析生成器,比如PHP、Ruby、Python以及MySQL的SQL語言實現。 Lex和Yacc是Unix下的兩個文本處理工具, 主要用于編寫編譯器, 也可以做其他用途。 - Lex(詞法分析生成器:A Lexical Analyzer Generator)。 - Yacc(Yet Another Compiler-Compiler) ### Lex/Flex Lex讀取詞法規則文件,生成詞法分析器。目前通常使用Flex以及Bison來完成同樣的工作, Flex和lex之間并不兼容,Bison則是兼容Yacc的實現。 詞法規則文件一般以.l作為擴展名,flex文件由三個部分組成,三部分之間用%%分割: 定義段 %% 規則段 %% 用戶代碼段 例如以下一個用于統計文件字符、詞以及行數的例子: %option noyywrap %{ int chars = 0; int words = 0; int lines = 0; %} ? %% [a-zA-Z]+ { words++; chars += strlen(yytext); } \n { chars++; lines++; } . { chars++; } %% ? main(int argc, char **argv) { if(argc > 1) { if(!(yyin = fopen(argv[1], "r"))) { perror(argv[1]); return (1); } yylex(); printf("%8d%8d%8d\n", lines, words, chars); } } 該解釋器讀取文件內容, 根據規則段定義的規則進行處理, 規則后面大括號中包含的是動作, 也就是匹配到該規則程序執行的動作,這個例子中的匹配動作時記錄下文件的字符,詞以及行數信息并打印出來。其中的規則使用正則表達式描述。 回到PHP的實現,PHP以前使用的是flex,[后來](http://blog.somabo.de/2008/02/php-on-re2c.html)PHP的詞法解析改為使用[re2c](http://re2c.org/),$PHP_SRC/Zend/zend_language_scanner.l 文件是re2c的規則文件, 所以如果修改該規則文件需要安裝re2c才能重新編譯。 ### Yacc/Bison > PHP在后續的版本中[可能會使用Lemon作為語法分析器](http://wiki.php.net/rfc/lemon), [Lemon](http://www.sqlite.org/src/doc/trunk/doc/lemon.html)是SQLite作者為SQLite中SQL所編寫的詞法分析器。 Lemon具有線程安全以及可重入等特點,也能提供更直觀的錯誤提示信息。 Bison和Flex類似,也是使用%%作為分界不過Bison接受的是標記(token)序列,根據定義的語法規則,來執行一些動作,Bison使用巴科斯范式([BNF](http://baike.baidu.com/view/1137652.htm))來描述語法。 下面以php中echo語句的編譯為例:echo可以接受多個參數,這幾個參數之間可以使用逗號分隔,在PHP的語法規則如下: echo_expr_list: echo_expr_list ',' expr { zend_do_echo(&$3 TSRMLS_CC); } | expr { zend_do_echo(&$1 TSRMLS_CC); } ; 其中echo_expr_list規則為一個遞歸規則,這樣就允許接受多個表達式作為參數。在上例中當匹配到echo時會執行zend_do_echo函數,函數中的參數可能看起來比較奇怪, 其中的$3 表示前面規則的第三個定義,也就是expr這個表達式的值,zend_do_echo函數則根據表達式的信息編譯opcode,其他的語法規則也類似。這和C語言或者Java的編譯器類似,不過GCC等編譯器時將代碼編譯為機器碼,Java編譯器將代碼編譯為字節碼。 > 更多關于lex/yacc的內容請參考[Yacc 與Lex 快速入門](http://www.ibm.com/developerworks/cn/linux/sdk/lex/index.html) 下面將介紹PHP中的opcode。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看