[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: How to free symbols during error recovery
From: |
Laurence Finston |
Subject: |
Re: How to free symbols during error recovery |
Date: |
Thu, 7 Oct 2004 17:13:51 +0200 (MEST) |
I haven't started to implement recovery from parse errors in
my project yet, but I have decided not to use the `error'
token, precisely because it's not possible to control what
happens when the parser stack is unwound.
The following explains an alternative approach. Please be
warned that I haven't tested it. It could be simplified by
using C++ instead of C.
If you're generating a reentrant parser, which I always
recommend, you can pass a parameter to `yyparse()'
via a `void*'.
Let `struct Parameter_Type* p' be the parameter.
You said you are using a pointer to a C struct as your value
type. If we call this type `A', then you could define
another type as follows:
struct A_Node
{
struct A* a;
struct A_Node* next;
};
`Parameter_Type' could contain a data member `struct A_Node* head'.
`p->head->a' must be 0.
At the end of the action for each rule containing symbols
that reference dynamically allocated objects of type `A',
a new `A_Node' is created for each object and a pointer to it is
pushed onto the linked list on `p':
struct A_Node* new_a_node = (struct A_Node*) malloc(size_of(struct A_Node));
new_a_node->a = $1; // or whatever.
new_a_node->next = p->head;
p->head = new_a_node;
If you reach the beginning of a rule action, then obviously
no parse error has occurred. You must clear the linked list
of `A_Node' pointers before filling it up again:
while (p->head->a)
{
struct A_Node* temp_a_node = p->head->next;
free(p->head);
p->head = temp_a_node;
}
The `A' pointers should not be freed!
Since `yyparse()' returns 1 upon error, you can wrap calls
to it in a loop like this:
int r;
do
{
r = yyparse((void*) p);
if (r != 0)
{
/* Error recovery. */
while (p->head->a) /* Here, `p->head->a' should be
freed. */
{
struct A_Node* temp_a_node = p->head->next;
free(p->head->a);
free(p->head);
p->head = temp_a_node;
}
/* More error recovery, or `break', if it's hopeless. */
} // if
} // do
while (r != 0);
Laurence
- How to free symbols during error recovery, Oliver Boris Fischer, 2004/10/06
- Re: How to free symbols during error recovery,
Laurence Finston <=
- Re: How to free symbols during error recovery, Oliver Boris Fischer, 2004/10/07
- Re: How to free symbols during error recovery, Laurence Finston, 2004/10/08
- Re: How to free symbols during error recovery, Akim Demaille, 2004/10/08
- Re: How to free symbols during error recovery, Laurence Finston, 2004/10/08
- Re: How to free symbols during error recovery, Akim Demaille, 2004/10/08
- Re: How to free symbols during error recovery, Laurence Finston, 2004/10/08