Tải bản đầy đủ (.doc) (27 trang)

BÁO CÁO BÀI TẬP LỚN CHƯƠNG TRÌNH DỊCH

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (181.27 KB, 27 trang )

BÁO CÁO BÀI TẬP LỚN
NHÓM: 14
Thành viên nhóm: Nguyễn Thị Ngọc Bích
Ngô Thị Chiên
Nguyễn Thị Thu Hải
Nguyễn Thị Lê Hồng
Giáo viên hướng dẫn: Phan Thị Thu Hồng
Đề số 3
Viết trình biên dịch để dịch 1 đoạn chương trình gồm các phát biểu sau sang
mã 3 địa chỉ:
- Phát biểu ghép, gán, while do trong Pascal
- Các phát biểu kết thúc bằng dấu ;
- Các biểu thức trong các phát biểu là các biểu thức số học và logic, gồm
các phép toán +, -, *, / và các phép so sánh. Các toán hạng gồm các danh
hiệu, hằng số thực, nguyên, true, false (kể cả biểu thức). Độ ưu tiên các phép
toán tương tự Pascal.
- Thực hiện chuyển đổi kiểu từ nguyên sang thực khi cần thiết.
- Các danh hiệu phải khai báo trước.
Yêu cầu:
- Viết chương trình bằng tay.
- Quá trình phân tích cú pháp được thực hiện theo phương pháp từ dưới lên
- Giai đoạn xử lý ngữ nghĩa sinh viên phải thực hiện bằng cách đặt các hành
vi ngữ nghĩa vào bản đặc tả cú pháp.
I.
I.
PHÂN TÍCH TỪ VỰNG
PHÂN TÍCH TỪ VỰNG
1.Tìm hiểu các lệnh trong Pascal
a. Lệnh gán (Assignment statement)
Một trong các lệnh đơn giản và cơ bản nhất của Pascal là lệnh gán. Mục đích
của lệnh này là gán cho một biến đã khai báo một giá trị nào đó cùng kiểu


với biến.
* Ý nghĩa:
Biến và các phát biểu gán là các khái niệm quan trọng của một họ các ngôn
ngữ lập trình mà Pascal là một đại diện tiêu biểu. Chúng phản ánh cách thức
hoạt động của máy tínhhiện nay, đó là:- Lưu trữ các giá trị khác nhau vào
một ô nhớ tại những thời điểm khác nhau Một quá trình tính toán có thể coi
như là một quá trình làm thay đổi giá trị của một (haymột số) ô nhớ nào đó,
cho đến khi đạt được giá trị cần tìm.
b. Lệnh ghép (Compound statement)
Một nhóm câu lệnh đơn được đặt giữa 2 chữ BEGIN và END sẽ tạo thành
một câu lệnhghép.Trong Pascal ta có thể đặt các lệnh ghép con trong các
lệnh ghép lớn hơn bao ngoài của nó và có thể hiểu tương tự như cấu trúc
ngoặc đơn ( ) trong các biểu thức toán học.
Một khối lệnh bắt đầu bằng BEGIN và chấm dứt ở END; . Trong một khối
lệnh cũng có thể có các khối lệnh con nằm trong nó. Một khối chương trình
thường được dùng để nhóm từ 2 lệnh trở lên để tạo thành một của các lệnh
có cấu trúc.
c. Lệnh WHILE DO
Trong khi mà điều kiện còn đúng thì cứ thực hiện Công việc, rồi quay trở về kiểm tra
điều kiện lại. Vòng lặp được tiếp tục, đến khi điều kiện đặt ra không còn
đúng nữa thì đi tới thực hiện lệnh tiếp theo.
* Cú pháp
WHILE <điều kiện> DO
Ghi chú:· Ðiều kiện trong cấu trúc lặp WHILE DO là một biểu thức logic
kiểu Booleanchỉ có 2 giá trị là Ðúng (True) hoặc Sai (False)· Nếu điều kiện
Ðúng thì chương trình sẽ chạy trong cấu trúc WHILE DO.· Sau mỗi lần
lặp, chương trình trở lại kiểm tra điều kiện. Tùy theo biểu thức logiccủa điều
kiện là Ðúng hay Sai thì chương trình sẽ thực hiện Công việc tương ứng.·
Nếu Sai thì chuyển xuống dưới cấu trúc WHILE DO
d. Biểu thức lôgic

