Content deleted Content added
→Example parser: fmt (EBNF grammar example) (spacing and 4-space indent) |
→Example parser: fmt (C example) (braces and 4-space indent) |
||
Line 46:
Notice how closely the predictive parser below mirrors the grammar above. There is a procedure for each nonterminal in the grammar. Parsing descends in a top-down manner, until the final nonterminal has been processed. The program fragment depends on a global variable, ''sym'', which contains the next symbol from the input, and the global function ''getsym'', which updates ''sym'' when called.
Symbol sym;
void getsym();
int accept(Symbol s)
{
if (sym == s) {
getsym();
return 1;
}
return 0;
}
int expect(Symbol s)
{
if (accept(s))
return 1;
error("expect: unexpected symbol");
return 0;
}
void factor()
{
if (accept(ident))
else if (accept(lparen)) {
expression();
expect(rparen);
} else {
error("factor: syntax error");
}
}
void term()
{
factor();
while (sym == times || sym == slash) {
}
void expression()
{
if (sym == plus || sym == minus)
getsym();
term();
while (sym == plus || sym == minus) {
term();
}
void condition()
{
else
expression();
if (sym == eql || sym == neq || sym == lss ||
sym == leq || sym == gtr || sym == geq) {
getsym();
expression();
error("condition: invalid operator");
}
}
{
expect(becomes);
} else if (accept(callsym))
while (accept(semicolon));
expect(endsym);
} else if (accept(ifsym)) {
condition();
expect(thensym);
statement();
} else if (accept(whilesym)) {
expect(
}
}
void block()
{
if
expect(
expect(eql);
expect(number);
expect(semicolon);
do
expect(ident);
while (accept(comma));
expect(semicolon);
}
while (accept(procsym)) {
expect(semicolon);
expect(semicolon);
}
statement();
}
void program()
{
getsym();
block();
expect(period);
}
== Formalizing recursive descent parsers ==
|