Why my rules of bison don't work

余生颓废 提交于 2019-12-13 18:41:26

问题


Every time I run my parser, it will appear "syntax error in line 1 near <>" (Because there is a subroutine yyerror(char *s)). I think that's because there is something wrong with my rules in bison.

The file (c17.isc) I want to parse.

*c17 iscas example (to test conversion program only)
*---------------------------------------------------
*
*
*  total number of lines in the netlist ..............    17
*  simplistically reduced equivalent fault set size =     22
*        lines from primary input  gates .......     5
*        lines from primary output gates .......     2
*        lines from interior gate outputs ......     4
*        lines from **     3 ** fanout stems ...     6
*
*        avg_fanin  =  2.00,     max_fanin  =  2
*        avg_fanout =  2.00,     max_fanout =  2
*
*
*
*
*
    1     1gat inpt    1   0      >sa1
    2     2gat inpt    1   0      >sa1
    3     3gat inpt    2   0 >sa0 >sa1
    8     8fan from     3gat      >sa1
    9     9fan from     3gat      >sa1
    6     6gat inpt    1   0      >sa1
    7     7gat inpt    1   0      >sa1
   10    10gat nand    1   2      >sa1
     1     8
   11    11gat nand    2   2 >sa0 >sa1
     9     6
   14    14fan from    11gat      >sa1
   15    15fan from    11gat      >sa1
   16    16gat nand    2   2 >sa0 >sa1
     2    14
   20    20fan from    16gat      >sa1
   21    21fan from    16gat      >sa1
   19    19gat nand    1   2      >sa1
    15     7
   22    22gat nand    0   2 >sa0 >sa1
    10    20
   23    23gat nand    0   2 >sa0 >sa1
    21    19

My flex file is as follows and it is right. You can find some information about how my scanner work here. Error in the output of my flex file

declare.h

# include <stdio.h>
# include <string.h>
# include <stdlib.h>

# define INPT 1
# define NOR 2
# define NAND 3
# define NOT 4
# define XOR 5
# define AND 6
# define BUFF 7
# define FROM 8

flex file is

%{
# include "declare.h"
# include "parse.tab.h"

/*gi=1,it's input;gi=8,it's fanout;otherwise,it's gate*/
static int gi=-1;
static int inum=0;



struct{
    char *symbol;
    int val;
} symtab[]={
{"inpt", INPT},
{"nor", NOR},
{"nand", NAND},
{"not", NOT},
{"xor", XOR},
{"and", AND},
{"buff", BUFF},
{"from",FROM},
{"0",0}
};

extern FILE *yyin;

extern int yylval;
%}

%start A B C D E

DIGITS [0-9]+
BLANK [ \t\n\r\f\v\b]+
ALPHA [a-z]+

%%

"*".*\n     {BEGIN A; return(COMMENT);}

<A>{DIGITS}        {yylval=atoi(yytext); BEGIN B; return(NUM);}
<B>{DIGITS}{ALPHA} {yylval=atoi(yytext); BEGIN C; return(GNAME);}
<C>{DIGITS}        {yylval=atoi(yytext); BEGIN D; return(OPNUM);}
<C>{DIGITS}{ALPHA} {yylval=atoi(yytext); BEGIN A; return(FR);}
<D>{DIGITS}        {inum=atoi(yytext);
                    yylval=inum;
                    if(gi==1)
                    {BEGIN A;}
                    if(gi!=1)
                    {BEGIN E;}
                    return(IPNUM);
                   }

<E>{DIGITS}        {inum--;
                    yylval=atoi(yytext);
                    if(inum<0)
                    {BEGIN B; return(NUM);}
                    else
                    {BEGIN E; return(ILIST);} 
                   }


{ALPHA} {yylval=lookup(yytext);
         return(GTYPE);      
         }

">sa"[0-1] {yylval=atoi(&yytext[yyleng-1]);return(FAULT);}

{BLANK}    ;

.          ;



%%
int lookup(const char *s)
{
    int i;
    for (i = 0; symtab[i].val != 0; i++)
    {
        if (strcmp(symtab[i].symbol, s) == 0)
            break;
    }
    return(symtab[i].val);
}

The right rules in bison file are as follows

parto: 
     | parto COMMENT
     | parto parti
     ;

parti: NUM
       {...}

       GNAME
       {...}


       GTYPE
       {...}

      | parti partii 
      | parti partiii
      ;

partii:OPNUM
       {...}

       IPNUM
       {...}

       partiv

       partv
       ;

partiii: FR
        {...}

         partiv
         ;

partiv: 
      | partiv FAULT
      {...}

      ;

partv:
     | partv ILIST
     {...}

     ;

回答1:


Transferring the key comments into an answer.

The first edition of the code had a couple of problems. In the scanner code, there were lines like this:

<A>{DIGITS}        { yylval=atoi(yytext); return(NUM); BEGIN B; }

You should be getting warnings about unreachable code from the BEGIN operations appearing after return. The BEGIN operations have to be executed. They aren't being executed, so you're not switching into your start states.

Michael commented:

There is no warning. I've modified it as you say and edit my codes in the question. Now I put return after BEGIN. Still, "syntax error in line 1 near <�>".

This probably means you aren't compiling the C code with enough warnings. Assuming you're using GCC, add -Wall to the compilation options for starters. There's a chance the warning requires optimization too.

Have you printed the tokens as they're returned (in the Flex scanner)? Have you compiled the Bison grammar with -DYYDEBUG? You also need to turn the debug on: yydebug = 1; in the main() program. You're probably not getting the tokens you expect when you expect them. I've not tried compiling this code yet. Tracking the tokens is key (in my experience) to getting grammars to work. Otherwise, you're running blind.

The other problem (closely related) is that you need to generate the symbolic names for FAULT etc from the grammar (bison -d grammar.y generates grammar.tab.h). You'll find that COMMENT is assigned the value 258, for example. Your scanner, though, is returning other numbers altogether because they're in declare.h. You'll have to fix this mismatch. One option is to #include "grammar.tab.h" in your scanner; this is more or less normal.

In retrospect, I think this is probably the most important observation; things seemed to revert to normal C debugging after this was resolved.

(People often include 'grammar.h' and only update 'grammar.h' if the content of 'grammar.tab.h' changes, so you don't recompile the scanner all the time).

The significance of this is that the set of tokens used by a grammar tends to be fairly stable while the actions associated with the rules change all the time as the implementation of the grammar evolves. So, if it takes enough time to be worth worrying about, you can create file grammar.h that is a copy of grammar.tab.h, but only update grammar.h when the content of grammar.tab.h changes.

cmp -s grammar.tab.h grammar.h || cp grammar.tab.h grammar.h

You'd include this in the makefile rule that converts that grammar into a C file (or an object file).

If the scanner is small enough and your machine fast enough, it may be simpler not to bother with this refinement; it mattered more in the days of 50 MHz machines with a few MiB of RAM than it does in these days of multiple cores running at 2+ GHz with a few GiB of RAM.



来源:https://stackoverflow.com/questions/15526259/why-my-rules-of-bison-dont-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!