跟著樹博讀博士適時四驅系統編譯器(詞法分析+活躍變量分析)

2022-01-18 半截入土楊大樹
跟著樹博讀博士適時四驅系統編譯器(詞法分析+活躍變量分析)前言

沒什麼想說的,只是今天刷步行街的時候綠帽男頻出,希望天下的女人能夠善待自己的男友,特別是當你的男朋友是個jrs的話,請珍惜他們,他們都是好男人。

(一)lexical analysis(詞法分析)1. 詞法分析的作用

首先提幾個概念

keyword 關鍵字,如for,do,while,if else等Identifier 標識符,如 a,a1,a_1等(譬如變量名)Operator 關係運算符,如 +,-,*,=等

把一個字符串轉換為為一種詞法單元(token),一個token的形式是這樣*<token class, lexeme>*, 上面的提到的那些概念在一個token中我們可以把它們當作token class, 而具體的字符子串則被是這裡的lexeme

舉個🌰

if(i == j)
 t = 0
else
 t = 1

首先在詞法分析器看到的並不是人類肉眼看到的東西,在詞法分析器的識別中,字符串首先是如下的格式 "\n"代表的是換行符,"\t"代表的是空格

if(i==j)\n\t\tt=0\nelse\n\t\tt=1

經過了詞法解析器的解析後得到的就是一個個的詞法單元(token)

2.詞法分析要解決的東西

所以詞法分析是要解決什麼事兒呢,下面的例子都是出於龍書

(1) Amazing whiteSpace

考慮Fortran這種情況,在遠古Fortran語法中,Do 5 l = 1,25 是一個常規的loop循環語句,代表了從now開始執行5行,執行1-25共25次,而Do 5 l = 1.25代表的含義是標識符 Do 5 l的值是float1.25,所以在現代語言的編譯器中,對這種情況的處理是編譯器要解決的一類事

Do 5 l = 1,25
Do 5 l = 1.25

**(2) **Lookahead

編譯器在對程序片段進行詞法分析的時候需要一個概念 "Lookahead",進行掃描的時候一般是left to right,看下面的🌰,針對這個程序片段,當掃描到第一行的 "=",它需要Lookahead地明白,到底這裡的 「=」 是一個簡單的賦值符號,還是和 「==」 一起表示 「等於」 的含義,再簡單一些針對 第三行的第一個「e」單詞,它需要lookahead地明白,「e」 代表是一個標識符,還是和 「else」 一起表示一個標識符

if(i==j)
 z=0;
else
 z=1;

(3) Keyword or Identifier?

看下面這個🌰,結合標題,懂了嗎?這個還是不要解釋了,怕吐。

IF ELSE THEN THEN = ELSE;ELSE ELSE=THEN

3.Regular Language(正則語言)

正則語言,想必姐妹們,學安全的,學開發的,熟的不能再熟了吧。

4.Formal Language(形式語言)

形式語言,在編譯器中也擔任著非常重要的看角色,在編譯器中往往使用著好幾種不同的形式語言,譬如正則表達式就是其中一種形式語言,簡單的舉兩個🌰

我們在表示形式化語言的時候有三個基本的元素 ,一個具有meaing意義的function,一個Map關係,一個Expression例如正則表達式

Function('c')={"c"}代表正則表達式c代表了一個map {"c"}

而其中比較核心的就是這個meaning function,所以為什麼需要這個meaning function呢

expression和meaning往往不是一對一的關係,而是多對一的關係,這就可以極大程度的提高效率5. Lexical Specifications(詞法規範)

詞法規範就是定義了接受怎麼樣的輸入,以及輸入的內容與什麼token class進行關聯,以下是一些簡單的🌰,值得注意的是在一般的Lexical Specifications,keyword比較特殊,會直接定義為本身。

image-20211212224514835

在程式語言中值得注意的還有whitespace(也就是🌰中的skip),還有Comment(注釋),它們分隔了其他的tokens,例如 if a本身代表了一個keyword和一個Identifier和一個如果沒有對Skip的解釋,那就你變成了一個Identifier if a,由此也可以看出單純的用正則表達式去解析輸入流為tokens,他的結果往往是不明確的。