Các biểu thức lôgic đơn giản, các biểu thức quan hệ liên kết với nhau bởi
phép toán lôgic tạo thành biểu thức lôgic.
- Biểu thức lôgic đơn giản là biến lôgic hoặc hằng lôgic.
- Các biểu thức quan hệ phải được đặt trong cặp dấu ( ).
- Giá trị biểu thức lôgic là TRUE hoặc FALSE.
Ví dụ 1:
( 5< X) AND (X <=100)
Kết quả: TRUE
Nếu X = 50
Ví dụ 2:
NOT( X > 9)
Nếu X = 2
Kết quả: FALSE
e. Biểu thức số học
Ví dụ:
Được tạo bởi:
Một biến hoặc một hằng kiểu nguyên hay thực;
- Các biến hay hằng liên kết với nhau bởi các phép toán số học, các dấu
ngoặc tròn.
-Trong PasCal
Biểu thức trong toán học
5*a – (2*b + 3)
5a – (2b + 3)
x*y/(5 + x)
3*x*x*x – (2 + x)*y*y
* Trình tự thực hiện:
Lần lượt từ trái sang phải.
- Thực hiện các phép toán trong ngoặc tròn trước.
- Dãy các phép toán không chứa ngoặc thực hiện từ trái sang phải
theo thứ tự:

+ Các phép toán * /
+ Các phép toán + - thực hiện sau.
Biểu thức chứa một hằng hay biến kiểu thực là biểu thức số học thực, giá trị
biểu thức có kiểu thực
2.BẢNG TOKEN
2.BẢNG TOKEN
Token Lexeme Thông tin mô tả pattern Attribute
id a1,d_e3c,ba2, (letter|’_’)(letter|digit|’_’)* vtrí BDB
Assign := ‘:=’
Semi ; ‘;’
Colon : ‘:’
Var Var, var , (‘v’|’V’)(‘a’|’A’)(‘r’|’R’)
Begin beGin,Begin, (‘b’|’B’)(‘e’|’E’)(‘g’|’G’)
(‘i’|’I’)(‘n’|’N’)
DOT .
End End,end, eNd, (‘e’|’E’)(‘n’|’N’)(‘d’|’D’)
WHIlE While,while… (‘w’|’W’)(‘h’|’H’)(‘i’|’I’)
(‘l’|’L’)(‘e’|’E’)
DO Do,DO,do (‘D’|’d’)(‘o’|’O’)
NOT not,Not,… (‘n’|’N’) (‘o’|’O’) (‘t’|’T’)
AND and,And,… (‘a’|’A’) (‘n’|’N’) (‘d’|’D’)
OR or,Or,… (‘o’|’O’) (‘r’|’R’)
Program PROGRAM,
program
(‘p’|’P’)(‘o’|’O’)(‘r’|’R’)
(‘g’|’G’)(‘a’|’A’)
Lpar ( ‘(‘
Rpar ) ‘)’
TYPE Integer, iNteger,


Real, rEal, …
Boolean, bOolean,

(‘i’|’I’)(‘n’|’N’)(‘t’|’T’)(‘e’|’E’)
(‘g’|’G’)(‘e’|’E’) (‘r’|’R’) |
(‘r’|’R’)(‘e’|’E’)(‘a’|’A’)(‘l’|’L’)
|
(‘b’|’B’)(‘o’|’O’)(‘o’|’O’)
(‘l’|’L’)(‘e’|’E’)(‘a’|’A’)
(‘n’|’N’)
Integer
Real
Boolean
True TRUE,TrUE,true

