语法分析器实验(Java)

详细代码请见同名文件

Syntax Analyzer Programming: BASING ON THE LA MADE IN RROJECT1

文章目录

  • Syntax Analyzer Programming: BASING ON THE LA MADE IN RROJECT1
    • a)Aim
    • b)Content Description
    • c)Ideas/Methods
    • d)Assumptions
      • 1. Lexical analyzer based on Project 1
      • 2. Based on the C syntax subset
    • e)CFG
      • 1. Eliminate the left common factor
      • 2. Eliminate the left recursion
      • 3.Work out the FIRST set
      • 4. Work out the FOLLOW set
      • 5.Conduct the LL(1)table
    • f)Description of important Software Architecture
    • g)Discription of core Algorithms
    • h)Use cases on running
      • Use case without errors
      • Use case with grammatical mistakes

a)Aim

Enhance the understanding of parser by implementing PDA.

b)Content Description

1)Input
Stream of characters
CFG(Combination of CFGs of some classes of sentences)
2)Output
Sequence of derivations if top-down syntax analyzing methods are used.
Sequence of reductions if bottom-up syntax analyzing methods are used.
3)Classes of sentences are defined by yourself
4)Error handling may be included

c)Ideas/Methods

What is the things should be done to construct a PARSER:

  • Construct a LL (1) table。

  • Get the Token continuously from the Analyzer constructed in the Project 1.

  • Match the token got with the head of the stack. If it matches, get the next token, else, refer to the table to find a production till there are no productions to choose.

d)Assumptions

1. Lexical analyzer based on Project 1

2. Based on the C syntax subset

我在网上找到了一个C语言语法子集:

<程序> → <语句><程序> | Ɛ;
<语句> → <变量定义语句> | <赋值语句> | <函数调用语句> | | <循环语句> | Ɛ
<变量定义语句> → <变量类型><标识符表>;
<赋值语句> → <标识符> = <表达式>;
<函数调用语句> → <标识符> ( <标识符表> );
→ if ( <条件表达式> ) { <语句> }
→ else{ <语句> } | Ɛ
<循环语句> → while ( <条件表达式> ) { <语句> }
<标识符表> → <标识符>| <标识符表>,<标识符>
<条件表达式> → <表达式><比较运算符><表达式>
<比较运算符> → > | >= | < | <= | != | ==
<变量类型>→ char | short | int | long | float | double
<表达式> → +T | -T | T | <表达式> + T | <表达式>-T
T → F | T*F | T/F
F → <标识符> | <无符号整数> | (<表达式 >)

e)CFG

将中文描述用英文非终结符替换,替换如下:

S' →程序
S  →语句
Q  →else语句
L  →标识符表
E  →表达式
X  →条件表达式
R  →比较运算符
id →标识符
num→常量

替换结果文法产生式为:

S' → S S'| Ɛ
S → A L; | id=E; | id(L); | if(X){S}Q | while(X){S} | Ɛ
A → char | short | int | long | float | double
Q → else{S} | Ɛ
L → id | L , id
X → ERE
R → > | >= | < | <= | == | !=
E → +T | -T | T | E+T | E-T
T → F | T*F | T/F
F → id | num | (E)

Cause that LL (1) recursive descent method is used, the left recursion should be eliminated and the common left factor extracted.

1. Eliminate the left common factor

S’ → S S’| Ɛ
S → A L; | id B | if(X){S}Q | while(X){S} | Ɛ
A → char | short | int | long | float | double
B → (L); | =E;
L → id | L , id
Q → else{S} | Ɛ
X → ERE
R → > | >= | < | <= | == | !=
E → +T | -T | T | EM
M → +T | -T
T → F | TN
N → *F |/F
F → id | num | (E)

2. Eliminate the left recursion

S’ → S S’
S’ → Ɛ
S → A L;
S → id B
S → if(X){S}Q
S → while(X){S}
S → Ɛ
B → (L);
B → =E;
L → id L’
L’→ , id L’
L’→ Ɛ
Q → else{S}
Q → Ɛ
X → ERE
E → TE’
E → +TE’
E → -TE’
E’ → ME’
E’ → Ɛ
M → +T
M → -T
T → FT’
T’ → NT’
T’ → Ɛ
N → *F
N → /F
F → id
F → num
F → (E)
R → >
R → >=
R → <
R → <=
R → ==
R → !=
A → char
A → short
A → int
A → long
A → float
A → double

3.Work out the FIRST set

