Yacc 只读取规则的第一个匹配项
Yacc only reads the first match of the rule
您好,我正在编写一个简单的 yacc 程序,它获取程序代码并计算有多少个 assign 语句。
例如,对于以下代码片段:
void main() {
int a = 3;
int bb = 10;
}
我希望我的 yacc 打印出有 2 个赋值语句。由于我是初学者,所以我在网上找到了Oreily的书中的示例代码并修改了代码。
yacc.y
%{
2 #include <stdio.h>
3 int assign = 0;
4 %}
5
6 %token NAME NUMBER
7 %start statement
8 %%
9 statement: NAME '=' expression ';' {assign++;}
11 ;
12 | expression { printf("= %d\n", ); }
13 ;
14 expression: expression '+' NUMBER { $$ = + ;
15 printf ("Recognized '+' expression.\n");
16 }
17 | expression '-' NUMBER { $$ = - ;
18 printf ("Recognized '-' expression.\n");
19 }
20 | NUMBER { $$ = ;
21 printf ("Recognized a number.\n");
22 }
23 ;
24 %%
25 int main (void) {
26 yyparse();
27 printf("assign =%d", assign);
28 }
29
30 /* Added because panther doesn't have liby.a installed. */
31 int yyerror (char *msg) {
32 return fprintf (stderr, "YACC: %s\n", msg);
33 }
lex.l
1 %{
2 #include "y.tab.h"
3 extern int yylval;
4 %}
5
6 %%
7 [0-9]+ { yylval = atoi (yytext);
8 printf ("scanned the number %d\n", yylval);
9 return NUMBER; }
10 [ \t] { printf ("skipped whitespace\n"); }
11 \n { printf ("reached end of line\n");
12 return 0;
13 }
14 [a-zA-Z]+ {printf("found name"); return NAME;}
15 . { printf ("found other data \"%s\"\n", yytext);
16 return yytext[0];
17 /* so yacc can see things like '+', '-', and '=' */
18 }
19 %%
20 int yywrap(){
21 return 1;
22 }
~
test.txt
a = 3;
3+2;
b = 3;
当我构建代码时,我得到 a.out。当我 运行 ./a.out < test.txt 时,输出显示有一个赋值。它似乎只识别了第一句话。
如何让程序在第一次匹配后继续寻找匹配项?
另外,为什么yacc.y中第11行和第13行有分号?因为都是用'|'连接的,我不明白为什么;放在那里。
了解如何调试程序非常重要。在文件的第一部分,您需要添加 #define YYDEBUG 1
,并在主函数中添加 yydebug = 1
。这将使您在 运行 解析器时看到确切的步骤,然后您就会知道错误在哪里。了解这一点非常重要,因为通常很难发现 Yacc 中的错误。所以调试你的程序!
%{
#define YYDEBUG 1 // This is new
%}
int main(){
yydebug = 1; // This is new
yyparse();
}
第 11 行的分号是错误的。 Yacc 规则如下所示:
Nonterminal : something here
| something else here
| ... etc.
...
;
你的语法只解析一个语句。进行以下更改:
%start statements
statements
: statement
| statements statement
;
等和以前一样。
您好,我正在编写一个简单的 yacc 程序,它获取程序代码并计算有多少个 assign 语句。
例如,对于以下代码片段:
void main() {
int a = 3;
int bb = 10;
}
我希望我的 yacc 打印出有 2 个赋值语句。由于我是初学者,所以我在网上找到了Oreily的书中的示例代码并修改了代码。
yacc.y
%{
2 #include <stdio.h>
3 int assign = 0;
4 %}
5
6 %token NAME NUMBER
7 %start statement
8 %%
9 statement: NAME '=' expression ';' {assign++;}
11 ;
12 | expression { printf("= %d\n", ); }
13 ;
14 expression: expression '+' NUMBER { $$ = + ;
15 printf ("Recognized '+' expression.\n");
16 }
17 | expression '-' NUMBER { $$ = - ;
18 printf ("Recognized '-' expression.\n");
19 }
20 | NUMBER { $$ = ;
21 printf ("Recognized a number.\n");
22 }
23 ;
24 %%
25 int main (void) {
26 yyparse();
27 printf("assign =%d", assign);
28 }
29
30 /* Added because panther doesn't have liby.a installed. */
31 int yyerror (char *msg) {
32 return fprintf (stderr, "YACC: %s\n", msg);
33 }
lex.l
1 %{
2 #include "y.tab.h"
3 extern int yylval;
4 %}
5
6 %%
7 [0-9]+ { yylval = atoi (yytext);
8 printf ("scanned the number %d\n", yylval);
9 return NUMBER; }
10 [ \t] { printf ("skipped whitespace\n"); }
11 \n { printf ("reached end of line\n");
12 return 0;
13 }
14 [a-zA-Z]+ {printf("found name"); return NAME;}
15 . { printf ("found other data \"%s\"\n", yytext);
16 return yytext[0];
17 /* so yacc can see things like '+', '-', and '=' */
18 }
19 %%
20 int yywrap(){
21 return 1;
22 }
~
test.txt
a = 3;
3+2;
b = 3;
当我构建代码时,我得到 a.out。当我 运行 ./a.out < test.txt 时,输出显示有一个赋值。它似乎只识别了第一句话。
如何让程序在第一次匹配后继续寻找匹配项?
另外,为什么yacc.y中第11行和第13行有分号?因为都是用'|'连接的,我不明白为什么;放在那里。
了解如何调试程序非常重要。在文件的第一部分,您需要添加 #define YYDEBUG 1
,并在主函数中添加 yydebug = 1
。这将使您在 运行 解析器时看到确切的步骤,然后您就会知道错误在哪里。了解这一点非常重要,因为通常很难发现 Yacc 中的错误。所以调试你的程序!
%{
#define YYDEBUG 1 // This is new
%}
int main(){
yydebug = 1; // This is new
yyparse();
}
第 11 行的分号是错误的。 Yacc 规则如下所示:
Nonterminal : something here
| something else here
| ... etc.
...
;
你的语法只解析一个语句。进行以下更改:
%start statements
statements
: statement
| statements statement
;
等和以前一样。