(‘T’|’t’)(‘R’|’r’)(‘U’|’u’)(‘e’|’E’)
False FALSE,False,
false….
(‘F’|’f’)(‘A’|’a’)(‘L’|’l’)(‘S’|’s’)
(‘e’|’E’)
Num 1,33,10,490,… digit(digit)* vtrí BDB
NumReal 1.2, 2E-3 ,0.5e+4
digit
+
.digit
+
| digit
+
(.digit
+

|∈)
(‘e’|’E’)(‘+’|’- ‘|∈)digit
+
vtrí BDB
OP1 +,- ‘+’, ‘-‘ plus,minus
OP2 *,/ ‘+’, ‘-‘ ‘*’,’/’ multi,div
Relop
=, <, >, <=, >=,
<>
‘=’, ’<’, ’>’, ’<=’, ’>=’, ’<>’
EQ, LT, GT,
LE,GE,NE
letter → ‘a’| |’z’|’A’| |’Z’
digit → ‘0’| |’9’
delim→ blank | tab |newline
id → letter(letter|digit)*
ws → delim
+
endline → newline
unsco → “_”
 Ghi chú:
- BDB: bảng danh biểu.
- Các từ khóa(keyword) được insert vào bảng danh biểu trước khi phân tích từ
vựng.
- Thứ tự ưu tiên của các phép toán trong Pascal (tương ứng với các phép toán đề
bài đưa ra):
• Dấu ngoặc ( )
• Phép toán một ngôi: NOT.
• Phép toán *, /, AND.
• Phép toán +, -, OR

• Phép toán so sánh =, <, >, <=, >=, <>
LƯỢC ĐỒ DỊCH
LƯỢC ĐỒ DỊCH
*
*
Sơ đồ dịch nhận dạng token relop:
Sơ đồ dịch nhận dạng token relop:
*
*
Start
0
2
1
return(relop, LE)
3
4
return(relop, NE)
return(relop, LT)
5
6
7
8
return(relop, EQ)
return(relop, EG)
return(relop, GT)
< =
>
other
=
=>

other


Sơ đồ dịch của id và từ khóa:
Sơ đồ dịch của id và từ khóa:
id → letter(letter|digit)*
Ghi chú: * lặp lại không hoặc nhiều lần


Sơ đồ dịch nhận dạng hằng số:
Sơ đồ dịch nhận dạng hằng số:
NumReal→digit
+
(.digit
+
)? (E ( + | -) ? digit
+
) ?
NumReal→digit
+
.digit
+
Num→digit
+
Ghi chú:
+ lặp lại một hoặc nhiều lần
? lặp lại không hoặc 1 lần
Start
letter | digit
|‘_’

letter
return(id, lookup(id))
other
9 1
0
11
*
*
*
1
4
19
‘.’
other
return(numreal,vtrbdb)
digit
digit

‘+’|’-‘
1
7
1
8
digit
‘E’ |’e’
1
5
1
6
digit

return(numreal,vtr bdb)
digit
other
21
other
*
*
‘E’ |’e’
Start
digit
1
3
digit
1
2
20
other
return(num,vtrbdb)
return(num,vtr bdb)
22
Sơ đồ dịch nhận dạng khoảng trắng:
II. PHÂN TÍCH CÚ PHÁP
1.Các luật sinh
s → program
1) program → khaibao body Dot
2) program → body
3) khaibao → VAR n_khaibao
4) n_khaibao → kbkieu SEMI n_khaibao // x:integer ; y:real
5) n_khaibao → kbkieu
6) kbkieu→ n_id COLON TYPE SEMI // x:integer

7) n_id → ID COMMA n_id
8) n_id → ID
9) body → BEGIN n_lenh END SEMI
10) n_lenh → lenh SEMI n_lenh
11) n_lenh → lenh SEMI
12) lenh → pgan
13) lenh → body
14) lenh → lenh_While_do
15) pgan → ID ASSGN exp SEMI
16) lenh_While_do → While while_body do body
17) while_body → dieukien1
18) while_body → dieukien2
19) dieukien1 → dieukien1 AND dieukien3
20) dieukien1 → dieukien1 OR dieukien3
21) dieukien1 → NOT dieukien3
22) dieukien1 → dieukien3
23) dieukien3 → LPARA dieukien4 RPARA
Start
delim
delim
other
2
3
2
4
25
*
24) dieukien2 → dieukien4
25) dieukien4→ dieukien4 RELOP exp
26) dieukien4→ exp

