GNU Flex与Bison结合使用

Bison适合上下文无关文法(Context-free grammar),并采用LALR(1)算法的文法。当bison读入一个终结符(token),它会将该终结符及其语意值一起压入堆栈。这个堆栈叫做分析器堆栈(parser stack)。把一个token压入堆栈通常叫做移进(shifting);当已经移进的后n个终结符和组(groupings)与一个文法规则相匹配时,会被根据那个规则结合起来叫做归约(reduction)。

Bison布局:

%{  C/C++引入头文件和声明  %}      Bison 声明     %%    语法规则(BNF)    %%     C/C++代码

一个计算器例子:

Calculator.l:

  1. %{  
  2.     #include"Calculator.tab.h"   
  3.     int yywrap();  
  4. %}  
  5.   
  6. %%  
  7. [\n] { yylloc.first_line++; yylloc.first_column = 0; return *yytext; }  
  8. [ \t] { yylloc.first_column += (*yytext == '\t' ? 3 : 1); }  
  9. [0-9]+ { yylloc.first_column += yyleng; yylval = atoi( yytext );  return NUM; }   
  10. [+\-*/\^\(\)] { yylloc.first_column += yyleng; return *yytext; }  
  11. . { return *yytext; }  
  12. %%  
  13.   
  14. int yywrap()  
  15. return 1; }  
Calculator.y:

  1. %{  
  2.     #define YYSTYPE int   
  3.     #include <stdio.h>   
  4.     #include <math.h>   
  5.   
  6.     void yyerror (char const *);  
  7.     int yylex( void );  
  8. %}  
  9.   
  10. %token NUM  
  11.   
  12. %left '-' '+'  
  13.   
  14. %left '*' '/'  
  15.   
  16. %left NEG  
  17.   
  18. %right '^'  
  19.   
  20. %%  
  21.   
  22. input : /* empty */  
  23.       | input line  
  24.       ;  
  25.   
  26. line : '\n'  
  27.      | exp '\n' { printf ( "%d\n" , $1 ); }  
  28.      ;  
  29.   
  30. exp : NUM { $$ = $1; }  
  31.     | exp '+' exp { $$ = $1 + $3; }  
  32.     | exp '-' exp { $$ = $1 - $3; }  
  33.     | exp '*' exp { $$ = $1 * $3; }  
  34.     | exp '/' exp {  
  35.         if ( $3 ) { $$ = $1 / $3; }  
  36.         else {  
  37.           $$ = 1;  
  38.           fprintf (stderr, "%d:%d: DIVISION BY ZERO\n",@3.first_line, @3.first_column );  
  39.         }  
  40.     }  
  41.     | '-' exp %prec NEG { $$ = -$2; }  
  42.     | exp '^' exp { $$ = pow ($1, $3); }  
  43.     | '(' exp ')' { $$ = $2; }  
  44.     ;  
  45.   
  46. %%  
  47. void yyerror (char const *s )  
  48. { printf( "%s" , s ); }  
  49.   
  50. int main()  
  51. return yyparse(); }  
相关文章
相关标签/搜索
每日一句
    每一个你不满意的现在,都有一个你没有努力的曾经。
公众号推荐
   一个历史类的公众号,欢迎关注
一两拨千金