1. 程式人生 > >語義分析中間程式碼的產生和屬性文法語法制導翻譯

語義分析中間程式碼的產生和屬性文法語法制導翻譯

1.語義分析的任務

(1)審查每一個語法結構的靜態語義,即驗證語法正確的結構是否有意義。如:賦值語句:x:=x+y,左邊變數型別與右邊變數型別是否一致;(2)在語義正確的基礎上生成一種中間程式碼或目的碼。

2.語義分析的範圍
(1)確定型別:確定識別符號所關聯的資料型別。
(2)型別檢查:按語言的型別規則,檢查運算的合法性與運算分量型別的一致性,必要時作型別轉換。

(3)識別含義:根據語言的語義定義(形式或非形式),識別程式中各構造成分組合到一起的含義,並作相應的語義處理(生成中間程式碼或目的碼)。

(4)控制流檢查:控制流語句必須轉移到合法的地方。如C中,break語句規定跳出最內層的迴圈或switch語句。

(5)一致性檢查:在很多場合要求物件只能被說明一次。如:pascal語言規定同一個識別符號在一個分程式中只能被說明一次等。(6)相關名字檢查:如:Ada,迴圈或塊可以有一個名字,它出現在這些結構的開頭或結尾。編譯程式必須檢查這兩個地方用的名字是否相同。

其它:如名字的作用域分析等也是語義分析的工作。

3.說明語句的翻譯: 程式語言中的說明語句都是給編譯程式提供資訊的,諸如型別、維數、每維的界種類等,因此一般不生成目標,只是在編譯時把有關資訊填入相應表格即可。

 (1)簡單說明句:用一個基本字來定義一串名字,其語法描述一般為:
     D→integer namelist∣real namelist
     namelist→namelist,i∣i
     直接用這種文法來制導翻譯有點麻煩,就是隻能在把所有名字規約成namelist之後才能把性質登記到符號表中。這就意味著在掃描名字時,應把名字用一個佇列(或棧)儲存起來,然後再處理。
我們可以對文法稍做改動,就可以免去建立佇列或棧的過程。修改文法如下:     

           D→D,i∣integer i∣real i

(2)陣列說明


4.陣列元素的地址計算公式: 若陣列A的元素存放在一片連續單元裡,則可以較容易的訪問陣列的每個元素。假定陣列的每個元素的寬度為w,則一維陣列A[i] 這個元素的起始地址為:
                            base + (i – low)*w 
            其中,low為陣列下標的下界, base是分配給陣列的相對地址,即base為A的第一個元素A[low]的相對地址。
        base + (i – low)*w   可整理為:  i*w + (base –low*w)
  其中:
     (1) i*w  是隨陣列下標變數而變化的部分,記為VARPART ;

    (2)(base – low*w)是在陣列中不變化的常數記為CONSPART

5.二維陣列:若二維陣列A按行存放,則可用如下公式計算A[i1,i2]的相對地址:
    base + (( i1 – l1)*d2 + i2 – l2) *w
    其中,l1、l2分別為i1、i2的下界;di界差。若ui為i的上界,則di=ui – li +1.
假定i1,i2是編譯時唯一尚未知道的值,我們可以重寫上述表示式為:( base –( (l1 *d2) + l2) *w)+ ( (i1*d2) + i2) *w          
                  CONSPART                   VARPART
       其中:前一項子表示式( base – ((l1 *d2) + l2) *w )的值是可以在編譯時確定的記為常數CONSPART。

      後一子項隨i1, i2 而改變是一個變數記VARPART。

6.迴圈與分情況語句的翻譯:

大多數程式語言中都有如下形式的迴圈句:
      S→for i:=E1 step E2 until E3 do S1
   其語義各語言可能有所不同,主要區別在先判斷、後執行還是先執行、後判斷。按Algol語言的解釋:
              i:=E1;
              goto over;
      again:  i:=i+E2;
      over:   if i<=E3 then 

                begin  S1; goto again  end;

 於是為了產生四元式,描述文法改寫如下:
          F1→for i:=E1
      F2→F1 step E2
      F3→F2 until E3
      S→F3 do S1

    根據前面的解釋,i在幾處都用到,故ENTRY(i)必須保留下來,而該文法正是基於這樣的考慮而寫出來的。

7..屬性文法是在上下文無關文法的基礎上為每個文法符號(終結符或非終結符)配備若干個相關的“值”(稱為屬性)。

8.屬性的分類:

(1)綜合屬性:用於“自下而上”傳遞資訊,在語法樹中,一個結點的綜合屬性的值,由其子結點的屬性值確定

  (2)繼承屬性:用於“自上而下”傳遞資訊。在語法樹中,一個結點的繼承屬性由此結點的父結點和/或兄弟結點的某些屬性確定

