[SP]Francis Compiler

6.1 Francis Compiler

  1. delimiter table
  2. reserved word table
  3. integer table
  4. real number table
  5. identifier table: subroutine 代表 scope為數值,指向identifier的index

6.2 Syntax Analysis

  1. token 組成statement,;代表statement結束
  2. 檢查文法是否正確,不正確則回傳錯誤訊息
  3. 保存資料到表格

Statement

PROGRAM GTO
SUBROUTINE assignment
VARIABLE CALL
LABEL INPUT
DIMENSION OUTPUT
IF

註解 identifier table的pointer指向中間碼的entry

變數宣告

VARIABLE <datatyep>: id{, id};

example

VARIABLE ARRAY: array1;

之後data type, scope, identifier保存進入identifier table,並且產生中間碼。

ARRAY     1
BOOLEAN   2
CHARACTER 3
INTEGER   4
LABEL     5
REAL      6

陣列宣告

宣告陣列,必須紀錄陣列各維度大小中間碼

DIMENSION <datatype>: <array>{, <array>};
<array ::= id (number {, number})>

範例16 * 5的陣列

DIMENSION REAL: A(16, 5);

透過 information table 7保存資料,保存型別維度數量各個維度大小,並且將pointer 指向information table的元素起始。

Label定義

LABEL identifier;

範例

LABEL L91, L92;

保存入identifier table,pointer會在最後指向對映指令的中間碼的位置,並且產生自己的中間碼。

GTO

GTO labelID;
GTO L92;

GTO的中間碼,前面對應到GTO,後面對應到Label指向的目標。

6.3 Function Definition And Function Call

SUBROUTINE

SUBROUTINE S1(INTEGER:X,Y,M);

Call

CALL S1(W, 136, A, 57.9)

6.4 Assignment

翻譯 X = Y + Z;

(+, Y, Z, X)

透過Reverse Polish Notation的方式下去處理,透過堆疊)做push,遇到時(檢查syntax並pop token ), 當中有operandoperator兩個堆疊, 分別保存運算元與運算子,為雙堆疊算法。

處理方式

每次pop時提取堆疊上方兩個運算元一個運算子, 之後將運算結果(暫存器)放回堆疊當成運算元, 每次pop產生中間碼。

注意: 暫存編號可能會被覆蓋,可以透過一個堆疊 保存尚未使用的暫存編號,以免蓋過先前產生的數值。

6.5 IF Statement

文法

IF <condition> THEN <statement> ELSE <statement>;

<condition>可能包含括號,翻出的statement會有forward reference, 因為沒辦法知道大小,而true的處理區塊後面必須採用GTO跳到false的後面, 以免執行false的程式碼。

邏輯運算子

範例

IF X GT Y AND Q THEN X =  X + 1 ELSE X = X + 2;

6.6 Array and Elements

處理陣列元素的statement,算出array元素指向的記憶體位置, 產生中間碼。

範例,B(I, J)元素的位置在(J - 1) * M + I產生中間碼。

(-, J , 1 , T1)  // T1 = J - 1
(*, T1, M , T2)  // T2 = T1 * M
(+, T2, I , T3)  // T3 = T2 + I
(=, B , T3, T4)  // T4 = B(T3)
(+, T4, 4 , T5)  // T5 = T4 + 4
(=, T5,   , X )  // X = T5

System Program