1. 程式人生 > >編譯原理 LR分析(主要是LR(0)分析)

編譯原理 LR分析(主要是LR(0)分析)

一、LR分析的基本原理

1、LR分析的基本思想

LR方法的基本思想就是,在規範歸約的過程中,一方面要記住已移進和歸約出的整個字串,也就是說要記住歷史;一方面能夠根據所用的產生式的推測未來可能碰到的輸入符號,也就是說能夠對未來進行展望。這樣,當一串貌似控制代碼的字串出現在分析棧的頂部時,我們希望能夠根據歷史和展望以及現實的輸入符號這三部分的材料,決定出現在棧頂的這一串符號是否就是我們要找的控制代碼。


2、LR分析器的構成

採用下推自動機這種資料模型。包括以下幾個部分:
    1.輸入帶
    2.分析棧:包括狀態棧和文法符號棧兩部分。(s0,#)為分析開始前預先放在棧裡的初始狀態和句子括號。
    3.LR 分析表

:包括動作表和狀態轉移表兩張表。

3、LR分析表是LR分析器的核心部分

一張LR分析表包括兩部分:動作表(ACTION)和狀態轉換表(GOTO)。它們都是二維陣列。ACTION[s,a]規定了當狀態s面臨輸入符號a時應採取什麼動作(移進、歸約、接受和報錯),而GOTO[s,X]規定了當狀態s面對文法符號X(終結符或非終結符)時的下一狀態是什麼

   顯然, GOTO[s,X]定義了一個以文法符號為字母表的DFA。

   不同的 LR 分析法構造LR分析表的方法都不同,由此產生了不同的LR分析法。


4、LR分析演算法

置ip指向輸入串w的第一個符號
  令Si為棧頂狀態
  a是ip指向的符號(當前輸入符號)
  BEGIN

(重複開始)
  IFACTION[Si,a]=SjTHEN

                BEGIN

           PUSH j,a (進棧)
          ip前進(指向下一輸入符號)
       END
  ELSEIFACTION[Si,a]=rj(若第j條產生式為A→β) THEN
          BEGIN
          pop|β| 項
          若當前棧頂狀態為Sk
          pushGOTO[Sk,A] 和A(進棧)
    END
  ELSEIFACTION[Si,a]=acc THEN
    return (成功)
  ELSE

error
  END. (重複結束)


二、LR(0)分析器

1、可歸字首與規範句型的活字首

文法G[S](1) S → aAcBe[1]
(2) A → b[2]
(3) A →
Ab[3]
(4) B → d[4]

S ÞaAcBe[1]
 
ÞaAcd[4]e[1]
 
ÞaAb[3]cd[4]e[1]         
 
Þab[2]b[3]cd[4]e[1]


每次歸約句型的前部分依次為:
ab[2]
aAb[3]
aAcd[4]
aAcBe[1]


規範句型的這種前部分符號串稱為可歸字首

我們把形成可歸字首之前包括可歸字首在內的所有規範句型的字首都稱為活字首

(活字首就是可歸字首的字首)如下:

e,a,ab
 
e ,a,aA,aAb
 
e ,a,aA,aAc,aAcd
 
e ,a,aA,aAc,aAcB,aAcBe


三、LR分析

(一)LR分析構造識別活字首的有窮自動機

專案(item):在每個產生式的右部適當位置新增一個圓點構成專案。


根據圓點所在的位置和圓點後是終結符還是非終結符把專案分為以下幾種:

移進專案,形如 A→aab

待約專案,形如 A→aBb

歸約專案,形如 A→a

接受專案,形如S’ →S


根據圓點所在的位置和圓點後是終結符還是非終結符把專案分為以下幾種:

   移進專案,形如 A →a . ab
    待約專案,形如 A→a . Bb
    歸約專案,形如 A→a .
    接受專案,形如 S’→S.

把文法的所有產生式的專案都引出,每個專案都為NFA的一個狀態。其中

文法的第一個產生式的第一個專案為文法的初態

文法的接受專案為文法的句子識別態

文法的每一個產生式的歸約專案為文法的控制代碼識別態


構造步驟:

專案圓點的左部表示分析過程的某個時刻用該產生式歸約時控制代碼已識別的部分,圓點右部表示待識別的部分

構造識別活字首的NFA:

1、把文法的所有產生式的專案都引出,每個專案都為NFA的一個狀態
2、確定初態控制代碼識別態句子識別態
3、確定狀態之間的轉換關係
  *
若專案iX X1X2...Xi-1 Xi...Xn專案jX X1X2...Xi-1 Xi Xi+1...Xn則從狀態i到狀態j連一條標記為Xi的箭弧
 
*若i為X→gAd,k為A→b,則從狀態i畫標  記為 e的箭弧到狀態k

(二)將非確定的有限自動機轉換成確定的有窮自動機

方法一:(採用子集構造法)

方法二:通過構造文法G的LR(0)的專案集規範族來直接構造識別活字首的DFA

LR(0)專案集規範族的構造

構成識別一個文法活字首的DFA專案集(狀態)的全體稱為這個文法的LR(0)專案集規範族

1通過閉包函式(CLOSURE)來求DFA一個狀態的專案集,找出所有的等價的專案。

如果I是文法G的一個專案集,定義和構造I的閉包CLOSURE(I)如下:
a)I的專案都在CLOSURE(I)
b)A→aBb屬於CLOSURE(I),則每一形如B→g的專案也屬於CLOSURE(I)
c)
重複b)直到CLOSURE(I)不再擴大


