鉴于包含字符串的文本文件,我会在此字符串中找到一些特定的子字符串/序列。
野牛档案.y (声明+规则)
%token <cval> AMINO
%token STARTCODON STOPCODON
%type <cval> seq
%%
series: STARTCODON seq STOPCODON {printf("%s", $2);}
seq: AMINO
| seq AMINO
;
%%
我希望在STARTCODON
和STOPCODON
Flex文件.l (规则)
%%
("ATG")+ {return STARTCODON;}
("TAA"|"TAG"|"TGA")+ {return STOPCODON;}
("GCT"|"GCC"|"GCA"|"GCG")+ {yylval.cval = 'A';
return AMINO;}
("CGT"|"CGC"|"CGA"|"CGG"|"AGA"|"AGG")+ {yylval.cval = 'R';
return AMINO;}
.
.
.
[ \t]+ /*ignore whitespace*/
\n /*ignore end of line*/
. {printf("-");}
%%
当我运行代码时,我只得到规则. {printf("-");}
的输出。
我是新人Flex/Bison
,我怀疑:
bison
规则series: STARTCODON seq STOPCODON {printf("%s", $2);}
不正确。
Flex
没有将整个字符串正确细分为3个字符的标记。
修改
(示例)输入文件: DnaSequence.txt :
输入字符串:cccATGAATTATTAGzzz
,其中较低的字符(ccc
,zzz
)生成(右)输出-
,ATG
是{{1 } {},STARTCODON
是两个AATTAT
( AAT TAT )的序列,AMINO
是TAG
此输入字符串产生(错误的)输出STOPCODON
。
修改
根据@JohnBollinger的建议,我在Flex文件中添加了---
,在Bison文件中添加了规则<<EOF>> {return ENDTXT;}
。
现在它返回finalseries: series ENDTXT;
的错误消息,指出解析错误。
我想我们需要一个yyerror
令牌,但我不知道如何实现它。
答案 0 :(得分:3)
我是新的Flex / Bison,我怀疑:
- 野牛规则系列:STARTCODON seq STOPCODON {printf(&#34;%s&#34;,$ 2);}不正确。
规则在语法上是可以接受的。如果令牌2的值是C字符串,则在语义上是正确的,在这种情况下,它会将该值打印到标准输出,但是您的Flex文件似乎假定类型<cval>
是{{1 ,不是一个C字符串,也不能直接转换为一个。
- Flex没有将整个字符串正确细分为3个字符的标记。
实际上,您的Flex输入对我来说很合适。您提供的示例输入/输出表明Flex确实正在识别从char
到ATG
的所有三元组,否则TAG
的规则将被触发三次以上。
数据类型问题是您需要整理的详细信息,但主问题是您的.
生产未设置其语义值。当seq
生产用于减少时,如何(似乎)没有打印的结果取决于您尚未公开的细节,并且可能涉及未定义的行为。
如果series
被声明为字符串(<cval>
),并且你的词法分析器将其值设置为字符串而不是字符,那么设置语义值可能如下所示:
char *
您可以考虑使用seq: AMINO { $$ = calloc(MAX_AMINO_ACIDS + 1, 1); /* check for allocation failure ... */
strcpy($$, $1); }
| seq AMINO { $$ = $1; strcat($$, $2); }
;
作为char
的语义值的类型,并将AMINO
定义为具有不同的类型(即seq
)。这样,您的更改可能仅限于语法文件。然而,这将要求char *
的生产中的语义动作的不同实现。
最后,请注意,尽管你说
这里我要打印STARTCODON和STOPCODON之间的每个序列
如您所示,您的语法以seq
作为开始符号。因此,一旦它将令牌序列减少到series
,它就会完成。如果跟随其他令牌(比如另一个series
的那些),那么这将是错误的。如果您需要支持,那么您需要一个更高级别的起始符号来表示多个series
的序列。