I am trying to write a recursive descent parser without backtracking for a kind of EBNF like this:
<a> ::= b [c] | d
where
<a> = non-terminal
lower-case-string = identifier
[term-in-brackets] = term-in-brackets is optional
a|b is the usual mutually exclusive choice between a and b.
For now, I care only about the right hand side.
Following the example at http://en.wikipedia.org/wiki/Recursive_descent_parser, I eventually ended up with the following procedures (rule in GNU bison syntax in comments above):
/* expression: term optional_or_term */
void expression()
{
term();
if (sym == OR_SYM)
optional_or_term();
}
/* optional_or_term: // empty
| OR_SYM term optional_or_term
*/
void optional_or_term()
{
while (sym == OR_SYM)
{
getsym();
term();
}
}
/* term: factor | factor term */
void term()
{
factor();
if (sym == EOF_SYM || sym == RIGHT_SQUAREB_SYM)
{
;
}
else if (sym == IDENTIFIER_SYM || sym == LEFT_SQUAREB_SYM)
term();
else if (sym == OR_SYM)
optional_or_term();
else
{
error("term: syntax error");
getsym();
}
}
/*
factor: IDENTIFIER_SYM
| LEFT_SQUAREB_SYM expression RIGHT_SQUAREB_SYM
*/
void factor()
{
if (accept(IDENTIFIER_SYM))
{
;
}
else if (accept(LEFT_SQUAREB_SYM))
{
expression();
expect(RIGHT_SQUAREB_SYM);
}
else
{
error("factor: syntax error");
getsym();
}
}
It seems to be working, but my expectation was that each procedure would correspond closely with the corresponding rule. You will notice that term() does not.
My question is: did the grammar need more transformation before the procedures were written?