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: Martin Alexander Neumann
Subject: Re: Bison yyparse return array of values
Date: Sun, 2 Apr 2017 17:07:17 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0

Hi Laura,

yes, sounds perfect.

Yours, Alex

On 04/02/2017 05:02 PM, Laura Morales wrote:
> - 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]