Αναλυτής αναδρομικής κατάβασης
- Ο συντακτικός αναλυτής αναδρομικής κατάβασης υλοποιεί μια συνάρτηση
για κάθε κανόνα της γραμματικής.
- Η κάθε συνάρτηση:
- Για τα μη τερματικά σύμβολα του κανόνα καλεί την αντίστοιχη
συνάρτηση.
- Διαβάζει τα τερματικά σύμβολα του κανόνα από το λεκτικό αναλυτή.
- Αν διαβάσει ένα τερματικό σύμβολο που δεν αντιστοιχεί στον
κανόνα το σπρώχνει πίσω στην είσοδο (ungetch()) και επιστρέφει.
- Αν έχει να επιλέξει ανάμεσα σε διαφορετικές παραγωγές για έναν
κανόνα, διαβάζει ένα σύμβολο εισόδου και αποφασίζει ανάλογα
με αυτό.
Παράδειγμα
Ο παρακάτω συντακτικός αναλυτής ελέγχει για τον αν η είσοδός του
ανήκει στη γλώσσα που ορίζεται από την παρακάτω γραμματική EBNF:
expr ::= term ('+' term |'-' term) *
term ::= factor ('*' factor |'/' factor) *
factor ::= digit | '-' factor | '(' expr ')'
digit ::= 0 | 1 | 2 | 3 |4 | 5 | 6 | 7 | 8 | 9
και τυπώνει "Parse ok", ") expected" ή "Syntax error".
/*
* Recursive descent parser for the following expression grammar:
* expr ::= term ('+' term |'-' term) *
* term ::= factor ('*' factor |'/' factor) *
* factor ::= digit | '-' factor | '(' expr ')'
* digit ::= 0 | 1 | 2 | 3 |4 | 5 | 6 | 7 | 8 | 9
*
* D. Spinellis, November 1999
*
* $Id: parse0.c 1.1 1999/11/10 00:14:12 dds Exp dds $
*
*/
#include <stdio.h>
/* Forward declarations */
void term(void);
void factor(void);
/* expr ::= term ('+' term |'-' term) * */
void
expr(void)
{
int c;
term();
for (;;) {
switch (c = getchar()) {
case '+':
term();
break;
case '-':
term();
break;
default:
ungetc(c, stdin);
return;
}
}
}
/* term ::= factor ('*' factor |'/' factor) * */
void
term(void)
{
int c;
factor();
for (;;) {
switch (c = getchar()) {
case '*':
factor();
break;
case '/':
factor();
break;
default:
ungetc(c, stdin);
return;
}
}
}
/* factor ::= digit | '-' factor | '(' expr ')' */
void
factor(void)
{
int c;
switch (c = getchar()) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
return;
case '-':
factor();
;
case '(':
expr();
c = getchar();
if (c != ')') {
printf("Expected ')'\n");
exit(1);
}
return;
default:
printf("Syntax error\n");
exit(1);
}
}
/*
* Test harness
*/
main()
{
expr();
printf("Parse ok\n");
}
Χρήση του αναλυτή
% parse
1+2*4-7*(3-1)
Parse ok
% parse
3++3-3
Syntax error
% parse
3-2*(2+2
Expected ')'
% parse
2-
Syntax error