[educoder] 编译原理 用YACC(BISON)生成语法分析和翻译器

用Bison构建逆波兰计算器

/* 逆波兰符号计算器 */
 /* 功能:能够计算出合法的后缀表达式的值,包括加法、减法、乘法、除法、乘方、取反等运算 */
 /* 说明:在下面的begin和end之间添加代码,加油吧! */
 /* 提示: */

%{
          
   
  #include <ctype.h>
  #include <stdio.h>
  #include <math.h>
  int yylex (void);
  void yyerror (char const *);
%}


%define api.value.type {
          
   double}
%token NUM

%% 

/* Grammar rules and actions follow.  */

input:
  %empty
| input line
;


line:
  

| exp 
      {
          
    printf ("%.10g
", $1); }
;


exp:
  NUM           {
          
    $$ = $1;           }
 /* begin */
    | exp exp +   {
          
    $$ = $1 + $2;      } 
    | exp exp -   {
          
    $$ = $1 - $2;      } 
    | exp exp *   {
          
    $$ = $1 * $2;      } 
    | exp exp /   {
          
    $$ = $1 / $2;      } 
    /* Exponentiation */ 
    | exp exp ^   {
          
    $$ = pow ($1, $2); } 
    /* Unary minus    */ 
    | exp n       {
          
    $$ = -$1;          } 





 /* end */
;

%%

/* The lexical analyzer returns a double floating point
   number on the stack and the token NUM, or the numeric code
   of the character read if not a number.  It skips all blanks
   and tabs, and returns 0 for end-of-input.  */


int yylex (void)
{
          
   
  int c;

  /* Skip white space.  */
  while ((c = getchar ()) ==   || c == 	)
    continue;

  /* Process numbers.  */
  if (c == . || isdigit (c))
    {
          
   
      ungetc (c, stdin);
      scanf ("%lf", &yylval);
      return NUM;
    }

  /* Return end-of-input.  */
  if (c == EOF)
    return 0;
  if (c == !)
    return 0;
  /* Return a single char.  */
  return c;
}

int main (int argc, char** argv)
{
          
   
  return yyparse();
}


/* Called by yyparse on error.  */
void yyerror (char const *s)
{
          
   
  fprintf (stderr, "%s
", s);
}
经验分享 程序员 微信小程序 职场和发展