27) exp → exp OP1 term
28) exp → term
29) term → term OP2 factor
30) term → factor
31) factor → ID
32) factor → NUM
33) factor→NUM DOT NUM //chuyển đổi kiểu từ số nguyên sang số thực
34) factor → NUMREAL
35) factor → LPARA exp RPARA
36) factor → OP1 factor
37)factor -> TRUE
38)factor -> FALSE
2.Các ký hiệu kết thúc

1.VAR
2.COLON //:
3.TYPE
4.SEMI //;
5.ID
6.COMMA //,
7.BEGIN
8.END
9.ASSGN //:=
10.WHILE
11.DO
12.AND
13.OR
14.NOT
15.RELOP
16.OP1

17.OP2
18.NUM
19.NUMREAL
20.LPARA //(
21.RPARA //)
22.DOT //.
23.TRUE
24.FALSE
25. $
3.Các ký hiệu không kết thúc

1.program
2.khaibao
3.body
4.n_khaibao
5.kbkieu
6.n_id
7.n_lenh
8.lenh
9.pgan
10.lenh_While_do
11.While_body
12.dieukien1
13.dieukien2
14.dieukien3
15.dieukien4
16.exp
17.term
18.factor
4. First của những ký hiệu không kết thúc

1. first(program) ={var,begin}
2. first(khaibao)={var}
3. first(body)={begin}
4. first(n_khaibao)={ID}
5. first(kbkieu)={ID}
6. first(n_id)={ID}
7. first(n_lenh)={begin,ID,while}
8. first(lenh)={begin,ID,while}
9. first(pgan)={ID}
10.first(lenh_While_do)={while}
11.first(While_body)={not,Lpara,ID,Num,Numreal,OP1,True,False}
12.first(dieukien1)={not,Lpara}
13.first(dieukien2)={ID,num,numreal,Lpara,OP1,True,False}
14.first(dieukien3)={Lpara}
15.first(dieukien4)= {ID,num,numreal,Lpara,OP1,True,False}
16.first(exp)= {ID,num,numreal,Lpara,OP1,True,False}
17.first(term)= {ID,num,numreal,Lpara,OP1,True,False}
18.first(factor)= {ID,num,numreal,Lpara,OP1,True,False}
5. Follow của những ký hiệu không kết thúc
1. Follow(program)={$}
2. Follow(khaibao)={$}
3. Follow(body)={SEMI,DOT,$}
4. Follow(n_khaibao)={$}
5. Follow(kbkieu)={SEMI,$}
6. Follow(n_id)={COLON,$}
7. Follow(n_lenh)={End,$}
8. Follow(lenh)={SEMI,$}
9. Follow(pgan)={SEMI,$}
10.Follow(lenh_While_do)={SEMI,$}
11.Follow(While_body)={do,$}

12.Follow(dieukien1)={do,and,or,$}
13.Follow(dieukien2)={do,$}
14.Follow(dieukien3)={do,and,or,$}
15.Follow(dieukien4)={do,Rpara,relop,$}
16.Follow(exp)={OP1,do,Rpara,Relop,SEMI,$}
17.Follow(term)={OP1,OP2,do,Rpara,relop,SEMI,$}
18.Follow(factor)={OP1,OP2,do,Rpara,relop,SEMI,$}
6. Tính các tập tuyển
I0:
S→.program
program→.khaibao body dot
program→.body
khaibao→.Var n_khaibao
body→.Begin n_lenh End SEMI
I1=goto(I0,program)
S→program.

I2=goto(I0,khaibao)
program→khaibao.body dot
body→.Begin n_lenh End SEMI
I3=goto(I0,body)
program→body.

I4=goto(I0,Var)
khaibao→Var. n_khaibao
n_khaibao →. kbkieu SEMI n_khaibao
n_khaibao →. kbkieu
kbkieu→ .n_id COLON TYPE SEMI
n_id →. ID COMMA n_id
n_id →. ID

