1

每次运行解析器都会出现“第1行<>附近的语法错误”(因为有一个子程序yyerror(char *s))。我认为那是因为我的野牛规则有问题。

我要解析的文件 (c17.isc)。

*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

我的flex文件如下,是对的。您可以在此处找到有关我的扫描仪如何工作的一些信息。 我的 flex 文件的输出错误

声明.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

弹性文件是

%{
# 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);
}

bison文件中正确的规则如下

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
     {...}

     ;
4

1 回答 1

0

将关键评论转化为答案。

代码的第一版有几个问题。在扫描仪代码中,有这样的行:

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

您应该从BEGIN返回后出现的操作中收到有关无法访问代码的警告。BEGIN必须执行操作。它们没有被执行,所以你没有切换到你的开始状态。

迈克尔评论说:

没有警告。我已经按照您的说法对其进行了修改,并在问题中编辑了我的代码。现在我把 return 放在 BEGIN 之后。不过,“<�> 附近的第 1 行有语法错误”。

这可能意味着您没有编译带有足够警告的 C 代码。假设您使用的是 GCC,请添加-Wall到初学者的编译选项。警告也有可能需要优化。

您是否在返回令牌时打印了它们(在 Flex 扫描仪中)?你用 编译过 Bison 语法-DYYDEBUG吗?您还需要yydebug = 1;main()程序中打开调试:当您期望它们时,您可能没有得到您期望的令牌。我还没有尝试编译这段代码。跟踪标记是(根据我的经验)让语法发挥作用的关键。否则,你就瞎跑了。

另一个问题(密切相关)是您需要FAULT从语法(bison -d grammar.ygenerate grammar.tab.h)生成 etc 的符号名称。例如,您会发现它COMMENT被赋值为 258。但是,您的扫描仪会完全返回其他数字,因为它们位于declare.h. 你必须修复这种不匹配。一种选择是#include "grammar.tab.h"在您的扫描仪中;这或多或少是正常的。

回想起来,我认为这可能是最重要的观察;解决此问题后,事情似乎恢复到正常的 C 调试。

(人们通常会包含 'grammar.h' 并且仅在 'grammar.tab.h' 的内容发生变化时才更新 'grammar.h',因此您不必一直重新编译扫描仪)。

这样做的意义在于,语法使用的标记集趋于相当稳定,而与规则相关的动作随着语法实现的发展而一直在变化。因此,如果需要足够的时间值得担心,您可以创建grammar.h作为 副本的文件grammar.tab.h,但仅grammar.h在内容grammar.tab.h更改时更新。

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

您可以将此包含在将语法转换为 C 文件(或目标文件)的 makefile 规则中。

如果扫描仪足够小并且您的机器足够快,那么不用担心这种改进可能会更简单;在拥有几 MiB RAM 的 50 MHz 机器的日子里,它比现在运行在 2+ GHz 和几 GiB RAM 的多核机器更重要。

于 2013-03-21T00:03:59.713 回答