【Lex & Yacc】计算器DEMO

Python源码编译

代码文件 calc.y

%require "3.0"
%language "c"

%{
#include <stdio.h>
#include <stdlib.h>

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

%union {
    int intval;
}

%token ADD SUB MUL DIV NUMBER
%token LBRAC RBRAC
%token ENDLINE UNKNOWN

%type <intval> NUMBER
%type <intval> line expr term factor

%%
top     : line              {};
top     : top line          {};

line    : expr ENDLINE      {printf("= %d\n", $1);};
line    : ENDLINE           {};

expr    : expr ADD term     {$$ = $1 + $3;};
expr    : expr SUB term     {$$ = $1 - $3;};
expr    : term              {$$ = $1;};

term    : term MUL factor   {$$ = $1 * $3;};
term    : term DIV factor   {$$ = $1 / $3;};
term    : factor            {$$ = $1;};

factor  : NUMBER            {$$ = $1;};
factor  : LBRAC expr RBRAC  {$$ = $2;};

%%

int yylex()
{
  int c = fgetc(stdin);
  switch (c) {
    case EOF:
      return 0;
    case '+':
      return ADD;
    case '-':
      return SUB;
    case '*': case 'x':
      return MUL;
    case '/':
      return DIV;
    case '(':
      return LBRAC;
    case ')':
      return RBRAC;
    case ' ': case '\t':
      return yylex();  // 递归
    case '\r': case '\n':
      return ENDLINE;
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
      {
        int dig = 0;
        do {
          dig = dig * 10 + c - '0';
          c = fgetc(stdin);
        } while (c >= '0' && c <= '9');
        ungetc(c, stdin);
        yylval.intval = dig;
      }
      return NUMBER;
    default:
      return UNKNOWN;
  }
  return 0;
}

void yyerror(const char* const err)
{
  // 遇到无法识别的,一行都废掉
  char *line = (char*)malloc(8192);
  ungetc(' ', stdin);
  fgets(line, 8192, stdin);
  free(line);
  fprintf(stderr, "Parse error: %s\n", err);
}

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

没安装bison的需要先安装bison

yum -y install bison

编译前要先用 bison 生成代码

[root@centos test]# bison -o calc.c -y calc.y
[root@centos test]# gcc -o calc calc.c
[root@centos test]# ./calc
(8 - 5 * 2 + 3) * 17 - 21 / 3 -5
= 5
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值