我写了一个.l文件,想要输出“c17.isc”中的内容。
但有一个错误,我不知道为什么。我已经给出了我打算读取的文件,flex文件和执行结果。
这是c17.isc文件 内容意味着
number gate_name gate_type output_number input_number fault
带“from”的行表示扇出。 带有2个数字的行仅表示输入列表。
*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文件。
首先,这是声明文件:
# 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"
/*gi=1,it's input;gi=7,it's fanout;otherwise,it's gate*/
int gi=-1;
int inum=0;
int val;
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;
%}
%start A B C D E
DIGITS [0-9]+
BLANK [ \t\n]+
ALPHA [a-z]+
%%
"*".*\n {ECHO; BEGIN A;}
<A>{BLANK}{DIGITS} {printf("num=%s\t",yytext); BEGIN B;}
<B>{BLANK}{DIGITS}{ALPHA} {printf("name=%s",yytext); BEGIN C;}
<C>{BLANK}{DIGITS} {printf("op=%s\t",yytext);BEGIN D;}
<C>{BLANK}{DIGITS}{ALPHA} {ECHO; BEGIN A;}
<D>{BLANK}{DIGITS} {inum=atoi(yytext);
printf("ip=%s\t",yytext);
if(gi==1)
{BEGIN A;}
if(gi!=1)
{BEGIN E;}
}
<E>{BLANK}{DIGITS} {inum--;
if(inum<0)
{printf("num=%s\t",yytext); BEGIN B;}
else
{printf("il=%s\t",yytext); BEGIN E;}
}
{ALPHA} {gi=lookup(yytext);
if(gi!=0) printf("\tty=%d\t",gi);
else ECHO;
}
{BLANK}">sa"[0-1] {val=atoi(&yytext[yyleng-1]);printf("\tfl=%d",val);}
{BLANK} ;
%%
lookup(s)
char* s;
{int i;
for (i=0;symtab[i].val!=0;i++)
{
if(strcmp(symtab[i].symbol,s)==0)
break;
}
return(symtab[i].val);
}
main()
{
FILE *x=fopen("c17.isc","r");
yyin=x;
yylex();
}
这是执行结果。我用*标记了错误的地方。基本上,错误发生在带有输入列表的行上。
例如,图片中的第一行错误行应为“num=10
”,第二行错误行应为“il=1 il=8
”等。
我对flex文件中输入列表的操作位于部分E.但我不知道它为什么不起作用。
num=1 name=1gat ty=1 op=1 ip=0 fl=1
num=2 name=2gat ty=1 op=1 ip=0 fl=1
num=3 name=3gat ty=1 op=2 ip=0 fl=0 fl=1
num=8 name=8fan ty=8 3gat fl=1
num=9 name=9fan ty=8 3gat fl=1
num=6 name=6gat ty=1 op=1 ip=0 fl=1
num=7 name=7gat ty=1 op=1 ip=0 fl=1
**il=10** name=10gat ty=3 op=1 ip=2 fl=1
**num=1** il=8
**il=11** name=11gat ty=3 op=2 ip=2 fl=0 fl=1
**num=9** il=6
**num=4** ...
**num=5** ...
**il=16** ...
**num=2** il=14
**num=0** ...
**num=1** ...
**il=19** ...
**num=15** il=7
**il=22** ...
**il=23** ...
答案 0 :(得分:2)
您的代码的这种改编似乎可能按照您的意图运行。有各种变化,最明显的是输出一些换行符,并明确num=
部分的识别位置。
%{
#include "declare.h"
/*gi=1, it's input;gi=7, it's fanout;otherwise, it's gate*/
static int gi = -1;
static int inum = 0;
extern int lookup(const char *s);
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;
%}
%start A B C D E
DIGITS [0-9]+
BLANK [ \t\n]+
ALPHA [a-z]+
%%
"*".*\n {ECHO; BEGIN A;}
<A>{DIGITS} {printf("\nnum1=%s\t", yytext); BEGIN B;}
<B>{DIGITS}{ALPHA} {printf(" name=%s\t", yytext); BEGIN C;}
<C>{DIGITS} {printf(" op=%s\t", yytext); BEGIN D;}
<C>{DIGITS}{ALPHA} {ECHO; BEGIN A;}
<D>{DIGITS} {
inum=atoi(yytext);
printf(" ip=%s\t", yytext);
if (gi==1)
{BEGIN A;}
if (gi!=1)
{BEGIN E;}
}
<E>{DIGITS} {inum--;
if (inum<0)
{printf("\nnum2=%s\t", yytext); BEGIN B;}
else
{printf(" il=%s\t", yytext); BEGIN E;}
}
{ALPHA} {
gi = lookup(yytext);
if (gi!=0) printf(" ty=%d (%s)\t", gi, yytext);
else { printf("Lookup failed: "); ECHO; }
}
">sa"[0-1] {int val=atoi(&yytext[yyleng-1]);printf(" fl=%d", val);}
{BLANK} ;
. { printf("Unmatched: %s\n", yytext); }
%%
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);
}
int main(void)
{
FILE *x=fopen("c17.isc", "r");
yyin=x;
yylex();
putchar('\n');
}
对于您的样本输入,输出为:
*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
*
*
*
*
*
num1=1 name=1gat ty=1 (inpt) op=1 ip=0 fl=1
num1=2 name=2gat ty=1 (inpt) op=1 ip=0 fl=1
num1=3 name=3gat ty=1 (inpt) op=2 ip=0 fl=0 fl=1
num1=8 name=8fan ty=8 (from) 3gat fl=1
num1=9 name=9fan ty=8 (from) 3gat fl=1
num1=6 name=6gat ty=1 (inpt) op=1 ip=0 fl=1
num1=7 name=7gat ty=1 (inpt) op=1 ip=0 fl=1
num1=10 name=10gat ty=3 (nand) op=1 ip=2 fl=1 il=1 il=8
num2=11 name=11gat ty=3 (nand) op=2 ip=2 fl=0 fl=1 il=9 il=6
num2=14 name=14fan ty=8 (from) 11gat fl=1
num1=15 name=15fan ty=8 (from) 11gat fl=1
num1=16 name=16gat ty=3 (nand) op=2 ip=2 fl=0 fl=1 il=2 il=14
num2=20 name=20fan ty=8 (from) 16gat fl=1
num1=21 name=21fan ty=8 (from) 16gat fl=1
num1=19 name=19gat ty=3 (nand) op=1 ip=2 fl=1 il=15 il=7
num2=22 name=22gat ty=3 (nand) op=0 ip=2 fl=0 fl=1 il=10 il=20
num2=23 name=23gat ty=3 (nand) op=0 ip=2 fl=0 fl=1 il=21 il=19
num1=10
行与il=1
和il=8
相关联,似乎反映了数据。 (我修改了打印输出以包含类型名称和类型编号。)
我不确定哪些更改是重要的。丢失匹配数字和alpha的规则的{BLANK}
部分简化了事情,我认为(扫描仪基本上忽略间距是很常见的。)
答案 1 :(得分:0)
我不确定我是否正确了解您的场景,但看起来您正在使用Flex和正则表达式解析文件的所有工作?
通常的方法是使用Flex生成只识别令牌的扫描仪(功能yylex)。令牌可以是单个数字或门名称。扫描仪会在找到令牌后立即返回。因此,扫描程序会将输入(文件中的字符序列)转换为一系列标记。
然后使用解析器生成器(通常是Bison)生成解析器,将这些单独的令牌与语法进行比较,然后在解析器级别处理输入的较大结构。
当您尝试在Flex中完成所有操作时,它变得非常复杂,而这并不适合它。