9.語義規則:屬性計算的過程即是語義處理的過程,對於文法的每一個產生式配備一組屬性的計算規則,則稱為語義規則。在一個屬性文法中,對應於每個產生式A都有一套與之相關聯的語義規則,每條語義規則的形式為:b:=f(c1,c2,…,ck)  這裡f是一個函式,而且或者(1)b是A的一個綜合屬性並且c1,c2,…ck是產生式右邊文法符號的屬性;或者(2)b是產生式右邊某個文法符號的一個繼承屬性並且c1,c2,…ck是A或產生式右邊任何文法符號的屬性,在這兩種情況下,我們都說屬性b依賴於屬性c1,c2,…,ck.A-》=>b1b2…bn,b:=f(c1,c2,…,ck)(1)b是A的一個綜合屬性(2)b是bi的一個繼承屬性

10.基於屬性文法的處理過程:輸入串->語法樹->依賴圖->語義規則計算次序->計算結果

11.依賴圖的構造演算法:for分析樹中每一個結點n
for 結點的文法符號的每一個屬性a
為a在依賴圖中建立一個結點;
for分析樹中每一個結點n
for結點n所用產生式對應的每一個語義規則
b:=f(c1,c2,…ck)
for i :=1 to k

從ci結點到b結點構造一條有向邊

12.L屬性文法:如果每個產生式A X1 X2 … Xn 的每條語義規則計算的屬性是A的綜合屬性;或者是Xj 的繼承屬性, 1  j  n, 但它僅依賴:該產生式中Xj左邊符號X1, X2, …, Xj-1的屬性;A的繼承屬性,S屬性文法包含於L屬性文法

13.翻譯模式:翻譯模式是語法制導定義的一種便於翻譯的書寫形式。其中屬性與文法符號相對應,語義規則或語義動作用花括號{ }括起來,可被插入到產生式右部的任何合適的位置上。



相關推薦

語義分析中間程式碼產生屬性文法語法制導翻譯

1.語義分析的任務(1)審查每一個語法結構的靜態語義,即驗證語法正確的結構是否有意義。如:賦值語句:x:=x+y,左邊變數型別與右邊變數型別是否一致;(2)在語義正確的基礎上生成一種中間程式碼或目的碼。2.語義分析的範圍(1)確定型別:確定識別符號所關聯的資料型別。(2)型別

編譯原理第七章-語義分析中間程式碼產生

語義分析的任務是:1.審查每一個語法結構的靜態語義,即驗證語法正確的結構是否有意義。2.在語義正確的基礎上生成一種中間程式碼或目的碼。語義分析的範圍是:1.確定型別:確定識別符號所關聯的資料型別。2.型別檢查:按語言的型別規則,檢查運算的合法性與運算分量型別的一致性,必要時作

編譯原理SLR(1)文法的C++實現(基於SLR(1)分析法的語法制導翻譯中間程式碼生成程式設計原理與實現)

程式功能描述完成以下描述賦值語句 SLR(1)文法語法制導生成中間程式碼四元式的過程。G[A]:A→V=EE→E+T∣E-T∣TT→T*F∣T/F∣FF→(E)∣iV→i[設計說明] 終結符號i為使用者定義的簡單變數,即識別符號的定義。[設計要求](1)構造文法的SLR(1)

編譯原理 第六章 屬性文法語法制導翻譯

一、知識總結        首先學習了屬性文法,屬性文法是在上下文無關文法的基礎上為每個文法符號(終結符或非終結符)配備若干個相關的“值”,稱為“屬性”。屬性分為綜合屬性和繼承屬性。綜合屬性用於“自下而上”傳遞資訊,在語法樹中,一個結點的綜合屬性的值,由其子結點的屬性值確定。

使用Xcode 自帶的view hierarchy 來分析view的層次屬性

最近發現Xcode的view hierarchy debug挺酷炫的,寫個簡單的材料 新建一個工程,然後在模擬器上執行,程式碼就是在viewDidLoad裡面生成一個button1,設定背景顏色和文字。 <p style="margin-top: 0px; mar

編譯原理第六章-屬性文法語法制導翻譯

      第六章主要講了屬性文法、語義規則、基於屬性文法的處理、S屬性的自下而上計算、L-屬性文法的自頂向下翻譯等內容。一些基本的概念:屬性文法:是在上下文無關文法的基礎上為每個文法符號(終結符或非終結符)配備若干個相關的“值”(稱為屬性)。屬性:代表與文法符號相關的資訊,

完整cmm直譯器構造實踐(四):語義分析程式碼生成

語義分析 語法分析只是分析了程式碼在語法上是不是合法的, 但是程式碼仍然有可能存在問題, 比如一些需要上下文才能分析的錯誤, 語法分析就不能分析出來. 比如下面的程式碼 a = 10; 從語法上來看, 這是一句合法的賦值語句. 但是從語義上看, 我們並

【編譯原理】語法制導翻譯屬性文法(一)

