[ Pobierz całość w formacie PDF ]
accept(colon, " error - : expected");
Student(DegreeCode);
while (SYM.sym == comma)
{ getsym(); Student(DegreeCode); }
}
void ClassName(void)
{ accept(identifier, " error - class name expected"); }
void ClassList(void)
{ ClassName();
OpenDataBase();
if (SYM.sym == bscsym || SYM.sym == bscssym)
{ Group();
while (SYM.sym == semicolon) { getsym(); Group(); }
}
CloseDataBase();
accept(period, " error - . expected");
}
Although all the examples so far have lent themselves to very easy implementation by a recursive
descent parser, it is not difficult to find an example where difficulties arise. Consider the ClassList
example again, but suppose that the input data had been of a form like
CompScience3
Mike, Juanito, Rob, Keith, Bruce : BSc ;
Erik, Arne, Paul, Rory, Andrew, Carl, Jeffrey : BScS ;
Nico, Kirsten, Peter, Luanne, Jackie, Mark : BSc .
This data can be described by the context-free productions
ClassList = ClassName [ Group { ";" Group } ] "." .
Group = Student { "," Student } ":" Degree .
Degree = "BSc" | "BScS" .
ClassName = identifier .
Student = identifier .
Now a moment s thought should convince the reader that attributing the grammar as follows
Group
= Student (. AddToDataBase(Name , DegreeCode ) .)
{ "," Student (. AddToDataBase(Name , DegreeCode ) .)
} ":" Degree .
Student
= identifier
does not create an L-attributed grammar, but has the unfortunate effect that at the point where it
seems natural to add a student to the database, his or her degree has not yet been ascertained.
Just as we did for the one-pass assembler, so here we can sidestep the problem by creating a local
forward reference table. It is not particularly difficult to handle this grammar with a recursive
descent parser, as the following amended code will reveal:
void Student(names &Name)
{ if (SYM.sym == identifier)
{ Name = SYM.name; getsym(); }
else
{ printf(" error - student name expected\n"); exit(1); }
}
void Group(void)
{ codes DegreeCode;
names Name[100];
int last = 0;
Student(Name[last]); // first forward reference
while (SYM.sym == comma)
{ getsym();
last++; Student(Name[last]); // add to forward references
}
accept(colon, " error - : expected");
Degree(DegreeCode);
for (int i = last; i >= 0; i--) // process forward reference list
AddToDataBase(Name[i], DegreeCode);
}
Exercises
11.2 Develop an attribute grammar and corresponding parser to handle the evaluation of an
expression where there may be an optional leading + or - sign (as exemplified by
+ 9 * ( - 6 + 5 ) ).
11.3 Develop an attribute grammar for the 8-bit ASSEMBLER language used in section 4.3, and
use it to build an assembler for this language.
11.4 Develop an attribute grammar for the stack ASSEMBLER language used in section 4.4, and
use it to build an assembler for this language.
[ Pobierz całość w formacie PDF ]