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

歲月流轉,往昔空明

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>
            亚洲美女区一区| 久久激情网站| 久久综合狠狠| 欧美资源在线| 久久亚洲精选| 亚洲第一久久影院| 蜜臀va亚洲va欧美va天堂| 久久亚洲综合| 欧美黄色成人网| 艳女tv在线观看国产一区| 亚洲无线视频| 久久久国产一区二区| 亚洲激情在线视频| 日韩视频在线免费| 免费在线亚洲| 校园激情久久| 欧美成人精品福利| 国产精品麻豆欧美日韩ww| 韩国一区二区三区在线观看 | 亚洲欧美日韩成人高清在线一区| 妖精视频成人观看www| 欧美一区二区在线播放| 美女网站在线免费欧美精品| 国产精品va在线播放| 激情久久一区| 亚洲午夜精品视频| 欧美.www| 午夜欧美大尺度福利影院在线看| 欧美大色视频| 黄色一区二区三区| 欧美一区二区视频97| 亚洲九九九在线观看| 久久综合九色综合欧美狠狠| 国产精品蜜臀在线观看| 亚洲美女中文字幕| 亚洲精品一区二区三区婷婷月| 亚洲一区二区在线播放| 欧美成人免费在线视频| 亚洲先锋成人| 欧美日韩国产欧美日美国产精品| 国产亚洲激情在线| 亚洲女同精品视频| 亚洲国产精品成人综合色在线婷婷| 亚洲欧美一区二区在线观看| 欧美日韩国产区| 日韩视频在线观看国产| 欧美顶级少妇做爰| 久久电影一区| 国产欧美午夜| 久久国产精品黑丝| 亚洲天堂久久| 欧美视频一区| 亚洲一区久久| 在线天堂一区av电影| 欧美日韩国产一级片| 日韩一区二区福利| 亚洲精品男同| 欧美日韩福利在线观看| 夜夜夜久久久| 久久久成人网| 久久成人18免费观看| 国产夜色精品一区二区av| 欧美在线视频观看| 亚洲欧洲av一区二区三区久久| 国产精品看片资源| 久久se精品一区精品二区| 午夜日韩在线观看| 国产一区日韩二区欧美三区| 久久久免费观看视频| 久久久久久久一区| 亚洲激情在线播放| 一区二区三区国产盗摄| 亚洲女人av| 久久伊人精品天天| 欧美诱惑福利视频| 激情丁香综合| 欧美不卡视频一区发布| 免费成人av资源网| 一本色道久久88综合日韩精品| 日韩视频久久| 国产一区二区三区四区三区四| 嫩模写真一区二区三区三州| 欧美成人综合在线| 午夜免费久久久久| 久久久久久久久久久成人| 亚洲精品一区二区在线观看| 99这里只有精品| 韩国免费一区| 亚洲免费播放| 国内精品伊人久久久久av一坑| 亚洲国产精品毛片| 国产精品视频yy9099| 欧美69wwwcom| 国产精品一区二区三区成人| 欧美.日韩.国产.一区.二区| 欧美日韩中文另类| 欧美成人免费全部| 国产精品免费福利| 亚洲国产成人精品久久久国产成人一区| 国产精品盗摄久久久| 欧美插天视频在线播放| 国产精品v欧美精品v日韩| 亚洲福利视频一区| 国内精品免费在线观看| 在线亚洲精品| 亚洲美女视频网| 久久久久中文| 久久av一区| 国产精品乱码妇女bbbb| 亚洲黄色尤物视频| 今天的高清视频免费播放成人 | 91久久在线| 午夜精品久久久久久久男人的天堂| 亚洲激情专区| 久久久久国产精品一区二区| 性欧美长视频| 国产精品h在线观看| 亚洲欧洲美洲综合色网| 亚洲大胆视频| 欧美在线3区| 久久精品免费看| 国产麻豆午夜三级精品| 在线视频亚洲一区| 亚洲一区二区三区午夜| 欧美乱人伦中文字幕在线| 欧美激情视频免费观看| 一区二区在线观看av| 久久精品亚洲一区二区| 久久精品视频在线观看| 国产欧美精品| 91久久中文| 国产精品99久久久久久宅男| 亚洲免费激情| 模特精品裸拍一区| 欧美激情精品久久久久久久变态| 国产一区二区高清视频| 欧美一区二区高清| 久久精品成人一区二区三区| 国产欧美精品一区二区三区介绍 | 久久免费黄色| 伊人久久av导航| 免费久久99精品国产| 亚洲国产精品电影| 99精品免费视频| 欧美午夜精品久久久久久超碰| 亚洲老板91色精品久久| 亚洲午夜av在线| 国产精品久久久久久五月尺| 亚洲欧美国产精品桃花| 久久人人97超碰国产公开结果| 黄色一区二区三区| 欧美风情在线| 亚洲午夜精品网| 久久综合图片| 夜夜精品视频| 国产午夜亚洲精品不卡| 裸体丰满少妇做受久久99精品| 亚洲欧洲美洲综合色网| 午夜精品久久久| 亚洲第一伊人| 国产精品国产三级国产aⅴ无密码| 亚洲男人第一av网站| 麻豆精品在线播放| 亚洲一级二级| 一区二区亚洲精品| 欧美日韩a区| 久久疯狂做爰流白浆xx| 亚洲高清毛片| 欧美一区深夜视频| 亚洲人妖在线| 国产区日韩欧美| 欧美精品久久久久久久久久| 亚洲综合久久久久| 亚洲欧洲日韩在线| 久久久噜噜噜久久中文字幕色伊伊 | 久久国产精品99国产精| 91久久黄色| 国产欧美一区视频| 欧美激情bt| 久久精品人人做人人综合| 99在线|亚洲一区二区| 欧美成人综合在线| 久久国产精品72免费观看| 一区二区三区蜜桃网| 亚洲成人在线免费| 国产日韩精品久久久| 欧美日韩在线不卡| 欧美大胆人体视频| 久久一二三四| 久久精品视频一| 先锋影音网一区二区| 99精品免费网| 最新国产拍偷乱拍精品| 蜜桃av一区| 久久久精彩视频| 欧美一区二区免费| 亚洲欧美成人一区二区三区| 日韩视频在线观看国产| 国产精品国产三级国产专区53 | 久久综合九九|