最近對程式語言如何從 原始碼->位元組碼(or 機器碼)->執行 產生了興趣,為此從今天開始,給自己制定了一個學習計劃, 目的是能夠對Java原始碼如何到class檔案位元組碼,再如何在JVM上執行有比較深入的理解。 學習的第一步,就從難啃的編譯原理開始。 之前

編譯原理第七章——語義分析中間程式碼產生

1、知識點圖重點記憶:說明語句的翻譯     程式語言中的說明語句都是給編譯程式提供資訊的,諸如型別、維數、每維的界種類等,因此一般不生成目標,只是在編譯時把有關資訊填入相應表格即可。賦值語句的翻譯 1.簡單算術表示式的賦值語句:      所謂簡單指不考慮陣列元素、記錄、函

第七章:語義分析中間程式碼產生

一.語義分析概述1.語義分析的任務 1)審查每一個語法結構的靜態語義,即驗證語法正確的結構是否有意義。如:賦值語句:x:=x+y,左邊變數型別與右邊變數型別是否一致。2)在語義正確的基礎上生成一種中間程式碼或目的碼。2.語義分析的範圍1)確定型別:確定識別符號所關聯的資料型別

第七章 語義分析中間程式碼生成

1、   編譯程式的任務是把源語言程式翻譯成目標程式,有些編譯程式在編譯過程中,不產生中間語言,而是直接從源語言程式翻譯成目標語言程式。 以上編譯過程省略了中間語言,它不利於編譯所產生的目的碼的優

編譯原理(九) LR(0)文法分析法(演算法描述C++程式碼實現)

後期DEBUG發現make_set函式和make_go存在問題,於2015年12月4日更新了程式碼,見諒 概念梳理 最左推導:每一步替換最左邊的非終結符 最右推導:每一步替換最右邊的非終結符,最右推導稱為規範推導 短語:令G是一個文法,S是文法的開始符號

編譯原理-詞法分析-語法分析-語義分析生成中間程式碼-python版

# -*- coding:UTF-8 -*- #!/usr/bin/python import string import sys import Analyze_2 Identifier=['if','else','for','while','do','int','writ

語義分析之一:屬性文法

編譯原理的幾個核心階段:詞法分析、語法分析和語義分析,其實編譯的本質便是翻譯,其各個階段便是承擔不同的翻譯任務,詞法分析階段的任務是將程式輸入的字串流翻譯成語言認可的字元流(剔除空格和註釋等部分);語法分析便是將程式按照語言文法的規則構建成語法樹;語義分析便是在

GSM A5/1演算法C語言程式碼實現分析

介紹 全球超過200個國家和地區超過10億人正在使用GSM電話。對中國使用者來說,GSM就是移動和聯通的2g模式。 在1982年A5首次提出時,人們認為A5 / 1金鑰長度要128位,但最終確定的結果是64位金鑰(政府可以使用暴力破解算出)。很可能是政府的壓力迫使金鑰位數縮

常見排序演算法的基本原理、程式碼實現時間複雜度分析

  排序演算法無論是在實際應用還是在工作面試中,都扮演著十分重要的角色。最近剛好在學習演算法導論,所以在這裡對常見的一些排序演算法的基本原理、程式碼實現和時間複雜度分析做一些總結 ,也算是對自己知識的鞏固。 說明: 1.本文所有的結果均按照非降序排列; 2.本文所有的程式均用c++實現,

程式碼從Polyline讀取到的座標屬性對話方塊顯示的不一樣?

屬性視窗中查詢的第一個點座標: 程式輸出的各個點座標: 差這麼多? 原來是座標系的問題,程式查詢到的是世界座標,屬性視窗中是當前ucs座標   Document doc = Application.DocumentManager.MdiActiveDocument;doc.Edit

[原始碼報告分享]Linux環境下的針對PL0語言的語法詞法語義分析

摘 要 此次編譯原理課程設計,我利用flex工具進行PL/0語言的詞法分析、自己用C++語言實現了LR語法分析、語義分析以及中間程式碼生成,我選擇的是布林表示式文法,對符合文法的布林表示式能夠產生相應四元式,處理了控制結構的真鏈與假鏈,對錯誤的表示式能夠給出錯誤提示。 鑑於flex工具原本來自Unix以及

補間動畫屬性動畫記憶體洩露分析

在使用屬性動畫的時候,我們知道如果不在頁面結束的時候釋放掉動畫,就會引起記憶體洩露。 簡單的說就是ValueAnimator在AnimationHandler註冊自己的AnimationFrameCallback,AnimationFrameCallback介面

python爬蟲-通過bs4xpath分析html程式碼

我感覺作者用xpath分析程式碼的時候不是很好,下面是我重新改善的 一、用lxml模組分析程式碼 #!/usr/bin/env python #-*- coding:utf-8 -*- import requests import time,os from