c/c++语言开发共享来自词法分析器和语法的简单计算器的意外行为

我开始了整个Flex和Bison的世界。 所以我按照教程为flex编写了这个l文件:

%{ #include  #include  void yyerror(char *); #include "y.tab.h" %} %% /******************** RULES ********************/ /* One letter variables */ [az] { yylval = *yytext - 'a'; // This is to return a number between 0 and 26 representting the letter variable. printf("VAR: %sn",yytext); return VARIABLE; } /* Integer constants */ [0-9]+ { yylval = atoi(yytext); printf("INT: %dn",yylval); return INTEGER; } /* Operators */ [-+()=/*n]+ { printf("OPR: %sn",yytext); return *yytext; /*n is considered an operator because it signals the end of a statement*/ } /* This skips white space and tab chararcters */ [ t] ; /* Anything esle is not allowed */ . yyerror("Invalid character found"); /***************** SUBROUTINES *****************/ %% int yywrap(void){ return 1; } 

这就是语法:

 /***************** DEFINITIONS *****************/ %token INTEGER VARIABLE %left '+' '-' %left '*' '/' %{ void yyerror(char *); int yylex(void); int sym[26]; %} %% /******************** RULES ********************/ program: program statement 'n' | ; statement: expr { printf("EXPR: %dn", $1); } | VARIABLE '=' expr { sym[$1] = $3; } ; expr: INTEGER | VARIABLE { $$ = sym[$1]; } | expr '+' expr { $$ = $1 + $3; } | expr '-' expr { $$ = $1 - $3; } | expr '*' expr { $$ = $1 * $3; } | expr '/' expr { $$ = $1 / $3; } | '(' expr ')' { $$ = $2; } ; %% /***************** SUBROUTINES *****************/ void yyerror(char *s){ printf("%sn",s); } int main(void) { yyparse(); return 0; } 

并且出现了几个问题。 第一个来自编译时。 这是我编译的方式:

 bison -d bas.y -o y.tab.c flex bas.l gcc y.tab.h lex.yy.c y.tab.c -o bas_fe 

这给了我两个这样的警告:

 bas.y:24:7: warning: incompatible implicit declaration of built-in function 'printf' expr { printf("EXPR: %dn", $1); } ^ bas.y: In function 'yyerror': bas.y:39:4: warning: incompatible implicit declaration of built-in function 'printf' printf("%sn",s); 

现在,它们是警告和打印工作,但我发现它很奇怪,因为我已经清楚地包含了使用printf函数的库。

我真正的问题来自于我与该计划的互动。 这是控制台输出:

 x = (3+5) VAR: x OPR: = OPR: ( INT: 3 OPR: + INT: 5 x OPR: ) VAR: x syntax error 

由此产生了几个问题。 1)输入x =(3 + 5)后,程序打印输出不包括’)’为什么?

2)当输入x(预期输出为8)时,才会出现’)’。 为什么?

3)然后是“语法错误”消息。 我假设消息是在y.tab.c的代码中自动生成的。 可以改成更有意义的东西吗? 我是正确的假设语法错误是因为程序找到了)和换行符和变量,并且这不符合程序语句,如语法所定义的那样?

    我已经清楚地包含了用于printf函数的库。

    您在flex文件中包含stdio.h ,但在bison文件中没有。 有关printf未声明的警告来自你的野牛文件,而不是你的flex文件。

    使用gcc(或任何其他C编译器)编译多个文件时,文件将独立编译,然后链接在一起。 所以你的命令

     gcc y.tab.h lex.yy.c y.tab.c -o bas_fe 

    不会连接这三个文件并将它们编译为一个单元。 相反,它独立编译三个文件,包括无用地编译头文件y.tab.h

    你应该做的是在你的bas.y文件中添加一个prolog块,包括#include

    [-+()=/*n]+ {... return *yytext; ...}

    此弹性模式匹配集[-+()=/*n]中的任意数量的字符。 所以在输入x=(3+5)n)n被匹配为单个标记 。 但是,该操作返回*yytext*yytext的第一个字符,实际上忽略了n 。 由于你的语法需要n ,这会产生语法错误。

    只需从模式中删除重复运算符即可。

    可以将错误消息更改为更有意义的内容吗?

    如果您有一个相当现代的野牛,请添加声明

     %error-verbose 

    到你的野牛文件的开头。

      以上就是c/c++开发分享来自词法分析器和语法的简单计算器的意外行为相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/519340.html

      (0)
      上一篇 2020年12月5日
      下一篇 2020年12月5日

      精彩推荐