First(S’)={ char , short , int , long , float , double , id , if , while , Ɛ }
First(S)={ char , short , int , long , float , double , id , if , while , Ɛ }
First(A)={ char , short , int , long , float , double }
First(B)={ ( , = }
First(L)={ id }
First(L’)={, Ɛ }
First(Q)={ else , Ɛ }
First(X)={ + , - , id , num , ( }
First(R)={ > , >= , < , <= , != , == }
First(E)={ + , - , id , num , ( }
First(E’)={ + , - , Ɛ }
First(M)={ + , - }
First(T)={ id , num , ( }
First(T’)={ * , / , Ɛ }
First(N)={ * , / }
First(F)={ id , num , ( }

4. Work out the FOLLOW set

Follow (S’)={ $ }
Follow (S)={ $ , } }
Follow (B)={ $ , } }
Follow (L)={ $ , ) , ; , } }
Follow (L’)={ $ , ) , ; , } }
Follow (Q)={ $ , } }
Follow (X)={ ) }
Follow (R)={ + , - , id , num , ( }
Follow (E)={ ) , ; , > , >= , < , <= , != , == }
Follow (E’)={ ) , ; , > , >= , < , <= , != , == }
Follow (M)={ ) , ; , > , >= , < , <= , != , == , + , - }
Follow (T)={ ) , ; , > , >= , < , <= , != , == , + , - }
Follow (T’)={ ) , ; , > , >= , < , <= , != , == , + , - }
Follow (N)={ ) , ; , > , >= , < , <= , != , == , + , - , * , / }
Follow (F)={ ) , ; , > , >= , < , <= , != , == , + , - , * , / }

5.Conduct the LL(1)table

LL(1) 预测分析表中的数字分别代表的产生式如下:

0:S → A L;
1:S → id B
2:S → if(X){P}Q
3:S → while(X){P}
4:S → Ɛ
5:B → (L);
6:B → =E;
7:L → id L’
8:L’→ ,id L’
9:L’→ Ɛ
10:Q → else{S}
11:Q → Ɛ
12:X → ERE
13:E → +TE’
14:E → -TE’
15:E → TE’
16:E’→ ME’
17:E’→ Ɛ
18:M → +T
19:M → -T
20:T → FT’
21:T’→ NT’
22:T’→ Ɛ
23:N → *F
24:N → /F
25:F → id
26:F → num
27:F → (E)
28:R → >
29:R → >=
30:R → <
31:R → <=
32:R → ==
33:R → !=
34:S’ → S S’
35:S’ → Ɛ
36:A → char
37:A → short
38:A → int
39:A → long
40:A → float
41:A → double
id num if else while + - * / > >= < <= == != ; , ( ) { } = char short int long float double $
S 1 2 3 4 35
S’ 34 34 34 34 34 34 34 34 34 34
A 36 37 38 39 40 41
B 5 6
L 7
C 9 8 9 9 9
Q 10 11 11
X 12 12 12 12 12
E 15 15 13 14 15
D 16 16 17 17 17 17 17 17 17 17
M 18 19
T 20 20 20
H 22 22 21 21 22 22 22 22 22 22 22 22
N 23 24
F 25 26 27
R 28 29 30 31 32 33

f)Description of important Software Architecture

|---ll1Table() 根据g)中的LL1表通过switch控制流进行状态转移的实现
|---initMap() 将Token编码和符号对应
|---intiProductions() 提供42个产生式,属性包括产生式左侧、产生式右侧、产生式描述
|---executeGra() 实现整个GrammarAnalyzer的程序控制

g)Discription of core Algorithms

public void executeGra(String strLex) throws Exception {
    int index = 0;
    initMap();
    initProductions();
    readToReader(strLex);//将String字符串转为token的标号存储
    stack.push(String.valueOf(mapS2i.get("$")));
    stack.push("S'");//此时语法栈为 S'$

    List<GraStack> stackItems = new ArrayList<>();
    while (!stack.isEmpty()) {
        GraStack graStack = new GraStack();
        graStack.setNum(++index);
        // 读取当前栈
        graStack.setCurrStack(getCurrStack());
        // 读取待读队列
        graStack.setUnread(getUnread());
        // 判断是否匹配
        if (!match()) {
            int i = ll1Table();
            if (i >= 0) {
                stackPush(productions[i]);
                graStack.setCandidate(productions[i].prod);
            } else {
                //没有Follow集相关的产生式,语法分析错误
                throw new Exception("语法分析错误,无匹配的产生式\n当前语法栈为:"+graStack.getCurrStack()+"\n当前字符串为:"+graStack.getUnread());
            }
        }else {
            //若匹配则reader指针向后移位
            graStack.setCandidate("move forward");
        }
        //记录每次ACTION
        stackItems.add(graStack);
    }
    int size=stackItems.size();
    for(int i=0;i<size;i++){
       GraStack gs=stackItems.get(i);
        String result=String.format("%18s %18s",gs.getCurrStack(),gs.getCandidate());
        System.out.printf("%d %s    %s\n",gs.getNum(),result,gs.getUnread());
    }
}