I5=goto(I0,Begin)
body→Begin .n_lenh End SEMI
n_lenh →. lenh SEMI n_lenh
n_lenh → .lenh SEMI
lenh → .pgan
lenh → .body
body→.Begin n_lenh End SEMI
lenh →. lenh_While_do
pgan → .ID ASSGN exp SEMI
lenh_While_do → .While while_body do body
I6=goto(I2,body)
program→khaibao body .dot
goto(I2,Begin)=I5
I7=goto(I4,n_khaibao)
khaibao→Var n_khaibao.
I8=goto(I4,kbkieu)
n_khaibao → kbkieu. SEMI n_khaibao
n_khaibao →kbkieu.
I9=goto(I4,n_id)
kbkieu→ n_id .COLON TYPE SEMI
I10=goto(I4,id)
n_id →ID . COMMA n_id
n_id → ID .
I11=goto(I5,n_lenh)
body→Begin n_lenh .End SEMI
I12=goto(I5,lenh)
n_lenh →lenh .SEMI n_lenh
n_lenh → lenh .SEMI

I13=goto(I5,pgan)

lenh → pgan .
I14=goto(I5,body)
lenh → body .
goto(I5,Begin)=I5
I15=goto(I5,lenh_While_do)
lenh →lenh_While_do .
I16=goto(I5,ID)
pgan → ID .ASSGN exp SEMI
I17=goto(I5,While)
lenh_While_do → While . while_body do body
while_body → .dieukien1
while_body → .dieukien2
dieukien1 → .dieukien1 AND dieukien3
dieukien1 → .dieukien1 OR dieukien3
dieukien1 → .NOT dieukien3
dieukien1 → .dieukien3
dieukien3 → .LPARA dieukien4 RPARA
dieukien2 → .dieukien4
dieukien4→ .dieukien4 RELOP exp
dieukien4→ .exp
exp → .exp OP1 term
exp → .term
term → .term OP2 factor
term → .factor
factor → .ID
factor → .NUM
factor→.NUM DOT NUM
factor → .NUMREAL
factor → .LPARA exp RPARA
factor → .OP1 factor

factor -> .TRUE
factor -> .FALSE
I18=goto(I6,dot)
program→khaibao body dot.
I19=goto(I8,SEMI)
n_khaibao → kbkieu SEMI .n_khaibao
n_khaibao → .kbkieu SEMI n_khaibao
n_khaibao → .kbkieu
kbkieu→ .n_id COLON TYPE SEMI
n_id → .ID COMMA n_id
n_id → .ID
I20=goto(I9,COLON)
kbkieu→ n_id COLON .TYPE SEMI

I21=goto(I10,COMMA)
n_id →ID COMMA .n_id
n_id → .ID COMMA n_id
n_id → .ID
I22=goto(I11,End)
body→Begin n_lenh End .SEMI
I23=goto(I12,SEMI)
n_lenh →lenh SEMI .n_lenh
n_lenh → lenh SEMI .
n_lenh → .lenh SEMI n_lenh
n_lenh → .lenh SEMI
I24=goto(I16,ASSGN)
pgan → ID ASSGN .exp SEMI
exp → .exp OP1 term
exp → .term
term → .term OP2 factor

term → .factor
factor → .ID
factor → .NUM
factor→.NUM DOT NUM
factor → .NUMREAL
factor → .LPARA exp RPARA
factor → .OP1 factor
factor -> .TRUE
factor -> .FALSE
I25=goto(I17,While_body)
lenh_While_do → While while_body .do body
I26=goto(I17,dieukien1)
while_body → dieukien1 .
dieukien1 → dieukien1 . AND dieukien3
dieukien1 → dieukien1 .OR dieukien3
.
I27=goto(I17,NOT)
dieukien1 →NOT .dieukien3
dieukien3 → .LPARA dieukien4 RPARA
I28=goto(I17,dieukien3)
dieukien1 → dieukien3.
I29=goto(I17,Lpara)
dieukien3 → LPARA. dieukien4 RPARA
factor → LPARA .exp RPARA
dieukien4→ .dieukien4 RELOP exp
dieukien4→ .exp
exp → .exp OP1 term
exp → .term
term → .term OP2 factor
term → .factor

