Báo cáo Chương trình dịchNhóm 3:Nguyễn Thị Ngọc HuyênHoàng Thị Hương Nguyễn Thị NgaNguyễn Thị Phương Thảo Đề 12: 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:
Trang 1Báo cáo Chương trình dịchNhóm 3:
Nguyễn Thị Ngọc HuyênHoàng Thị Hương
Nguyễn Thị NgaNguyễn Thị Phương Thảo
Đề 12:
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:
Phát biểu gán, while trong C
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 gồm các phép toán !, &&, || và cácphép toán so sánh Toán hạng gồm các định danh, hằng số thực vànguyên (kể cả biểu thức) Độ ưu tiên các phép toán tương tự C Cácphép toán kết hợp trái
Thực hiện chuyển đổi kiểu đổi kiểu từ nguyên sang thực khi cần thiết.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ướilên
Giai đoạn xử lý ngữ nghĩa sinh viên phải thực hiện bằng cách đặt cáchành vi ngữ nghĩa vào các bản đặc tả cú pháp
Trang 3*Sơ đồ chuyển tiếp nhận dạng chuỗi ký tự, từ khoá:
* Sơ đồ chuyển tiếp nhận dạng số nguyên, số thực:
* Sơ đồ chuyển tiếp nhận dạng phép gán:
Trang 4* Sơ đồ chuyển tiếp cho các phép toán
1
3
Start
1 4
=
1 5
2 9
2 3
2 6
1
1 8
2 1
1 7
1 6
=+other
=_
+
_
2 20
3 0
2 4
3 1
2 8
2 5 2 7
Trang 5* Sơ đồ chuyển cho các token khác
3
2
Start
3 43
=
3 5
4 1
3 8
4 0
3 9
4 2
3 7
3 6
=other
37
=
return(RELOP,LE)
return(RELOP,LT) return(RELOP,GE)
return(RELOP,GT)
!
return(RELOP,NE)
4 3
other
return(NOT)
4 7
4 5
4 6
4 4
*
*
*
Trang 6 Giải thuật mô phỏng lược đồ dịch để nhận dạng token:
int state; // state: để theo dõi các trạng thái chuyển đổi trên đồ thị chuyển.
int start; // start: trạng thái bắt đầu.
int fail(start)// Hàm fail dùng để trả lại đầu vào của một đồ thị chuyển tiếp theo.
{
switch(start){
case 1: start = 4; break;
case 4: start = 13; break;
case 13: start = 32; break;
case 32: start = 48; break;
case 48: recover(); //gọi hàm xử lý lỗi khi chương trình nguồn có lỗi.
5 3
5 2
5 4
5 1
5 0}
)
;
return(BEGIN)
5 57
return(END) return(LPAR) return(RPAR) return(SEMI),
return(COMA)
5 6
return(COMM)
5 9
5 7
5 8
4 87
/
(
Trang 7ch = nextchar(); //hàm nextchar(): đọc vào ký tự tiếp theo.
if(ch== '_'||isalpha(ch)) state=2; //hàm isalpha(ch): Kiểm tra
ký tự đọc vào có phải là chữ cái hay không.
else state=fail(1);
break;
case 2:
ch = nextchar();
if(!(ch== '_'||isalpha(ch)||isdigit(ch))) state=3;
//hàm isdigit(ch): Kiểm tra ký tự đọc vào có phải là chữ số hay không.
break;
case 3:
retract(1); //Hàm retract(): xử lý các trạng thái có đánh dấu *
install_id(); //Hàm install_id(): kiểm tra ký tự nhập vào là từ khoá hay là một tên biến.
t.type=gettoken(); //Hàm install_id: trả về từ tố là mã của một từ khoá nào đó hoặc chuỗi ký tự tên.
else if(ch=='.') state=6;
else if(ch=='E'||ch=='e') state=8;
else state=10;
break;
case 6:
ch=nextchar();
Trang 9switch(ch){
case'=': state=14; break;case'+': state=15; break;case'-': state=19; break;case'*': state=23; break;case'/': state=26; break;case'%': state=29; break;default: state=fail(13);}
Trang 12case'<': state=35; break;case'>': state=38; break;case'!': state=41; break;case'&': state=44; break;case'|': state=46; break;default: state=fail(32);}
Trang 16} while(exitflag==0);
II Phân tích cú pháp
Trang 17A Văn phạm gia tố
S → main
1 main → MAIN LPAR RPAR body
2 body → BEGIN ct END
10.var → TYPE n_id
11.n_id → ID COMA n_id
12 n_id → ID
13.pbgan → ID ASG exp
14.while → WHILE LPAR bieu_thuc RPAR body_ while15.body_ while → BEGIN lenh_ while END
16.lenh_ while → ct
17.lenh_ while → BREAK SEMI lenh_ while
18.lenh_ while → CONTINUE SEMI lenh_ while
36.factor → LPAR exp RPAR
37.factor → OP1 factor
Trang 193 FIRST(ct) = {TYPE, ID, BEGIN, WHILE, }
4 FIRST(lenh) = {ID, BEGIN}
12.FIRST(bt1) = {NOT, LPAR}
13.FIRST(bt2) = { ID, NUMINT, NUMFLOAT, LPAR, OP1}
14.FIRST(bt3) = {LPAR}
15.FIRST(bt4) = { ID, NUMINT, NUMFLOAT, LPAR, OP1}
16.FIRST(exp) = {ID, NUMINT, NUMFLOAT, LPAR, OP1}
17.FIRST(term) = {ID, NUMINT, NUMFLOAT, LPAR, OP1}18.FIRST(factor) = {ID, NUMINT, NUMFLOAT, LPAR, OP1}
Trang 2014.FOLLOW(bt3) = {AND, OR, RPAR, $}
15.FOLLOW(bt4) = {RPAR, RELOP, $}
16.FOLLOW(exp) = {OP1, RPAR, RELOP, SEMI, $}
17.FOLLOW(term) = {OP1, OP2, RPAR, RELOP,SEMI, $}
18.FOLLOW(factor) = {OP1, OP2, RPAR, RELOP, SEMI, $}
F Tính tuyển
I0:
S → mainmain → MAIN LPAR RPAR body
main → MAIN LPAR RPAR body
I6 = goto(I4, BEGIN) = goto(I6, BEGIN) = goto(I10, BEGIN) = goto(I17, BEGIN) = goto(I18, BEGIN) = goto(I60, BEGIN) = goto(I70, BEGIN) =
Trang 21pbgan → ID ASG expbody → BEGIN ct ENDwhile → WHILE LPAR bieu_thuc RPAR body_while
I7 = goto(I6, ct)
body → BEGIN ct END
I8 = goto(I6, var) = goto(I10, var) = goto(I17, var) = goto(I18, var) =
goto(I60, var) = goto(I70, var) = goto(I71, var)
I11 = goto(I6, TYPE) = goto(I10, TYPE) = goto(I17, TYPE) = goto(I18, TYPE) = goto(I60, TYPE) = goto(I70, TYPE) = goto(I71, TYPE)
var → TYPE n_idn_id → ID COMA n_idn_id → ID
I12 = goto(I6, pbgan) = goto(I10, pbgan) = goto(I17, pbgan) = goto(I18, pbgan) = goto(I60, pbgan) = goto(I70, pbgan) = goto(I71, pbgan)
lenh → pbgan
I13 = goto(I6, body) = goto(I10, body) = goto(I17, body) = goto(I18, body)
= goto(I60, body) = goto(I70, body) = goto(I71, body)
Trang 22I15 = goto(I6, WHILE) = goto(I10, WHILE) = goto(I17, WHILE) =
goto(I18, WHILE) = goto(I60, WHILE) = goto(I70, WHILE) = goto(I71, WHILE)
while → WHILE LPAR bieu_thuc RPAR body_while
I19 = goto(I10, ct)
ct → while ct
I20 = goto(I11, n_id)
var → TYPE n_id
I21 = goto(I11, ID) = goto(I26, ID)
n_id → ID COMA n_idn_id → ID
I22 = goto(I14, ASG)
Trang 23pbgan → ID ASG exp
exp → exp OP1 term
factor → LPAR exp RPAR
factor → OP1 factor
factor → LPAR exp RPAR
factor → OP1 factor
n_id → ID COMA n_id
n_id → ID COMA n_id
n_id → ID
I27 = goto(I22, exp)
Trang 24pbgan → ID ASG exp.
exp → exp OP1 term
I28 = goto(I22, term) = goto(I23, term) = goto(I33, term) = goto(I40, term) =goto(I52, term) = goto(I55, term)
exp → term
term → term OP2 factor
I29 = goto(I22, factor) = goto(I23, factor) = goto(I33, factor) = goto(I40, factor) = goto(I44, factor) = goto(I52, factor) = goto(I55, factor)
term → factor
I30 = goto(I22, ID) = goto(I23, ID) = goto(I33, ID) = goto(I34, ID) =
goto(I40, ID) = goto(I44, ID) = goto(I45, ID) = goto(I52, ID) = goto(I55, ID)
factor → ID
I31 = goto(I22, NUMINT) = goto(I23, NUMINT) = goto(I33, NUMINT) = goto(I34, NUMINT) = goto(I40, NUMINT) = goto(I44, NUMINT) = goto(I45, NUMINT) = goto(I52, NUMINT) = goto(I55, NUMINT)
factor → NUMINT
I32 = goto(I22, NUMFLOAT) = goto(I23, NUMFLOAT) = goto(I33,
NUMFLOAT) = goto(I34, NUMFLOAT) = goto(I40, NUMFLOAT) = goto(I44, NUMFLOAT) = goto(I45, NUMFLOAT) = goto(I52, NUMFLOAT) = goto(I55, NUMFLOAT)
factor → NUMFLOAT
I33 = goto(I22, LPAR) = goto(I33, LPAR) = goto(I34, LPAR) = goto(I40, LPAR) = goto(I44, LPAR) = goto(I45, LPAR) = goto(I52, LPAR) = goto(I55, LPAR)
factor → LPAR exp RPARexp → exp OP1 term
exp → termterm → term OP2 factorterm → factor
factor → IDfactor → NUMINTfactor → NUMFLOATfactor → LPAR exp RPARfactor → OP1 factor
I34 = goto(I22, OP1) = goto(I23, OP1) = goto(I33, OP1) = goto(I34, OP1) = goto(I40, OP1) = goto(I44, OP1) = goto(I45, OP1) = goto(I52, OP1) = goto(I55, OP1)
factor → OP1 factorfactor → ID
factor → NUMINT
Trang 25factor → NUMFLOATfactor → LPAR exp RPARfactor → OP1 factor
I37 = goto(I23, bt2)
bieu_thuc → bt2
I38 = goto(I23, NOT)
bt1 → NOT bt3bt3 → LPAR bt4 RPAR
I39 = goto(I23, bt3)
bt1 → bt3
I40 = goto(I23, LPAR)
bt3 → LPAR bt4 RPARfactor → LPAR exp RPARbt4 → bt4 RELOP expbt4 → exp
exp → exp OP1 termexp → term
term → term OP2 factorterm → factor
factor → IDfactor → NUMINTfactor → NUMFLOATfactor → LPAR exp RPARfactor → OP1 factor
n_id → ID COMA n_id
I44 = goto(I27, OP1) = goto(I42, OP1) = goto(I46, OP1) = goto(I54, OP1) = goto(I64, OP1)
Trang 26exp → exp OP1 term
term → term OP2 factor
term → factor
factor → ID
factor → NUMINT
factor → NUMFLOAT
factor → LPAR exp RPAR
factor → OP1 factor
I45 = goto(I28, OP2) = goto(I56, OP2)
term → term OP2 factor
factor → ID
factor → NUMINT
factor → NUMFLOAT
factor → LPAR exp RPAR
factor → OP1 factor
I46 = goto(I33, exp)
factor → LPAR exp RPAR
exp → exp OP1 term
Trang 27factor → NUMINT
factor → NUMFLOAT
factor → LPAR exp RPAR
factor → OP1 factor
exp → exp OP1 term
I55 = goto(I41, RELOP) = goto(I53, RELOP)
factor → LPAR exp RPAR
factor → OP1 factor
I56 = goto(I44, term)
exp → exp OP1 term
term → term OP2 factor
I57 = goto(I45, factor)
term → term OP2 factor
I58 = goto(I46, RPAR) = goto(I54, RPAR)
factor → LPAR exp RPAR
lenh_ while → BREAK SEMI lenh_ while
lenh_ while → CONTINUE SEMI lenh_ while
ct → var SEMI ct
ct → var SEMI
ct → lenh SEMI ct
ct → while ct
Trang 28ct →
var → TYPE n_id
lenh → pbgan
lenh → body
pbgan → ID ASG exp
body → BEGIN ct END
while → WHILE LPAR bieu_thuc RPAR body_while
exp → exp OP1 term
I65 = goto(I60, lenh_ while)
body_ while → BEGIN lenh_ while END
I66 = goto(I60, ct) = goto(I70, ct) = goto(I71, ct)
lenh_ while → ct
I67 = goto(I60, BREAK) = goto(I70, BREAK) = goto(I71, BREAK)
lenh_ while → BREAK SEMI lenh_ while
I68 = goto(I60, CONTINUE) = goto(I70, CONTINUE) = goto(I71, CONTINUE)
lenh_ while → CONTINUE SEMI lenh_ while
lenh_ while → BREAK SEMI lenh_ while
lenh_ while → CONTINUE SEMI lenh_ while
Trang 29pbgan → ID ASG exp
body → BEGIN ct END
while → WHILE LPAR bieu_thuc RPAR body_while
I71 = goto(I68, SEMI)
lenh_ while → CONTINUE SEMI lenh_ while
lenh_ while → ct
lenh_ while → BREAK SEMI lenh_ while
lenh_ while → CONTINUE SEMI lenh_ while
pbgan → ID ASG exp
body → BEGIN ct END
while → WHILE LPAR bieu_thuc RPAR body_while
I72 = goto(I70, lenh_ while)
lenh_ while → BREAK SEMI lenh_ while
I73 = goto(I71, lenh_ while)
lenh_ while → CONTINUE SEMI lenh_ while
G Bảng Action – Goto
(file: BangAction_Goto.doc)
III Phân tích ngữ nghĩa
1 Kiểm tra kiểu của các biểu thức và các câu lệnh
Trang 30factor → NUMINT { factor.TYPE := int}
factor → NUMFLOAT { factor.TYPE := float}
pbgan → ID ASG exp { pbgan.type := if ID.type = exp.type
then void else type_ error}
while → WHILE LPAR bieu_thuc RPAR body_ while
{ while.type:=if while.type=Boolean then body_ while.type else
type_error}
2 Chuyển đổi kiểu từ số nguyên sang số thực
Ta xét một biểu thức dạng x + i với x có kiểu float và i có kiểu int Biểudiễn của float và in trong máy tính là khác nhau, đồng thời, cách thực hiệnphép cộng đối với số int và đối với số float là khác nhau Trong thực tế, đểthực hiện được phép cộng này, trước tiên chương trình dịch sẽ đổi cả hai toán
tử này về cùng một kiểu (cụ thể ở đây là kiểu float) sau đó thực hiện phépcộng
Trong các ngôn ngữ, việc chuyển đổi kiểu như trên là rất cần thiết Bộkiểm tra kiểu trong một chương trình dịch có thể được dùng để chèn thêm cácphép toán vào các biểu diễn trung gian của chương trình nguồn Ví dụ, ký hiệu
cho x + i có thể được chèn thêm phép toán inttofloat dùng để chuyển một số
int thành float rồi mới thực hiện phép cộng số thực
Ép kiểu
Một phép đổi kiểu từ một kiểu sang kiểu khác được gọi là không rõ (ẩn)nếu nó thực hiện một cách tự động bởi chương trình dịch Các phép biến đổikiểu này cũng được gọi là ép kiểu và có trong nhiều ngôn ngữ Các phép biếnđổi nói chung dễ làm mất thông tin nên các chương trình dịch thông thườngkhông tự động thực hiện các phép biến đổi kiểu này Ví dụ một số nguyên đổi
tự động được thành số thực nhưng ngược lại thì mất thông tin
Chuyển đổi kiểu từ số nguyên sang thực:
Trang 31Lưu ý: Hàm lookup(e) dùng để lấy kiểu cất trong bảng ký hiệu trỏ bởi e.
Trang 32TÀI LIỆU THAM KHẢO
1 Giáo trình Chương trình dịch – Phạm Hồng Nguyên – NXB Đại họcQuốc Gia Hà Nội – 2008
2 Bài giảng Chương trình dịch – Phan Thị Thu Hồng