(2)定義轉換函式如下:GOTOIX=CLOSURE(J)
其中:I為包含某一專案集的狀態,X為一文法符號
 J={任何形如A→aX b的專案|A→aX b屬於I}

圓點不在產生式右部最左邊的專案稱為,唯一的例外是S’ → S。因此用GOTOIX)轉換函式得到的J為轉向後狀態所含專案集的


使用閉包函式(CLOSURE)和轉向函式(GOTO(I,X))構造文法G’的LR(0)的專案集規範族,步驟如下:

a)置專案S’→ S為初態集的核,然後對核求閉包CLOSURE({S’→ S})得到初態的專案集
b)對初態集或其它所構造的專案集應用轉換函式GOTO(I,X)=CLOSURE(J)求出新狀態J的專案集
c)重複b)直到不出現新的專案集為止


相關推薦

編譯原理之LL(1) 、LR(0)、SLR、LR(1)、LALR文法的對比

考完編譯原理有一段時間了,記得當時都被以上這五種文法搞懵了,所以希望寫篇文章幫助那些正在學習的人。以下內容是依據龍書中文版講解的,由於老師不同可能某些地方大同小異,如有什麼紕漏之處還請指出,多謝~ 以下文章參考了:LL LR SLR LALR 傻傻分不清。 首先來看張圖,上圖是四種文法的包含

編譯原理中的逆波蘭表示式資料流圖中運算變數的流程

表示式一般由運算元(Operand)、運算子(Operator)組成,例如算術表示式中,通常把運算子放在兩個運算元的中間, 這稱為中綴表示式(Infix Expression),如A+B。 波蘭數學家Jan Lukasiewicz提出了另一種數學表示法,它有兩種表示形

thinkphp5.0與thinkphp3.2的幾個不同之處主要寫5.0

5.0的入口檔案是放在public資料夾下面,所以如果要單獨配置站點,則需要選到public資料夾 模板渲染方面:5.0使用的是:return $this->fetch();(fetch裡不帶引數,是自動定位到當前操作的模板檔案,如果帶引數就跟原來的一樣) 資料庫方面:5.0在

php中資料的儲存主要講述的檔案的儲存

程式語言中對資料劃分了很多的型別,但資料與之相關的有兩個方面:其一是值,其二是型別。 程式在運算的過程中,會產生資料,但程式執行結束記憶體中的資料都會丟失。如果想儲存程式執行過程中產生資料,要儲存起來。儲存的位置文字檔案或資料庫。 但是文字檔案中只能儲存字元資訊。為了將資料的資料與型別一

Linux伺服器調優主要sysctl和ulinit和nginx

安裝一臺新的Linux伺服器之後都要做些配置調整工作,優化一下系統,以前零零碎碎記錄過一些,這裡集中整理一下。 Linux核心引數 http://space.itpub.net/17283404/viewspace-694350 net.ipv4.tcp_syncoo

編譯原理實驗之源程式的預處理及詞法分析程式設計

題目要求: 1、實現預處理功能 源程式中可能包含有對程式執行無意義的符號,要求將其剔除。 首先編制一個源程式的輸入過程,從鍵盤、檔案或文字框輸入若干行語句,依次存入輸入緩衝區(字元型資料);然後編制一個預處理子程式,去掉輸入串中的回車符、換行符和跳格符等編輯性文字;把多個

