每次运行解析器时,它都会出现“第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文件如下,它是正确的。您可以在此找到有关我的扫描仪如何工作的一些信息。 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文件
%{
# 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);
}
野牛档案中的正确规则如下
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
{...}
;
答案 0 :(得分:0)
将关键评论转移到答案中。
第一版代码有几个问题。在扫描仪代码中,有这样的行:
<A>{DIGITS} { yylval=atoi(yytext); return(NUM); BEGIN B; }
迈克尔评论道:您应该收到有关返回后出现的
BEGIN
操作无法访问的代码的警告。必须执行BEGIN
个操作。它们没有被执行,所以你不会切换到你的开始状态。
没有警告。我已按照您的说法对其进行了修改,并在问题中编辑了我的代码。现在我在BEGIN之后回来了。仍然,“第1行附近的语法错误&lt; &gt;”。
这可能意味着您没有使用足够的警告编译C代码。假设您正在使用GCC,请将-Wall
添加到初学者的编译选项中。警告也有可能需要优化。
您是否在返回时(在Flex扫描仪中)打印了令牌?你用
-DYYDEBUG
汇编了Bison语法吗?您还需要在yydebug = 1;
程序中打开调试:main()
。当你期望它们时,你可能没有得到你期望的代币。我还没有尝试过编译这段代码。跟踪令牌是获得语法工作的关键(根据我的经验)。否则,你是盲目的。另一个问题(密切相关)是你需要从语法中生成
FAULT
等的符号名称(bison -d grammar.y
生成grammar.tab.h
)。例如,您会发现COMMENT
被赋值为258。但是,您的扫描仪正在返回其他数字,因为它们位于declare.h
。你必须解决这个不匹配问题。一种选择是在扫描仪中#include "grammar.tab.h"
;这或多或少是正常的。
回想起来,我认为这可能是最重要的观察;在解决之后,事情似乎恢复了正常的C调试。
(如果'grammar.tab.h'的内容发生变化,人们通常会包含'grammar.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
您可以在makefile规则中包含它,将该语法转换为C文件(或目标文件)。
如果扫描仪足够小并且您的机器足够快,可能更容易不打扰这种改进;在具有少量MiB RAM的50 MHz机器的日子里,它比在多个内核运行在2+ GHz以及少量GiB RAM的情况下更为重要。