青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

歲月流轉,往昔空明

C++博客 首頁 新隨筆 聯系 聚合 管理
  118 Posts :: 3 Stories :: 413 Comments :: 0 Trackbacks

Exodus:語法分析(一)

在一個魔法世界里,你是一個會魔法的法師。我的意思是,作為一個法師,你什么都會了,也什么都有了,施法材料,法袍,魔杖,法術書。甚至你連成功后的慶祝動作都想好了。你以為你會“魔法”了。只可惜,這里還缺少了一樣東西,那就是,魔法的口訣。

而在這里,我們什么都有了。用來分析的Token,語法樹到OP CODE的翻譯,虛擬機,什么都有了。但是我們還是缺一樣口訣,那就是,如何從Token到語法樹的口訣。

在我們進行詞法分析的時候,遵從的是Spirit這本頗有難度的《圣經》。不過,我們只瀏覽了如《使徒行傳》般流暢而松散的Spirit.Lex。在這里,我們依然沿用Spirit,這是我們編譯器前端的原旨。不過現在,我們要講解的是環環相扣、蕩氣回腸的《Exodus》——Spirit.Qi。

嘛,這段神叨叨的引子,只是為了強調語法分析的地位而已。在繼續閱讀本章之前,需要你看的明白BNF。有關于BNF方面的信息,你可以在任何一本講述編譯原理的書籍上找到。

仍然是以一個簡單的A+B為例。由于我們已經有了詞法“literal_int”和“literal_add”,因此A+B這樣一個表達式,用BNF來表示,就是:

Expr ::= literal_int literal_add literal_int

在Spirit.Qi里,語法的表達也類似于BNF的形式。只要你設計出語言的BNF,就很容易的翻譯成Spirit.Qi支持的語法定義。我們這里,就可以寫成:

template <typename IteratorT>

struct binary_expression: qi::grammar<IteratorT>{

    template <typename TokenDefT> binary_expression(const TokenDefT& tok): binary_expression::base_type(start)

    {

        start = (  literal_int >> literal_op >> literal_int );

        literal_int = tok.littok_int;

        literal_op = tok.optok_add;

    }

    qi::rule<IteratorT> literal_op, literal_int, start;

};

在Spirit.Qi中,一個Rule就等于EBNF的一個非終結符。一個Grammar相當于一組Rule的集合,并且可以擁有一個或者多個的起始Rule作為入口。本質上我們可以把Grammar看成一個Rule(準確的說,是Parser,若要了解相關概念,請參閱Spirit的自定義Parser部分)。等號用于連接非終結符(Rule)及其推導式;使用“>>”(輸入流/右位移運算符)連接語法要素之間的連接符號。更多的符號請參閱Spirit.Qi文檔。

至于為什么不將Rule合并到一起,而提供一個Grammar的中間層,主要有兩方面的考慮,一個是提供了一個抽象層,例如我們可以把Statement和Expression分開來寫,使得層次上更加清晰;還有一個方面在于節省編譯時間。因為Spirit使用了大量的源編程技術,如果把所有的Rule合并到一起編譯,會占用大量的編譯時間。在使用了Grammar之后,可以運用C++編譯器在一個編譯過程里對相同的模板特化只進行一次的Tricks,大大節省了編譯時間。

在上一章里,咱們最后還留了一個問題,就是空白符號的處理方法。這里,我們將于空白符號一起,來走一下Spirit的語法和詞法分析的流程。

首先,我們建立好詞法,將源代碼字符流組織成更加容易被語法分析識別的Token流。

template <typename BaseLexerT>

struct sasl_tokens : public boost::spirit::lex::lexer< BaseLexerT > {

    sasl_tokens(){

        this->self.add_pattern("SPACE", "[ \\t\\v\\f]+");

 

        littok_int = "[0-9]+";

        optok_add = "[\\+]");

        whitetok_space = "{SPACE}";

       

        this->self = littok_int | optok_add;

        this->self("SKIPPED") = whitetok_space;

    }

    boost::spirit::lex::token_def<>

        littok_int, optok_add, whitetok_space;

};

這里,我們將詞法分為兩組,對語法分析有效的Tokens組和無效的空白組,空白組用”Skipped”作為狀態以示區別。這里我們需要說明一下,Spirit.LEX的詞法分析的“狀態”與詞法分析工具“Lex/Flex”中的狀態概念是相同的。

在Lex類的詞法分析工具里,有一個專門的狀態。一般而言,這些狀態都用字符串表示。Lex的默認是“INITIAL”,Spirit.Lex的默認狀態是空(如果我沒記錯的話)。在指定詞法的時候,可以告訴詞法分析器,此文法在什么狀態下,這條詞法才發揮作用。詞法分析器的狀態可以由外部程序自由指定。