factor → .ID
factor → .NUM
factor→.NUM DOT NUM
factor → .NUMREAL
factor → .LPARA exp RPARA
factor → .OP1 factor
factor -> .TRUE
factor -> .FALSE
I30=goto(I17,dieukien4)
dieukien2 → dieukien4.
dieukien4→ dieukien4 .RELOP exp
I31=goto(I17,exp)
dieukien4→ exp.
exp → exp .OP1 term
I32=goto(I17,term)
exp → term.
term → term .OP2 factor
I33=goto(I17,factor)
term → factor.
I34=goto(I17,ID)
factor → ID.
I35=goto(I17,NUM)
factor → NUM.
factor→NUM .DOT NUM
I36=goto(I17,NUMREAL)
factor → NUMREAL.
I37=goto(I17,OP1)
factor → OP1 .factor
factor → .ID
factor → .NUM

factor→.NUM DOT NUM
factor → .NUMREAL
factor → .LPARA exp RPARA
factor → .OP1 factor
factor -> .TRUE
factor -> .FALSE
I38=goto(I17,True)
factor -> TRUE.
I39=goto(I17,False)
factor -> FALSE.
I40=goto(I19,n_khaibao)
n_khaibao → kbkieu SEMI n_khaibao.
Goto(I19,kbkieu)=I8
Goto(I19,n_id)=I9
Goto(I19,id)=I10
I41=goto(I20,TYPE)
kbkieu→ n_id COLON TYPE .SEMI
I42=goto(I21,n_id)
n_id →ID COMMA n_id.
Goto(I21,ID)=I10
I43=goto(I22,SEMI)
body→Begin n_lenh End SEMI .
I44=goto(I23,n_lenh)
n_lenh →lenh SEMI n_lenh.
Goto(I23,lenh)=I12
I45=goto(I24,exp)
pgan → ID ASSGN exp .SEMI
exp → exp .OP1 term
goto(I24,term)=I32
goto(I24,factor)=I33

goto(I24,ID)=I34
goto(I24,NUM)=I35
goto(I24,NUMREAL)=I36
I46=goto(I24,Lpara)
factor → LPARA .exp RPARA
exp → .exp OP1 term
exp → .term
term → .term OP2 factor
term → .factor
factor → .ID
factor → .NUM
factor→.NUM DOT NUM
factor → .NUMREAL
factor → .LPARA exp RPARA
factor → .OP1 factor
factor -> .TRUE
factor -> .FALSE
goto(I24,OP1)=I37
goto(I24,True)=I38
goto(I24,False)=I39
I47=goto(I25,do)
lenh_While_do → While while_body do .body
body → .BEGIN n_lenh END SEMI
I48=goto(I26,And)
dieukien1 → dieukien1 AND .dieukien3
dieukien3 → .LPARA dieukien4 RPARA
I49=goto(I26,OR)
dieukien1 → dieukien1 OR .dieukien3
dieukien3 → .LPARA dieukien4 RPARA
I50=goto(I27,dieukien3)

dieukien1 →NOT dieukien3.
goto(I27,Lpara)=I29
I51=goto(I29,dieukien4)
dieukien3 → LPARA dieukien4 . RPARA
dieukien4→ dieukien4 .RELOP exp

I52=goto(I29,exp)
factor → LPARA exp .RPARA
dieukien4→ exp.
exp → exp . OP1 term
goto(I29,term)=I32
goto(I29,factor)=I33
goto(I29,ID)=I34
goto(I29,NUM)=I35
goto(I29,NUMREAL)=I36
goto(I29,Lpara)=I46
goto(I29,OP1)=I37
goto(I29,True)=I38
goto(I29,False)=I39
I53=goto(I30,Relop)
dieukien4→ dieukien4 RELOP .exp
exp → .exp OP1 term
exp → .term
term → .term OP2 factor
term → .factor
factor → .ID
factor → .NUM
factor→.NUM DOT NUM
factor → .NUMREAL
factor → .LPARA exp RPARA

