21/1/2010
1
Bài 9.
Phương pháp đệ quy
trên xu
ng
Đặc đim ca phương pháp
S dng để phân tích cú pháp cho các
văn phm LL(1)
thmrng cho vănphm LL(k)
th
m
rng
cho
văn
phm
LL(k)
,
nhưng vic tính toán phc tp
S dng để phân tích văn phm khác có
th dn đến lp vô hn
B phân tích cú pháp
Bao gm mt tp th tc, mi th tc ng
vi mt sơ đồ cú pháp (mt ký hiu không
kết thúc)
Các th tc đệ quy : khi tri
n khai mt ký
hiu không kết thúc có th gp các ký hiu
không kết thúc khác, dn đến các th tc
gi ln nhau, và có th gi trc tiếp hoc
gián tiếp đến chính nó.
Mô t chc năng
Gi s mi th tc hướng ti mt đích
ng vi mt sơ đồ cú pháp
Timithiđim luôn mtđích được
Ti
mi
thi
đim
luôn
mt
đích
được
trin khai, kim tra cú pháp hết mt đon
nào đó trong văn bn ngun
21/1/2010
2
Th tc trin khai mt đích
Đối chiếu văn bn ngun vi mt đường trên sơ đồ
pháp
Đọc t t tiếp
Đ
i chiếu vi nút tiế
p
theo trên sơ đồ
p
Nếu là nút tròn (ký hiu kết thúc)thì t t va đọc phi
phù hp vi t t trong nút
Nếu là nút ch nht nhãn A (ký hiu không kết thúc), t
t va đọc phi thuc FIRST (A) => tiếp tc trin khai
đích A
Ngược li, thông báo mt li cú pháp ti đim đang xét
T sơ đồ thành th tc
Mi nút trên sơ đồ ng vi mt th tc
Các nút xut hin tun t chuyn thành các câu lnh kế
tiếp nhau.
Các đim r nhánh chu
y
n thành câu l
nh l
a ch
n
(
if
,
y (,
case)
Chu trình chuyn thành câu lnh lp (while, do while,
repeat. . .)
Nút tròn chuyn thành đon đối chiếu t t
Nút ch nht chuyn thành li gi ti th tc khác
Chú ý
B phân tích cú pháp luôn đọc trước mt
t t
Xem trướcmtttcho phép chnđúng
Xem
trước
mt
t
t
cho
phép
chn
đúng
đường đi khi gp đim r nhánh trên sơ
đồ cú pháp
Khi thoát khi th tc trin khai mt đích,
có mt t t đã được đọc dôi ra
B phân tích cú pháp KPL
void error (const char msg[]);
int accept(symbol s); // kim tra s có phi là symbol
không?
int expect(symbol s); // kim tra s có phi là symbol cn
đọc không?
void factor(void);//phân tích nhân t
void term(void);//phân tích s hng
void expression(void); // phân tích biu thc
void condition(void); // phân tích điu kin
void statement(void); // phân tích câu lnh
void block(void); // phân tích các khi câu lnh
void basictype(void); // các kiu biến cơ bn
void program();
21/1/2010
3
Hàm accept
int accept(symbol s)
{
if (sym == s)
getsym();
return 1;
}
return 0;
}
Hàm expect
int expect(symbol s)
{
if(accept(s))
if(accept(s))
return 1;
error("expect: unexpected symbol");
return 0;
}
Phân tích
factor
void factor(void)
{if(accept(ident){}
else
if(accept(number)) {}
else if(accept(lparen))
{
expression();
expect(rparen);
}
else
{
("f t t ")
error
("f
ac
t
or: syn
t
ax error
")
;
getsym();
}
}
Phân tích
term
void term(void)
{
factor();
while(sym == times || sym == slash)
{
getsym();
factor();
}
}
21/1/2010
4
Phân tích
expression
void expression(void)
{
if(sym == plus || sym == minus)
getsym();
term();
while(sym == plus || sym == minus)
{
getsym();
term();
}
}
Phân tích
condition
void condition(void)
{
expression();
if(sym == eql || sym == neq || sym == lss || sym == leq || sym ==
grt || sym == geq)
{
getsym();
expression();
expression();
}
else
{
error("condition: syntax error");
}
}
Sơ đồ cú pháp ca lnh
KPL
Phân tích statement
void statement(void)
{
if(accept(ident))
{
expect(becomes);
expression();
// variable :=
}
else if(accept(callsym))
{
expect(ident);
expect(lparen);
expression();
expect(rparen);
}
else if(accept(beginsym))
{
statement();
while(sym == sem icolon)
{
getsym();
statement();
}
expect(endsym);
}
else if(accept(ifsym))
{
condition();
expect(thensym);
statement();
if (accept(elsesym))
statement();
expression();
while (sym == comma)
{
getsym();
expression();
}
statement();
}
else if(accept(whilesym))
{
condition();
expect(dosym);
statement();
}
else if (accept(forsym))
{
expect(ident);
expect(becomes);
expression();
expect(tosym);
expression();
expect(dosym);
statement();
}
else
{
getsym();
}
}
21/1/2010
5
Phân tích
basic type
void basictype()
{
if(accept(integersym)){}
else
expect(charsym);
expect(charsym);
}
Phân tích
program
void program()
{
expect(programsym);
expect(ident);
expect(semicolon);
block();
if(sym == period)
{
{
printf("No error!");
return;
}
else
{
error("Syntax error.");
}
}
Phân tích block
void block(void)
{
if(accept(constsym)) // const
{
while (accept(ident))
{
expect(eql);
constant_decl();
expect(semicolon);
}
if(accept(varsym))
{
while (accept(ident))
{
expect(colon);
type();
expect(semicolon);
}
}
while(sym == procsym)
{
getsym();
t(id t)
}
}
if (accept(typesym)) // type
{
while (accept(ident))
{
expect(eql);
type();
expect(semicolon);
}
}
expec
t(id
en
t)
;
if (accept(lparen))
{
paramlist();
expect(rparen);
}
expect(semicolon);
block();
expect(semicolon);
}
expect(beginsym);
statement();
while(accept(semicolon))
statement();
expect(endsym);
}
Khi