我們將表示空白的詞法都放在Skipped狀態下后,我們就可以對每個單詞,用Skipped狀態去匹配。如果發現是在Skipped狀態下匹配成功的單詞,在進入語法分析前就可以先丟棄,進而實現過濾空白符的目的。

考慮表達式“55_+38”(‘_’代表空格),在分析成Token流之后,會變成以下的形式:

State

INITIAL

SKIPPED

INITIAL

INITIAL

Token

Literal_int

Literal_ws

Literal_op

Literal_int

Literal

55

_

+

38

然后撰寫我們的Grammar。由于我們需要指定Skipper來跳過我們不需要的Token,因此我們的Grammar在模板參數里,也要加入這個Skipper的類型參數。

template <typename IteratorT, typename LexerT>

struct binary_expression:

qi::grammar<IteratorT, qi::in_state_skipper<LexerT> >

{

    template <typename TokenDefT>

binary_expression(const TokenDefT& tok):

    binary_expression::base_type(start)

    {

        start = (  literal_int >> literal_op >> literal_int );

        literal_int = tok.littok_int;

        literal_op = tok.optok_add;

    }

boost::spirit::qi::in_state_skipper<LexerT> skipper_type;

    qi::rule<IteratorT, skipper_type> literal_op, literal_int, start;

};

并在咱們的驅動代碼里面,這樣寫:

typedef sasl_tokenizer::iterator_type sasl_token_iterator;

typedef sasl_tokenizer::lexer_def sasl_skipper;

 

sasl_tokenizer sasl_tok;

binary_expression<sasl_token_iterator, sasl_skipper> g( sasl_tok );

 

lex::tokenize_and_phrase_parse(

first,

last,

sasl_tok,

g, qi::in_state("SKIPPED")[sasl_tok.self]

);

喏,看到了指定skipper的代碼了不?這就提示parser,遇到了skipped狀態解析出來的token,就自己吃了吧,不要拿去匹配了。這樣就達到了過濾掉空白符的目的。

不過呢,盡管我們parse通過了,但是仍然沒有提取出我們想要的信息來。到目前為止,我們還沒能讓parser構造出咱們之前手工構建并傳遞給Code Generator的語法樹來。這仍然是橫亙在出埃及的我們面前的紅海。

下一次,我們將仍然相信Spirit這本Bible,相信它給我們的一章叫 “Semantic Action”的啟示錄。它將告訴我們,如何把Parser分析出的結果轉化為我們要的語法樹,以引領我們走向流OP CODE之地。

God bless programmers and p2p sites except gfw’s developers and Cisco. Amen

posted on 2009-12-15 23:35 空明流轉 閱讀(2384) 評論(1)  編輯 收藏 引用

評論