factor → .OP1 factor
factor -> .TRUE
factor -> .FALSE
I54=goto(I31,OP1)
exp → exp OP1 .term
term → .term OP2 factor
term → .factor
factor → .ID
factor → .NUM
factor→.NUM DOT NUM
factor → .NUMREAL
factor → .LPARA exp RPARA
factor → .OP1 factor
factor -> .TRUE
factor -> .FALSE
I55=goto(I32,OP2)
term → term OP2 . factor
factor → .ID
factor → .NUM
factor→.NUM DOT NUM
factor → .NUMREAL
factor → .LPARA exp RPARA
factor → .OP1 factor
factor -> .TRUE
factor -> .FALSE
I56=goto(I35,Dot)
factor→NUM DOT .NUM
I57=goto(I37,factor)
factor → OP1 factor.
Goto(I37,ID)=I34

goto(I37,NUM)=I35
goto(I37,NUMREAL)=I36
goto(I37,Lpara)=I46
goto(I37,OP1)=I37
goto(I37,True)=I38
goto(I37,False)=I39
I58=goto(I41,SEMI)
kbkieu→ n_id COLON TYPE SEMI.
I59=goto(I45,SEMI)
pgan → ID ASSGN exp SEMI .
goto(I45,OP1)=I54
I60=goto(I46,exp)
factor → LPARA exp . RPARA
exp → exp .OP1 term

goto(I46,term)=I32
goto(I46,factor)=I33
goto(I46,ID)=I34
goto(I46,NUM)=I35
goto(I46,NUMREAL)=I36
goto(I46,Lpara)=I46
goto(I46,OP1)=I37
goto(I46,True)=I38
goto(I46,False)=I39
I61=goto(I47,body)
lenh_While_do → While while_body do body.

Goto(I47,Begin)=I5
I62=goto(I48,dieukien3)
dieukien1 → dieukien1 AND dieukien3.

Goto(I48,Lpara)=I29
I63=goto(I49,dieukien3)
dieukien1 → dieukien1 OR dieukien3.
Goto(I49,Lpara)=I29

I64=goto(I51,Rpara)
dieukien3 → LPARA dieukien4 RPARA.
Goto(I51,Relop)=I53
I65=goto(I52,Rpara)
factor → LPARA exp RPARA.
Goto(I52,OP1)=I54
I70=goto(I53,exp)
dieukien4→ dieukien4 RELOP exp.
exp → exp. OP1 term
goto(I53term)=I32
goto(I53,factor)=I33
goto(I53,ID)=I34
goto(I53,NUM)=I35
goto(I53,NUMREAL)=I36
goto(I53,Lpara)=I46
goto(I53,OP1)=I37
goto(I53,True)=I38
goto(I53,False)=I39
I66=goto(I54,term)
exp → exp OP1 term.
term → term .OP2 factor
goto(I54,factor)=I33
goto(I54,ID)=I34
goto(I54,NUM)=I35
goto(I54,NUMREAL)=I36

goto(I54,Lpara)=I46
goto(I54,OP1)=I37
goto(I54,True)=I38
goto(I54,False)=I39
I67=goto(I55,factor)
term → term OP2 factor.
goto(I55,ID)=I34
goto(I55,NUM)=I35
goto(I55,NUMREAL)=I36
goto(I55,Lpara)=I46
goto(I55,OP1)=I37
goto(I55,True)=I38
goto(I55,False)=I39
I68=goto(I56,NUM)
factor→NUM DOT NUM.
I69=goto(I17,dieukien2)
while_body → dieukien2
goto(I60,Rpara)=I65
goto(I60,OP1)=I54
goto(I66,OP2)=I55
goto(I70,OP1)=I54
* Bảng phân tích cú pháp SLR:

III. PHÂN TÍCH NGỮ NGHĨA
- Giai đoạn phân tích ngữ nghĩa sẽ thực hiện việc kiểm tra xem chương
trình nguồn có chứa lỗi về ngữ nghĩa hay không và tập hợp thông tin về kiểu
cho giai đoạn sinh mã về sau.
- Phân tích ngữ nghĩa gồm 2 nội dung cơ bản:
 Kiểm tra kiểu
 Chuyển đổi kiểu