這裡就引入了一個新的概念,disambiguation rule消歧規則,而一個常用的規則就是「最長可能匹配原則」,其中有兩個內容

舉個🌰,下面的程序片段,如果不使用最長可能匹配原則,for_b中的for就會被匹配為Keyword for,這顯然是不符合語義的。

if a = for_b

6. finite automata(有限狀態機)

詞法是由正則進行定義,然後,往往通過finite automata(有限狀態機)進行實現,一個字母表Σ由以下的元素實現

一個集合∆,由Σ中的字母進行標記的由state -> state的edge邊,空集€也可以作為一個edge上的標記,也就是說,(q,€,q')代表了q狀態到q'狀態是一個自發的不需要條件的過程

舉個🌰,下面就是一個接受實數的有限狀態機,無非就是判斷本位是0-9還是"." ,如果是"."則到另外一個狀態,如果是0-9,則循環這個狀態繼續添加為實數總的一位數字,便於理解,0狀態有兩種可能,一個非0實數,或者為0。

如果此時解析的片段為3.1415920-3+x,那麼在生成token的時候可以把已經是別為實數的3.1415826,我們把這個值和token class一起儲存為一個token

上類的這種狀態機被稱之為 deterministic finite automaton(DFA)可確定有限狀態機。還有一種有限狀態機為nondeterministic finite automata(NFA)不確定的有限狀態機,當一個input會有多種路徑進行狀態轉換,有的路徑會成功,而有的路徑會失敗,這時會出現這種情況。為了讓「最長可能匹配原則」能夠正常實現,需要追蹤狀態轉換的接受狀態,如果不被接受則重設狀態轉換。

舉個🌰,當一個語法中包含了INT和FLOAT(🌰中的REAL),那情況就是下面這種NFA,對於q0要猜測(一般情況下可能是遍歷)會被那種type接受。

image-202112122341409137. 由正則表達式到NFA

正則表達式可以非常方便的轉換為有限狀態機,舉個🌰,此時我們定一個利用正則表達式作為標記的遞歸過程(其中的兩個圈的qf,代表這裡是可遞歸的),一個正則表達式就可以被轉換為有限狀態機的轉換條件(edge,鄙人還是說狀態轉換條件比較順嘴兒),因為在轉換為NFA的過程中可能會出現新的temp狀態,所以會引如p1,q1,其中第三個r*的轉換有點難懂,那就對了,難懂說明他是NFA。

8. 由NFA到DFA

NFA的規範定義其實是很簡單的,但實現起來會非常的麻煩;實現DFA非常的簡單的,首先我們把程序當前的狀態儲存在一個初始化為q0的程序變量中,然後根據接下來輸入的character,根據狀態轉換錶轉換到下一個狀態,因為要符合最大匹配原則,需要持續的進行分析。如果要實現NFA,我們有一個問題,我們往往會碰到很多的choice,但卻不一定知道去選擇哪一個choice進而進行狀態轉換分析,這時NFA在遇到任何的choice的時候,它需要遵循任何一個choice,我們實現的方式就是在預計算的階段遵循之前一樣的法則,而不是在運行時。

這裡的處理就涉及到了一個離散數學中的知識

首先我們需要去定一個€-transition的情況,來包括所有從{q0}狀態發生狀態轉移的情況,下面的S指的是所有的狀態Q的中符合上面符合€-transition的子集,下面的核心式子指的就是不需要任何狀態輸入消耗的狀態轉移情況。image-20220110132738915

下面定義一個需要一個狀態輸入"a", 得到的所有情況,(q,a) → (q′,ε) 也可以表達為 (q,a,q′) ∈ ∆,簡單的來說就是在整個狀態轉移表中q -> q'的狀態轉移存在一個edge a,也就是這裡所需要的狀態輸入(不是輸入狀態,其實就是狀態轉移條件,鄙人喜歡這麼說)。

image-202201101345042509. 最小確定性有限自動機

閉包!

10. 由正則表達式到DFA

這裡提出一種 Brzozowski derivatives and Antimirov’s partial derivatives 提出的一種精妙的方式,有兩篇論文,準備抽空看了。

(二)Liveness Analysis1. WHY LIVENESS ANALYSIS

活躍變量是數據流分析中的一種,在編譯器的設計中,活躍變量分析是為了優化編譯器的性能,主要是在指令選擇的時候使用,在靜態分析中也可以幫助理解用的最多的數據流分析。

2. WHAT IS LIVENESS ANAYLYSIS

活躍變量分析,顧名思義就是分析出還活著的變量,複雜的來說就是,給定一個live的屬性,當一個變量在數據流輸入輸出的過程中不會再使用,那麼此時它就是一個活躍變量,live的屬性值就是 fucking yes

3. 如何判斷一個變量是否是live

假設一個三地址碼x <- y ⊕ z

要判斷變量是否live,有兩個可能

immediate

例如y和z兩個變量,在這個二元操作⊕執行之前就被使用(取值)

next

在下一條指令中一個變量是live的,那在當前指令中他就是live的,這個情況相對上面的略微難理解一些。這樣假設,有兩個聯繫的三地址碼

x <- y ⊕ z
a <- u

這裡可以看到在第二條指令中,u根據imediate來看是live的,所以它在x <- y ⊕ z中也是live的,即使插入一個常量的操作u依舊是live的,例如這個情況

x <- y ⊕ z
x <- 100
a <- u

有一個例外, 此時x是一個賦值的操作,所以說原有的x變量在這條指令執行之後就不是live的了,雖然下一條指令的時候x是live的,但這個x已經不是之前的那個x了,之前那個x已經變成了no live並釋放掉了

x <- y ⊕ z
a <- x

除此之外還有一種情況較為特殊,當return x這種情況下,x一定是live的,我們用邏輯形式來表達上面的情況下的規則,live(l,x)代表在行號為l時,x變量是live的,現在常用的一種工具 Datelog 就是可以基於二元決策圖(BDD)進行活躍變量的分析,這裡的實現路徑,就不詳細講了,我的讀者們應該只能看懂下面的了,講實話,具體的實現到時候在油管上找一些國外課程的視頻看看,在視頻裡對這種東西更容易理解

image-20211215221814000image-20211215223336364

當被分析的程序語言允許循環的存在時,上面的四條邏輯規則明顯是無法使用,此時引入以下的邏輯規則(這裡的「?」指的是二元比較符),如果上面的例子看懂的話,對下面的規則應該也是挺好理解的。

image-20211215224354240

上面的所有例子中只用到了live一個謂語,可以看出在性能上規則具有一定的重複性,例如L2和L4,規則上非常的相近,從性能上來說,可以添加其他的謂語來更好的抽象出合理的邏輯規則。下面提出三種新的謂語

succ(l,l') 代表行號l時,當前指令執行後,執行的行號也許是l'

利用這三種謂語,可以把所有的規則變成兩條新的邏輯規則

image-20211215225904309

K2,在l行,u不是被進行了賦值操作,l之後執行的指令是l',在l'時,u是live的,則l行時u是live的

由上面的學習可以得到,在進行活躍變量分析時,def謂語應該是要最先飽和的,因為它的分析結果不會對其他的謂語有影響,不會影響到整個分析的膨脹,然後再飽和所有live謂語

在K1,K2的規則前提上可以引入以下的規則

image-20211215231025406

OK,關於活躍變量的知識應該就講這些,在課程中後續的內容是一些控制流分析,個人覺得拿活躍變量舉例從目的上來說,意義不大,未來直接做控制流分析的文章吧。

相關焦點

  • 搞懂靜態代碼分析,看這文就夠了!
    現代軟體系統規模越來越大,代碼行數從數萬或數十萬行規模增長到數千萬行;系統複雜度也越來越高,從傳統的單機系統變為分布式系統,同構系統變為異構系統;而且軟體開發的程式語言也從使用單一的語言發展為多種語言協同開發。這些變化都對SAST工具帶來了巨大挑戰。
  • 社工統計學雜記3:單變量、雙變量、多變量分析
    一般而言,一篇定量文章,先要匯報統計分析模型所包含的變量的描述性分析結果(即單變量分析:百分比,均值,或標準差等);有些文章還會檢驗兩個變量之間的相關關係(即雙變量分析:如相關分析,獨立樣本t檢驗,或卡方檢驗等);更多的時候,一個統計分析模型會控制除了很多其他的因素(如年齡,婚姻,教育水平,收入等)在裡面(即多變量分析:如各種回歸模型等)。
  • 適時四驅是什麼意思?有什麼優缺點?
    適時四驅是什麼意思?有什麼優缺點?許多人不明白適時四驅是什麼意思,認為全時四驅不是更好嗎?既然存在,那麼適時四驅自然有其存在價值的,相對分時四驅、全是四驅來說自有其獨特的優點。適時四驅只有在適當的時候才會轉換為四輪驅動,而在其它情況下仍然是兩輪驅動的驅動系統。系統會根據車輛的行駛路況自動切換為兩驅或四驅模式,不需要人為操作。
  • 編譯器說 Lambda 表達式中的變量必須是 final 的,我偏不信 | 原力計劃
    作者 | 沉默王二來源 | CSDN博客專家出品 | CSDN(ID:CSDNnews)偶爾,我們需要在 Lambda 表達式中修改變量的值,但如果直接嘗試修改的話,編譯器不會視而不見聽而不聞既能讓編譯器不發出警告,又能修改變量的值。思前想後,試來試去,我終於找到了 3 個可行的解決方案:1)把 limit 變量聲明為 static。2)把 limit 變量聲明為 AtomicInteger。3)使用數組。下面我們來詳細地一一介紹下。
  • C語言中,全局變量濫用的後果竟如此嚴重?
    1、靜態變量會被放在程序的靜態數據存儲區裡,這樣可以在下一次調用的時候還可以保持原來的賦值。這一點是他與堆棧變量和堆變量的區別2、變量用static告知編譯器,自己僅僅在變量的作用域範圍內可見。這一點是他與全局變量的區別。
  • 潛變量交互作用分析方法
    我們所熟知的 two-way ANOVA 就是交互作用分析的典型代表。而交互作用的變量,並不經常可以被直接測量得到,而只能通過可觀測變量間接測量得到。這些無法直接被測量的變量之間的交互,即為潛變量的交互。
  • C 語言 頭文件中 INT_MIN 奇怪定義的分析
    C 語言標準庫<limit.c>中定義了整型數的最大值和最小值,以 GCC 編譯器為例,
  • c編譯器so easy,gcc c編譯器生成、使用動靜態庫
    此命令的功能在於讓ldconfig將指定目錄下的動態連結庫被系統共享起來,意即:在緩存文件/etc/ld.so.cache中追加進指定目錄下的共享庫。本例讓系統共享了/usr/zhsoft/lib目錄下的動態連結庫。該命令會重建/etc/ld.so.cache文件。第三章對於c編譯器,大家並不陌生。
  • C/C+編程筆記:C語言的編譯器工作原理
    1.預處理階段:編譯器以cpp文件作為一個單元,首先讀這個cpp文件,發現第一句與第二句包含一個頭文件,就會在所有搜索路徑中尋找這兩個頭文件,找到之後,就會到相應頭文件中再去處理宏
  • 悅讀 | 不要為了讀博士而讀博,來自一個博士的透徹分析
    ,這是每一個面臨讀博的學生甚至開始讀博的學生的困惑。博士是一個文憑,更是一種經歷。當前社會上有不少人在妖魔化博士群體,尤其是女博士。事實上真的就那麼恐怖嗎? 1.首先,談談為什麼要讀博?如果你壓根就沒想好這個問題,完全是隨波逐流,或者證明自己是一個「好學生」,或者認為考博可以帶來生活的翻天復地的變化,或者認為讀博就是混個學位,為了以後好提升。
  • 世界上第一個C語言編譯器是怎麼編寫的?它為什麼能夠用C語言編寫?
    所謂C語言編譯器,就是把編程得到的文件,比如.c,.h的文件,進行讀取,並對內容進行分析,按照C 其本質在於對文件的讀入,分析,及處理。這些操作,C語言都是可以實現的。 所以用C語言來做C語言的編譯器是完全可行的。 但是,歷史上的第一個C語言編譯器,肯定不是C語言寫的,因為在沒有編譯器時,無法把C語言轉換成可執行文件。只要有了第一版其它語言的編譯器,就可以用C語言寫編譯器了。
  • 分時四驅系統問題解析:為何不能在鋪裝道路使用四驅模式?
    所以才需要在傳動系統中增加差速器,其運行原理其實非常簡單。03四驅系統特點1:分時四驅會通過分動箱往前後橋分配動力,四驅模式中是以前後50:50的固定比例分動;理論上動力達到前後橋之後但是前置前驅的後輪不輸出動力,跟著轉不會影響前輪;前置後驅的前輪不輸出動力,後輪推著轉動的時候,前輪摩擦力可以克服後輪的直線摩擦力。然而分時四驅前後輪輸出的動力相同,轉向時前輪會受到後輪的影響,前輪與前懸架是會受到推力衝擊的。
  • 第一個C語言編譯器是怎樣編寫的?
    在C語言被用作系統程式語言之前,Tomphson也用過B語言編寫作業系統。可見,在C語言實現以前,B語言已經可以投入實用了。因此第一個C語言編譯器的原型完全可能是用B語言或者混合B語言與PDP彙編語言編寫的。
  • 數據分析能力的核心是思維
    數據分析只是手段,它的誤區就是,太在意方法和工具。而最缺少的,恰恰是最重要的思維。數據分析的本質數據分析最重要的思維就是,不斷確定業務中兩組變量之間的關係,用以解釋業務。收入、轉化、用戶規模、用戶活躍等,我們稱為現象。而只有通過數據量化的現象,我們才能精準感知。所以,數據是用來描述現象的,是被量化的現象。
  • 基於MATLAB+ISIGHT的懸置系統敏感性分析
    1、研究車型懸置參數本研究車型動力總成懸置系統特性分析和優化所需的相關參數可通過相應的測試和計算獲得。表1為各懸置的主軸剛度;表2為各懸置點的位置坐標及安裝角度。表1原懸置系統主軸剛度(參考整車坐標系)2懸置安裝位置及動力總成質心坐標2、解耦計算及優化將目標動力總成各參數代入動力學模型,利用Matlab軟體編製程序進行解耦分析,可得到原懸置系統的固有頻率和能量分布百分比如圖1所示。
  • 李紅莉研發全國首個氣象實況分析系統—— 分析海量數據辨雲識雨
    為解決這一難題,李紅莉把雷達資料同化作為自己的博士論文研究方向。  「資料同化技術比較難,但是對改進數值預報具有重要意義,不同數據的解析和融合需要深厚的數學功底和良好的編程能力,是難點也是挑戰。」導師的一席話,她默默記在心裡。
  • 學習編譯原理Time02 ~ 語法分析樹
    語法分析的作用是識別由詞法分析給出的單詞符號序列是否是給定文法的正確句子,目前語法分析常用的方法有自頂向下分析和自底向上分析兩大類
  • 統計學最常用的「數據分析方法」清單(二)
    時間序列預測法的應用 系統描述:根據對系統進行觀測得到的時間序列數據,用曲線擬合方法對系統進行客觀的描述; 系統分析:當觀測值取自兩個以上變量時,可用一個時間序列中的變化去說明另一個時間序列中的變化,從而深入了解給定時間序列產生的機理; 預測未來:一般用ARMA模型擬合時間序列