h)Use cases on running

Use case without errors

int a;
a=1;
float b;
b=2.0;
if(a<b){
    a=b+1;
}else{
    b=2;
}
while(a==10){
    a=a/1;
}

Result

(3,int)
(20,a)
(49,;)
(20,a)
(31,=)
(30,1)
(49,;)
(5,float)
(20,b)
(49,;)
(20,b)
(31,=)
(30,2.0)
(49,;)
(9,if)
(41,()
(20,a)
(34,<)
(20,b)
(42,))
(45,{)
(20,a)
(31,=)
(20,b)
(37,+)
(30,1)
(49,;)
(46,})
(10,else)
(45,{)
(20,b)
(31,=)
(30,2)
(49,;)
(46,})
(11,while)
(41,()
(20,a)
(32,==)
(30,10)
(42,))
(45,{)
(20,a)
(31,=)
(20,a)
(40,/)
(30,1)
(49,;)
(46,})
------------Start Syntax Analyzing--------------
NUM      CURRENT STACK SELECTED PRODUCTION    UNREAD STRING
1                S'$           S' → SS'    int id ; id = num ; float id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
2               SS'$           S → A L;    int id ; id = num ; float id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
3             AL;S'$            A → int    int id ; id = num ; float id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
4           intL;S'$       move forward    int id ; id = num ; float id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
5              L;S'$          L → id L'    id ; id = num ; float id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
6           idL';S'$       move forward    id ; id = num ; float id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
7             L';S'$             L' → ε    ; id = num ; float id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
8               ;S'$       move forward    ; id = num ; float id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
9                S'$           S' → SS'    id = num ; float id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
10               SS'$           S → id B    id = num ; float id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
11             idBS'$       move forward    id = num ; float id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
12               BS'$            B → =E;    = num ; float id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
13             =E;S'$       move forward    = num ; float id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
14              E;S'$            E → TE'    num ; float id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
15            TE';S'$            T → FT'    num ; float id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
16          FT'E';S'$            F → num    num ; float id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
17        numT'E';S'$       move forward    num ; float id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
18           T'E';S'$             T' → ε    ; float id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
19             E';S'$             E' → ε    ; float id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
20               ;S'$       move forward    ; float id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
21                S'$           S' → SS'    float id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
22               SS'$           S → A L;    float id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
23             AL;S'$          A → float    float id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
24         floatL;S'$       move forward    float id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
25              L;S'$          L → id L'    id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
26           idL';S'$       move forward    id ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
27             L';S'$             L' → ε    ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
28               ;S'$       move forward    ; id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
29                S'$           S' → SS'    id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
30               SS'$           S → id B    id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
31             idBS'$       move forward    id = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
32               BS'$            B → =E;    = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
33             =E;S'$       move forward    = num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
34              E;S'$            E → TE'    num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
35            TE';S'$            T → FT'    num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
36          FT'E';S'$            F → num    num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
37        numT'E';S'$       move forward    num ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
38           T'E';S'$             T' → ε    ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
39             E';S'$             E' → ε    ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
40               ;S'$       move forward    ; if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
41                S'$           S' → SS'    if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
42               SS'$      S → if(X){S}Q    if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
43       if(X){S}QS'$       move forward    if ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
44         (X){S}QS'$       move forward    ( id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
45          X){S}QS'$            X → ERE    id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
46        ERE){S}QS'$            E → TE'    id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
47      TE'RE){S}QS'$            T → FT'    id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
48    FT'E'RE){S}QS'$             F → id    id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
49   idT'E'RE){S}QS'$       move forward    id < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
50     T'E'RE){S}QS'$             T' → ε    < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
51       E'RE){S}QS'$             E' → ε    < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
52         RE){S}QS'$              R → <    < id ) { id = id + num ; } else { id = num ; } while ( id == num ) { id = id / num ; } $ 
53         

Use case with grammatical mistakes

int a;
a=1;
float b;
b=2.0==1;//错误语法
if(a<b){
a=b+1;}
else{
b=2;
}
while(a==10){
a=a/1;
}

你可能感兴趣的:(编译原理,java,软件工程)