如何找到子串
How to find a substring
给定一个包含字符串的文本文件,我会在该字符串中找到一些特定的 substrings/sequences。
Bison 文件.y(声明+规则)
%token <cval> AMINO
%token STARTCODON STOPCODON
%type <cval> seq
%%
series: STARTCODON seq STOPCODON {printf("%s", );}
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", );}
不正确。
Flex
没有将整个字符串正确细分为 3 个字符的标记。
编辑:
(示例)输入文件: DnaSequence.txt:
输入字符串:cccATGAATTATTAGzzz
,其中低位字符(ccc
、zzz
)产生(右)输出 -
,ATG
是 STARTCODON
,AATTAT
是两个AMINO
的序列(AATTAT),TAG
是 STOPCODON
.
此输入字符串产生(错误的)输出 ---
。
编辑:
根据@JohnBollinger 的建议,我在 Flex 文件中添加了 <<EOF>> {return ENDTXT;}
,在 Bison 文件中添加了规则 finalseries: series ENDTXT;
。
现在它返回 yyerror
的错误消息,表示解析错误。
我想我们需要一个 STARTTXT
令牌,但我不知道如何实现它。
I am new Flex/Bison, I suspect that:
- The bison rule series: STARTCODON seq STOPCODON {printf("%s", );} is not correct.
规则在句法上是可以接受的。如果标记 2 的值是 C 字符串,这在语义上是正确的,在这种情况下,它会导致该值打印到标准输出,但您的 Flex 文件似乎假定类型 <cval>
是 char
,不是 C 字符串,也不能直接转换为 C 字符串。
- Flex doesn't subdivide correctly the entire string into tokens of 3 characters.
实际上,您的 Flex 输入在我看来还不错。您提供的示例输入/输出表明 Flex 确实识别了从 ATG
到 TAG
的所有三元组,否则 .
的规则将被触发超过三次。
数据类型问题是您需要解决的一个细节问题,但是主要问题是您对seq
的产生式没有设置其语义值.当 series
生产用于减少时,这如何导致(看似)没有被打印取决于您没有披露的细节,并且可能涉及未定义的行为。
如果 <cval>
被声明为字符串 (char *
),并且如果您的词法分析器将其值设置为字符串而不是字符,那么设置语义值可能如下所示:
seq: AMINO { $$ = calloc(MAX_AMINO_ACIDS + 1, 1); /* check for allocation failure ... */
strcpy($$, ); }
| seq AMINO { $$ = ; strcat($$, ); }
;
您可能会考虑坚持使用 char
作为 AMINO
语义值的类型,并将 seq
定义为不同的类型(即 char *
)。这样,您的更改可能仅限于语法文件。然而,这将要求在 seq
.
的产生式中对语义动作进行不同的实现。
最后,请注意,虽然你说
Here I want to print every sequence between STARTCODON and STOPCODON
你的文法,如前所述,以 series
作为它的开始符号。因此,一旦它将令牌序列减少到 series
,它就可以完成。如果后面有其他标记(比如另一个 series
的标记),那将是错误的。如果这是您需要支持的东西,那么您将需要一个更高级别的开始符号来表示多个 series
.
的序列
给定一个包含字符串的文本文件,我会在该字符串中找到一些特定的 substrings/sequences。
Bison 文件.y(声明+规则)
%token <cval> AMINO
%token STARTCODON STOPCODON
%type <cval> seq
%%
series: STARTCODON seq STOPCODON {printf("%s", );}
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", );}
不正确。Flex
没有将整个字符串正确细分为 3 个字符的标记。
编辑:
(示例)输入文件: DnaSequence.txt:
输入字符串:cccATGAATTATTAGzzz
,其中低位字符(ccc
、zzz
)产生(右)输出 -
,ATG
是 STARTCODON
,AATTAT
是两个AMINO
的序列(AATTAT),TAG
是 STOPCODON
.
此输入字符串产生(错误的)输出 ---
。
编辑:
根据@JohnBollinger 的建议,我在 Flex 文件中添加了 <<EOF>> {return ENDTXT;}
,在 Bison 文件中添加了规则 finalseries: series ENDTXT;
。
现在它返回 yyerror
的错误消息,表示解析错误。
我想我们需要一个 STARTTXT
令牌,但我不知道如何实现它。
I am new Flex/Bison, I suspect that:
- The bison rule series: STARTCODON seq STOPCODON {printf("%s", );} is not correct.
规则在句法上是可以接受的。如果标记 2 的值是 C 字符串,这在语义上是正确的,在这种情况下,它会导致该值打印到标准输出,但您的 Flex 文件似乎假定类型 <cval>
是 char
,不是 C 字符串,也不能直接转换为 C 字符串。
- Flex doesn't subdivide correctly the entire string into tokens of 3 characters.
实际上,您的 Flex 输入在我看来还不错。您提供的示例输入/输出表明 Flex 确实识别了从 ATG
到 TAG
的所有三元组,否则 .
的规则将被触发超过三次。
数据类型问题是您需要解决的一个细节问题,但是主要问题是您对seq
的产生式没有设置其语义值.当 series
生产用于减少时,这如何导致(看似)没有被打印取决于您没有披露的细节,并且可能涉及未定义的行为。
如果 <cval>
被声明为字符串 (char *
),并且如果您的词法分析器将其值设置为字符串而不是字符,那么设置语义值可能如下所示:
seq: AMINO { $$ = calloc(MAX_AMINO_ACIDS + 1, 1); /* check for allocation failure ... */
strcpy($$, ); }
| seq AMINO { $$ = ; strcat($$, ); }
;
您可能会考虑坚持使用 char
作为 AMINO
语义值的类型,并将 seq
定义为不同的类型(即 char *
)。这样,您的更改可能仅限于语法文件。然而,这将要求在 seq
.
最后,请注意,虽然你说
Here I want to print every sequence between STARTCODON and STOPCODON
你的文法,如前所述,以 series
作为它的开始符号。因此,一旦它将令牌序列减少到 series
,它就可以完成。如果后面有其他标记(比如另一个 series
的标记),那将是错误的。如果这是您需要支持的东西,那么您将需要一个更高级别的开始符号来表示多个 series
.