# re: 實用編譯器構建指南(四) 2010-01-07 11:09 正心
It looks like you've read so many God's books! :)~~~  回復  更多評論
  

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            午夜精品久久久久久久99樱桃| 亚洲乱码国产乱码精品精天堂 | 午夜精品视频一区| 一本色道久久综合亚洲精品高清| 欧美日韩精品在线视频| 亚洲午夜精品久久久久久app| 亚洲视频欧美视频| 国产亚洲欧洲一区高清在线观看 | 久久天天躁狠狠躁夜夜爽蜜月| 久久精品国内一区二区三区| 亚洲国产成人久久| 夜夜爽夜夜爽精品视频| 国产手机视频精品| 亚洲第一黄色| 国产精品久久久久久影视| 久久精品一区四区| 欧美美女福利视频| 欧美中文字幕在线| 欧美国产日韩一区二区在线观看 | 海角社区69精品视频| 亚洲第一天堂av| 国产精品看片你懂得| 美日韩精品免费观看视频| 欧美人与性禽动交情品 | 亚洲激情社区| 亚洲欧美日韩国产一区二区三区| 一区二区亚洲精品国产| 日韩网站在线观看| 伊人激情综合| 亚洲在线一区二区| 亚洲精选久久| 欧美在线短视频| 亚洲天堂成人| 欧美成人精品在线观看| 久久av一区二区三区| 欧美日韩视频在线一区二区| 欧美成人69av| 国产一区二区三区丝袜| 亚洲视频网在线直播| 亚洲国产日韩一区| 久久久国产成人精品| 欧美在线播放视频| 国产精品v片在线观看不卡| 亚洲第一在线视频| 黄色国产精品一区二区三区| 亚洲尤物在线| 亚洲尤物影院| 欧美日韩日本网| 亚洲人成网站色ww在线 | 欧美成人高清| 黄色一区二区三区| 香蕉久久夜色| 欧美在线观看视频一区二区三区| 欧美欧美天天天天操| 欧美va天堂| 亚洲国产毛片完整版| 久久精品九九| 裸体女人亚洲精品一区| 国产在线拍偷自揄拍精品| 亚洲一品av免费观看| 亚洲永久字幕| 国产精品你懂的在线欣赏| 一区二区欧美视频| 午夜精品久久久久久久| 国产精品大片免费观看| 亚洲网站啪啪| 欧美影院成年免费版| 国产女主播一区二区三区| 亚洲欧美日韩一区二区三区在线| 欧美一区二区在线看| 国产女主播视频一区二区| 欧美一级视频精品观看| 久久久视频精品| 亚洲大胆女人| 欧美精品电影在线| 亚洲午夜av在线| 久久久久久久综合狠狠综合| 极品av少妇一区二区| 免费亚洲电影在线观看| 亚洲级视频在线观看免费1级| 亚洲毛片在线观看.| 欧美三日本三级少妇三2023| 亚洲一区二区三区久久| 久久一本综合频道| 亚洲人成欧美中文字幕| 国产精品av一区二区| 欧美一级播放| 亚洲激情视频在线观看| 亚洲欧美日韩天堂| 影院欧美亚洲| 欧美性猛交xxxx乱大交蜜桃| 亚欧成人在线| 亚洲欧洲精品一区| 欧美一区观看| 日韩小视频在线观看| 国产精品欧美精品| 久久影院午夜论| 一区二区三区成人精品| 美玉足脚交一区二区三区图片| 日韩一区二区精品葵司在线| 国产欧美韩日| 欧美国产先锋| 亚洲欧美激情一区二区| 亚洲国产成人精品女人久久久| 亚洲欧美日韩区| 亚洲精品美女在线| 国产一区二区日韩精品欧美精品| 欧美顶级艳妇交换群宴| 午夜在线一区| 一区二区国产日产| 亚洲国产天堂久久综合| 久久精品免费| 亚洲男人的天堂在线观看| 亚洲高清av在线| 国产午夜精品久久久| 欧美三区在线视频| 欧美激情中文字幕一区二区| 久久狠狠亚洲综合| 亚洲欧美另类国产| 一本大道久久a久久精二百| 欧美黑人在线观看| 亚洲尤物视频网| 亚洲视频在线视频| 亚洲激情自拍| 永久久久久久| 国内自拍视频一区二区三区| 国产精品久久久久久久久久三级 | 国产在线精品二区| 国产乱码精品一区二区三区忘忧草 | 亚洲精品社区| 欧美高清在线一区| 蜜臀久久99精品久久久久久9| 午夜在线观看欧美| 亚洲一区中文| 亚洲欧美日本国产有色| 亚洲网友自拍| 亚洲夜晚福利在线观看| 99亚洲精品| 一区二区三区国产| 在线视频你懂得一区| 亚洲素人一区二区| 亚洲一区二区成人| 亚洲欧美电影在线观看| 亚洲综合二区| 小黄鸭精品aⅴ导航网站入口| 亚洲免费网址| 久久国产精品久久久| 久久九九国产精品怡红院| 久久网站免费| 欧美激情一区二区三区成人| 亚洲国产成人在线视频| 91久久精品日日躁夜夜躁欧美| 亚洲国产精彩中文乱码av在线播放| 欧美国产精品中文字幕| 亚洲肉体裸体xxxx137| 一区二区日韩| 性久久久久久久| 久久一区激情| 欧美猛交免费看| 国产精品日韩久久久| 黄色亚洲网站| 99re在线精品| 欧美一区二区三区免费观看视频| 久久国产66| 亚洲高清精品中出| 亚洲一区在线视频| 久久综合999| 国产精品国产馆在线真实露脸| 国产视频欧美| 日韩视频在线观看| 欧美一区二区大片| 欧美丰满高潮xxxx喷水动漫| 亚洲精品视频在线播放| 午夜老司机精品| 欧美国产亚洲视频| 国产日韩在线一区二区三区| 亚洲国产另类久久久精品极度 | 国内精品久久久久影院优| 亚洲欧洲在线免费| 欧美一区二区三区在线播放| 欧美成人午夜激情在线| 亚洲一二三区视频在线观看| 久久精品人人| 国产精品久久91| 亚洲国产欧美日韩另类综合| 亚洲欧美在线一区二区| 欧美国产另类| 性久久久久久久久| 欧美精品三级日韩久久| 黄色精品网站| 欧美在线播放一区二区| 亚洲麻豆一区| 免费观看成人www动漫视频| 国产女主播一区二区三区| 99亚洲视频| 亚洲激情国产精品| 久久综合给合久久狠狠色| 亚洲午夜久久久久久久久电影院| 亚洲女人天堂av| 欧美日韩在线看|