1. Kiểm tra kiểu
a. Kiểu của biểu thức
type → int {type.type := int}
type → real {type.type := real}
type → boolean {type.type := boolean}
dieukien1→ dieukien1 AND dieukien3
dieukien1 → dieukien1 OR dieukien3
{ dieukien1.type := if
(dieukien3.type = boolean and
dieukien1= boolean) then boolean
else error}
dieukien1 → NOT dieukien3



,
{dieukien1.type := if (dieukien3=
boolean) then boolean else error
exp → exp OP1 term
exp → term

{ exp.type := if (term.type ∉
{int,real} | |exp.type ∉ {int,real})
then error
else if (term.type = exp.type = int
then int else real
term → term OP2 factor
term → factor

{term.type := if (term.type

∉{int,real} | | factor.type ∉
{int,real}) then error
else if (term.type = factor.type = int
then int else real}
factor → id {factor.type := sym_lookup(id.
entry,type)}
sym_lookup(): Hàm tra cứu kiểu trong bảng ký hiệu
b. Kiểu của các lệnh
lenh_While_do → While while_body do body {lenh_While_do.type:=if
(lenh_While_do.type = boolean) then
body.type else error}
pgan → ID ASSGN exp SEMI
{pgan.type := if (id.type = exp.type)
then void else error}
*Chú ý: error – lỗi, void – “không có giá trị” (dùng trong kiểm tra kiểu đối
với lệnh.
2. Chuyến đổi kiểu
IV. Sinh mã 3 địa chỉ
- Mã 3 địa chỉ là một dạng biểu diễn của mã trung gian
- Mã lệnh 3 địa chỉ là một chuỗi các lệnh có dạng tổng quát là:
x := y op z
Trong đó: - x, y, z là tên, hằng hoặc dữ liệu tạm sinh ra trong khi dịch
- op là một toán tử số học hoặc login
1. Sinh mã 3 địa chỉ cho lệnh gán và các biểu thức toán học
pgan → ID ASSGN exp SEMI
pgan.code := exp.code ||
gen (id.place ‘:=’ exp.place)
exp → exp + term
exp.place := newtemp();
exp.code := exp.code || term.code || gen

(exp.place ‘:=’ exp.place ‘+’ term.place)
exp → exp - term exp.place := newtemp();
exp.code := exp.code || term.code || gen
(exp.place ‘:=’ exp.place ‘-’ term.place)
term → term * factor term.place := newtemp();
term.code := factor.code || term.code ||
gen (term.place ‘:=’ factor.place ‘*’
term.place)
term → term / factor term.place := newtemp();
term.code := factor.code || term.code ||
gen (term.place ‘:=’ factor.place ‘/’
term.place)
factor → - factor factor.place := newtemp();
factor.code := factor.code ||
gen (factor.place ‘:=’ ‘uminus’
factor.place)
factor → LPARA exp RPARA factor.place := newtemp();
factor.code := exp.code
factor → id factor.place := id.place;
factor.code := ‘’
*Chú ý:
- E.place: nơi giữ giá trị của E
- E.code: Chuỗi lệnh 3 địa chỉ để đánh giá E
- Hàm newtemp(): Sinh ra tên tạm: t1, t2…
- Hàm gen(): Biểu diễn mã 3 địa chỉ
2. Sinh mã 3 địa chỉ cho biểu thức logic
exp → factor and term factor.true := newlabel();
factor.false := exp.false;
term.true := exp.true;
term.false := exp.false;

exp.code := factor.code
|| gen (exp.true ‘:’)
|| term.code
exp → factor or term factor. true:= exp. true;
factor.false := newlabel();
term.true := exp.true;
term.false := exp.false;
exp.code := factor.code
|| gen (exp.false ‘:’)
|| term.code
exp → not factor factor. true:= exp. false;
factor. false:= exp. true;
exp. code := factor.code
exp → (factor) factor. true:= exp. true;
factor. false:= exp. false;
exp. code := factor.code

×