[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
>