<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    迷途書童

    敏感、勤學(xué)、多思
    隨筆 - 77, 文章 - 4, 評(píng)論 - 86, 引用 - 0
    數(shù)據(jù)加載中……

    從lex&yacc說(shuō)到編譯器(3.范式文法)

    從這一節(jié)開始,我們就算進(jìn)入編譯器構(gòu)造的正題了.不得不說(shuō),前面的詞法掃描器在整個(gè)編譯器部分只是個(gè)很小很小的組成,而這兩節(jié)講述的語(yǔ)言構(gòu)造器才能真正為我們的編譯工作起到重要的作用.這些東西相信大家在大學(xué)的編譯原理的課程已經(jīng)學(xué)了不少,那么本文我也只是大致地帶過(guò),讓大家回憶起大學(xué)的知識(shí),重要的yacc使用技巧等等,我將在后面的內(nèi)容講出.

    3.1

    exp -> exp op exp | (exp) | number

    op -> + | - | *

    這里就是一個(gè)定義的帶有加法,減法,乘法的簡(jiǎn)單整數(shù)算術(shù)表達(dá)式的文法.其中粗體表示的是終結(jié)符號(hào),也就是不能有產(chǎn)生式生成的符號(hào).而exp,op就是非終結(jié)符,它們都是由一個(gè)”->”符號(hào)來(lái)產(chǎn)生的.

    比如100 + 222 *123123 –(888+11)就是符合上述文法的具體的表達(dá)式.

    注意,在文法定義中,是可以遞歸的.所以exp產(chǎn)生式右邊的式子中可以再次出現(xiàn)exp.

    這里的|和正則表達(dá)式一樣,表示的選擇的意思,也就是說(shuō),exp可以是exp op exp或者(exp)再或者number.

    下面讓我們看看<<編譯原理及實(shí)踐>>書中的一個(gè)關(guān)于BNF文法的介紹.

    比如說(shuō)我們有個(gè)數(shù)學(xué)表達(dá)式(34-3)*42,然后我們來(lái)看看上面的exp文法怎么來(lái)推導(dǎo)識(shí)別它.

    (1) exp => exp op exp?????????????? [exp ->exp op exp]

    (2)???? => exp op number??????????? [exp ->number??? ]

    (3)???? => exp * number???????????? [op -> *???????? ]

    (4)???? => (exp) * number?????????? [exp ->(exp)???? ]

    (5)???? => (exp op exp) * number??? [exp ->exp op exp]

    (6)???? => (exp op number)* number? [exp -> number?? ]

    (7)???? => (exp – number) * number [op -> -???????? ]

    (8)???? => (number–number)* number [exp -> number?? ]

    最終,exp里面全部的非終結(jié)符號(hào)全部變成了終結(jié)符號(hào).那么推導(dǎo)完成.

    這種推導(dǎo)十分像我們?cè)陔x散數(shù)學(xué)中講到的命題推理.其實(shí)形式語(yǔ)言的推導(dǎo)的數(shù)學(xué)基礎(chǔ)就是我們離散數(shù)學(xué)的命題推理.

    在推導(dǎo)過(guò)程中,其實(shí)就是把原來(lái)的文法中的遞歸展開.那么我們?cè)谕茖?dǎo)的過(guò)程,也就很容易實(shí)現(xiàn)分析樹的生成.而分析樹就是我們編譯程序中十分重要的信息源.我們之所以前面又做詞法分析,又做語(yǔ)法分析的目標(biāo)就是為了生成分析樹.有了它,我們編譯程序在后面的代碼生成過(guò)程中將變得容易百倍.

    ?請(qǐng)看:

    3.2

    同樣是<<編譯原理及實(shí)踐>>書上的例子.

    設(shè)E -> E+a | a 表示的文法為G,那么考慮它生成的表達(dá)L(G)

    如果由標(biāo)準(zhǔn)的數(shù)學(xué)定義,那么我們用公式L(G)={s | exp =>* s }表示一種文法G.

    s代表記號(hào)符號(hào)的任意數(shù)組串,也就是我們的終結(jié)符號(hào).而exp代表非終結(jié)符號(hào),=>*表示一系列的從非終結(jié)符到終結(jié)符號(hào)的推導(dǎo)過(guò)程.這里*有點(diǎn)像我們?cè)谥v述正則表達(dá)式中的*符號(hào)一樣,它表示0到無(wú)限次的重復(fù).所以=>*就是表示0次到無(wú)限次的推導(dǎo)過(guò)程.

    L(G) = {a,a+a,a+a+a,a+a+a+a,…}

    E => E+a => E+a+a => E+a+a+a

    同時(shí),在我們的編譯課本上,又經(jīng)常講述另一種數(shù)學(xué)表達(dá)方式來(lái)闡述文法的定義.

    G=(T,N,P,S)

    注意,這里的T,N,P,S都是集合.

    T表示終結(jié)符號(hào)(terminal),也就是這里{a,+}

    N表示非終結(jié)符號(hào)(nonterminal),也就是這里{E},但是N不能與T相交.

    P表示產(chǎn)生式(production)或者文法規(guī)則(grammar rule)的集合,這里它只有一個(gè)元素: E -> E+a

    S表示集合N的開始符號(hào)(start symbol).關(guān)于S,本人也搞不清楚它的用處,所以很抱歉!

    3.3

    這是我們C程序語(yǔ)言中經(jīng)常使用if else文法

    statement -> if-stmt | other

    if-stmt -> if(exp) statement | if (exp) statement else statement

    exp -> 0|1

    statement就是我們C語(yǔ)言中使用語(yǔ)句,它的產(chǎn)生式包括了兩種可能,一是if-stmt語(yǔ)句,二是other.然后我們又另外定義if-stmt語(yǔ)句的產(chǎn)生式.這里有兩種情況,一是沒(méi)有else的,另外就是有else的.里面我們又使用了遞歸.if-stmt本來(lái)是包含在statement里面的,可是我們又在if-stmt的產(chǎn)生式中使用statement.正是因?yàn)槲姆ㄖ性试S遞歸,所以它比起我們前面講的正則表達(dá)式有更廣泛的表示能力,但同時(shí),文法的推導(dǎo)識(shí)別也更加法復(fù)雜.按照編譯原理的書籍,一般講完BNF文法后,就要重點(diǎn)講解文法的推導(dǎo)算法.一共有兩種,一是LL算法,自頂向下的算法,二是LR算法,自底向上的算法.LL算法比較簡(jiǎn)單,其中還有一種特殊的情況,就是我們下一節(jié)要講的遞歸下降的算法.由于C語(yǔ)言中的函數(shù)本來(lái)就可以遞歸,那么實(shí)現(xiàn)這中遞歸下降的算法是十分簡(jiǎn)單的,而且對(duì)于我們一般的程序設(shè)計(jì)語(yǔ)言來(lái)說(shuō),雖然它的算法能力很弱,但是已經(jīng)是足夠用了.而關(guān)于LR的算法,那么就是一個(gè)大難題了.它的算法能力最強(qiáng),但是實(shí)現(xiàn)起來(lái)十分困難,還好,已經(jīng)有科學(xué)家為我們提供了yacc(或者叫bison)這個(gè)工具,可以來(lái)自動(dòng)生成LR的文法推導(dǎo)算法.這就是我們一直在提到的yacc工具了.

    回過(guò)頭來(lái),我們看看下面的程序

    if(0) other else other

    的分析樹

    思考: 為什么要把文法最終分析成樹結(jié)構(gòu)?

    因?yàn)槲姆ū旧硎沁f歸的,而表示的遞歸的最好數(shù)據(jù)結(jié)構(gòu)就是樹,所以我們把文法弄成樹結(jié)構(gòu)后,后面在處理代碼生成等問(wèn)題上,也可以用遞歸來(lái)很容易地完成.

    3.4

    這里我給出microsoft在msdn中對(duì)于C語(yǔ)言的statement的文法

    注意,這里用:符號(hào)替代了我們前面產(chǎn)生式的->

    statement :

    labeled-statement
    compound-statement
    expression-statement
    selection-statement
    iteration-statement
    jump-statement
    try-except-statement???/* Microsoft Specific */
    try-finally-statement???/* Microsoft Specific */

    jump-statement :

    goto identifier ;
    continue;
    break;
    return expression opt ;

    compound-statement :

    { declaration-list opt statement-list opt }

    declaration-list :

    declaration
    declaration-list declaration

    statement-list :

    statement
    statement-list statement

    expression-statement :

    expression opt ;

    iteration-statement :

    while ( expression ) statement
    do statement while ( expression );
    for ( expression opt ; expression opt ; expression opt ) statement

    selection-statement :

    if ( expression ) statement
    if ( expression ) statement else statement
    switch ( expression ) statement

    labeled-statement :

    identifier : statement
    case constant-expression : statement
    default : statement

    try-except-statement :???/* Microsoft Specific */

    __try compound-statement
    __except ( expression ) compound-statement

    try-finally-statement :???/* Microsoft Specific */

    __try compound-statement
    __finally compound-statement

    posted on 2006-05-06 16:16 迷途書童 閱讀(775) 評(píng)論(0)  編輯  收藏 所屬分類: 編譯原理

    主站蜘蛛池模板: 久久亚洲精品国产精品黑人| 亚洲精品成人区在线观看| 亚洲av中文无码乱人伦在线咪咕| 四虎影视久久久免费观看| 国产三级免费电影| 青青草国产免费国产是公开 | 亚洲人成色777777精品| 成人免费无码大片a毛片| 亚洲欧美乱色情图片| 国产公开免费人成视频| 全黄A免费一级毛片| 亚洲午夜国产精品无码| 久草视频在线免费看| 777亚洲精品乱码久久久久久| 99视频在线免费| 亚洲日本香蕉视频| 午夜毛片不卡高清免费| 黄床大片30分钟免费看| 老司机亚洲精品影视www| 三级网站免费观看| 亚洲婷婷天堂在线综合| 四色在线精品免费观看| 免费无码AV一区二区| 国产AV无码专区亚洲AV毛网站| 亚洲成人免费在线| 亚洲综合一区无码精品| 久久久久亚洲精品男人的天堂| 久久精品一区二区免费看| 亚洲一区二区影视| 免费在线观看毛片| 无码AV片在线观看免费| 在线综合亚洲欧洲综合网站| yy6080久久亚洲精品| 午夜无码A级毛片免费视频| 亚洲a∨无码男人的天堂| 亚洲精品NV久久久久久久久久| 久久国产乱子免费精品| 亚洲成av人无码亚洲成av人| 亚洲无人区一区二区三区| 91视频国产免费| 成在线人视频免费视频|