JavaScipt30(第三個案例)主要知識點:css變量

情況 event prop data- reac https 源碼 頁面 date 承接上文 https://www.cnblogs.com/wangxi01/p/10641210.html,下面是第三個案例: 主要要實現的是移動上面的input range,改變下面

ijkplayer修改動態庫名稱目前最新版本0.8.8

       瞭解ijkplayer的朋友都知道,底層有三個動態庫,分別是libijkffmpeg.so、libijksdl.so、libijkplayer.so。一般出於避免重名衝突和便於區分的考慮都會修改它們的名稱。接下來我就依次介紹如何修改三個動態庫

python筆記11.30-2.0-2.4

2.0-2.4 內建函式一個函式可以說是一個邏輯或者功能.使用ipython檢視python的內建函式builtin. 顯示一共有137個內建函式也可以登入https://docs.python.org/2/library 官網去查詢 •返回數字的絕對值abs() abs(-10) 返回的是10 •取列表

caffe-SSD 安裝、訓練、SSD測試ubuntu18.04+cuda9.0+openvc3.4

安裝及MNIST模型測試、matlab caffe介面測試 https://blog.csdn.net/qq_35608277/article/details/84938244 自己看程式碼提供者的最直接,大家都是根據他的copy的: https://github.com/weili

搭配購買並查集+0/1揹包

Joe覺得雲朵很美,決定去山上的商店買一些雲朵。商店裡有n朵雲,雲朵被編號為1,2,…,n,並且每朵雲都有一個價值。但是商店老闆跟他說,一些雲朵要搭配來買才好,所以買一朵雲則與這朵雲有搭配的雲都要買。但是Joe的錢有限,所以他希望買的價值越多越好。 輸入 第1

Android 版本更新適配7.0 xml配置

版本更新一般分兩種情況: 需要更新時跳轉到應用市場或者跳轉到瀏覽器處理 另一種情況則是在App內進行更新 第一種沒什麼好說的,本文主要是實現應用內進行更新 App內部更新分以下幾個步驟: 檢測App版本 下載Apk 安裝已下載完成的Apk 下面貼上例項: 1.

解決 web伺服器部署常見問題,server application unavailable 和 程式無法連線資料庫 的問題asp.net 2.0 + oracle9i + winXP

部署時出現以下錯誤: server application unavailable the web application you are attempting to access on this web server is currently unavailable. pl

Factorial階乘最後0的個數

Factorial Time Limit: 1500MS Memory Limit: 65536K Total Submissions: 15475 Accepted: 9533 Description The most important part of

阿里雲Centos搭建java全攻略jdk1.8+tomcat9.0+mysql5.7

由於專案需要部署到伺服器,但是學校課程推薦的新浪雲收費較高,所以最新購買了阿里雲,現在還有優惠活動(9塊錢買一年雲端儲存oos贈送半年雲伺服器cse,現在還可以,手慢無) 伺服器相關配置 推薦64位Centos,但是第一次選錯了也沒關係,可以通過停止例項

Kmp求next的值下標從0開始的

直接上程式碼: #include<iostream> #include<cstring> #include<cstdio> using namespace std

登錄註冊頁面連接MySQL8.0.15版本

導包 class 抽象 如果 隱藏 font 用戶 puts getc 原文鏈接:https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=2247483779&idx=1&sn=e23e68e961

編譯原理自底向上分析LR分析

markdown lr分析 編譯原理 lock mar blog pre 分析法 logs 自底向上分析之LR分析法 說明:以老師PPT為標準,借鑒部分教材內容,AlvinZH學習筆記。 本節內容太多了,考完再寫了,對不起~ 引用說明 - 邵老師課堂PDF - 《編譯原

編譯原理 LR分析主要是LR0分析

一、LR分析的基本原理 1、LR分析的基本思想 LR方法的基本思想就是,在規範歸約的過程中,一方面要記住已移進和歸約出的整個字串,也就是說要記住歷史;一方面能夠根據所用的產生式的推測未來可能碰到的輸入符號,也就是說能夠對未來進行展望。這樣,當一串貌似控制代碼的字串出現在分

編譯原理語法分析之自底向上分析之算符優先分析

logs cnblogs div mar 分析法 clas pos block mark 語法分析之自頂向下分析 說明:以老師PPT為標準,借鑒部分教材內容,AlvinZH學習筆記。 先看看PPT吧! 引用說明 - 邵老師課堂PDF - 《編譯原理級編譯程序構造》 編譯