[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: |
Tue, 4 Apr 2017 08:33:43 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 |
Hi Laura,
the GNU Flex option "%option reentrant" turns the generated scanner into
a reentrant one. This adds the function parameter "yyscan_t yyscanner"
to yylex() to keep the scanner state. The program calling yylex() has to
allocate and prepare a variable of type "yyscan_t" and hand it to
yylex() on each call.
The Bison option "%parse-param {yyscan_t scanner}" adds such a function
parameter to yyparse() allowing to hand such a scanner state from your
program to yyparse(). But Bison does not automatically add this
parameter to its calls to yylex(): the second Bison option "%lex-param
{yyscan_t scanner}" instructs the generated parser to add this function
parameter in the calls to yylex().
Yours, Alex
On 04/02/2017 06:03 PM, Laura Morales wrote:
> I'm looking at this example http://esr.ibiblio.org/?p=6341 which is using
> these slightly different instructions
>
> %define api.pure full
> %lex-param {yyscan_t scanner}
> %parse-param {yyscan_t scanner}
>
> and then add another parameter to handle the output
>
> %define api.pure full
> %lex-param {yyscan_t scanner} {cvs_file *cvsfile}
> %parse-param {yyscan_t scanner} {cvs_file *cvsfile}
>
> Can somebody please explain the meaning of "yyscan_t scanner" and if I can
> omit it?
>
> ================
> %{
> #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;
> }
> ================
>