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. intyywrap();
  4. %}
  5. %%
  6. [\n]{yylloc.first_line++;yylloc.first_column=0;return*yytext;}
  7. [\t]{yylloc.first_column+=(*yytext=='\t'?3:1);}
  8. [0-9]+{yylloc.first_column+=yyleng;yylval=atoi(yytext);returnNUM;}
  9. [+\-*/\^\(\)]{yylloc.first_column+=yyleng;return*yytext;}
  10. .{return*yytext;}
  11. %%
  12. intyywrap()
  13. {return1;}
%{
	#include"Calculator.tab.h"
	int yywrap();
%}

%%
[\n] { yylloc.first_line++; yylloc.first_column = 0; return *yytext; }
[ \t] { yylloc.first_column += (*yytext == '\t' ? 3 : 1); }
[0-9]+ { yylloc.first_column += yyleng; yylval = atoi( yytext );  return NUM; } 
[+\-*/\^\(\)] { yylloc.first_column += yyleng; return *yytext; }
. { return *yytext; }
%%

int yywrap()
{ return 1; }
Calculator.y:

  1. %{
  2. #defineYYSTYPEint
  3. #include<stdio.h>
  4. #include<math.h>
  5. voidyyerror(charconst*);
  6. intyylex(void);
  7. %}
  8. %tokenNUM
  9. %left'-''+'
  10. %left'*''/'
  11. %leftNEG
  12. %right'^'
  13. %%
  14. input:/*empty*/
  15. |inputline
  16. ;
  17. line:'\n'
  18. |exp'\n'{printf("%d\n",$1);}
  19. ;
  20. exp:NUM{$$=$1;}
  21. |exp'+'exp{$$=$1+$3;}
  22. |exp'-'exp{$$=$1-$3;}
  23. |exp'*'exp{$$=$1*$3;}
  24. |exp'/'exp{
  25. if($3){$$=$1/$3;}
  26. else{
  27. $$=1;
  28. fprintf(stderr,"%d:%d:DIVISIONBYZERO\n",@3.first_line,@3.first_column);
  29. }
  30. }
  31. |'-'exp%precNEG{$$=-$2;}
  32. |exp'^'exp{$$=pow($1,$3);}
  33. |'('exp')'{$$=$2;}
  34. ;
  35. %%
  36. voidyyerror(charconst*s)
  37. {printf("%s",s);}
  38. intmain()
  39. {returnyyparse();}
%{
	#define YYSTYPE int
	#include <stdio.h>
	#include <math.h>

	void yyerror (char const *);
	int yylex( void );
%}

%token NUM

%left '-' '+'

%left '*' '/'

%left NEG

%right '^'

%%

input : /* empty */
      | input line
      ;

line : '\n'
     | exp '\n' { printf ( "%d\n" , $1 ); }
     ;

exp : NUM { $$ = $1; }
    | exp '+' exp { $$ = $1 + $3; }
    | exp '-' exp { $$ = $1 - $3; }
    | exp '*' exp { $$ = $1 * $3; }
    | exp '/' exp {
    	if ( $3 ) { $$ = $1 / $3; }
    	else {
    	  $$ = 1;
    	  fprintf (stderr, "%d:%d: DIVISION BY ZERO\n",@3.first_line, @3.first_column );
    	}
    }
    | '-' exp %prec NEG { $$ = -$2; }
    | exp '^' exp { $$ = pow ($1, $3); }
    | '(' exp ')' { $$ = $2; }
    ;

%%
void yyerror (char const *s )
{ printf( "%s" , s ); }

int main()
{ return yyparse(); }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值