help-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bison yyparse return array of values


From: Laura Morales
Subject: Re: Bison yyparse return array of values
Date: Sun, 2 Apr 2017 17:02:20 +0200

- if I want multiple parsers, I *must* use prefix change
- the purpose of a pure/reentrant parser is to encapsulate globals such that I 
can call the same parser multiple times and avoid conflicts or race conditions

correct? Is this basically the bottom line?
I thought reentrancy was a substitute to prefix renaming, but looks like they 
solve different problems so I have to use both.


=================================================
Hi Laura,

if you want multiple different parsers (i.e. different .y files) in one
binary, use renaming. See the "%name-prefix"-Option.

In this case, I guess you could stick with globals to store the parsing
result.

If you want to use multiple instances of the same parser simultaneously,
turn the parser into a reentrant one. See the "%define api.pure
full"-Option.

In this case, I would add a function parameter to yyparse() to hand back
the parsing result.

The following example generates a reentrant parser (with renamed prefix)
that stores the linked list of parsed words in a new function parameter
to yyparse() and counts the number of parsed WORDS after yyparse() has
finished.

================
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct elem {
char *val;
struct elem *next;
} elem_t;

elem_t *add_word(elem_t *words, char *val) {
elem_t *word = (elem_t *)malloc(sizeof(elem_t));
if (word == NULL) {
fprintf (stderr, "%s", "malloc failed");
exit(1); }
word->val = val;
word->next = words;
return word;
}
%}

%output "parser.c"
%defines "parser.h"

%name-prefix "yy1"
%define api.pure full
%parse-param { elem_t **words };

%union {
char *str;
}

%token <str> WORD

%start Input

%%

Input
: WORD { *words = add_word(NULL, $1);
printf("word: %s\n", yylval.str); }
| Input WORD { *words = add_word(*words, $2);
printf("word: %s\n", yylval.str); }
;

%%

int main() {
elem_t *words = NULL;
yy1parse(&words);

int i = 0;
while (words != NULL) {
i++;
words = words->next;
}

fprintf(stdout, "Parsed %d WORDS\n", i);
}

void yy1error(char *error) {
fprintf(stderr, "%s", error);
}

int yy1lex(YYSTYPE *lvalp) {
static int i = 0;
while (i++ < 100) {
lvalp->str = "testWord";
return WORD;
}

return 0;
}
================

Yours, Alex



reply via email to

[Prev in Thread] Current Thread [Next in Thread]