📅  最后修改于: 2023-12-03 14:43:53.259000             🧑  作者: Mango
Lex程序是一种自动化工具,可用于生成基于正则表达式的词法分析器。本文将介绍如何使用Lex程序实现一个简单的计算器,支持基本的四则运算和括号。
首先,我们需要定义词法分析器,以便能够识别输入的表达式中的单词(例如数字、运算符等)。以下是我们的词法分析器:
%{
#include <stdio.h>
%}
%%
[ \t\n] ; // 忽略空格、制表符和换行符
[0-9]+\.[0-9]+|[0-9]+ printf("NUMBER ");
[+\-*/(){}] printf("%c ", yytext[0]);
. ; // 忽略其他字符
%%
int main()
{
yylex();
return 0;
}
上述代码定义了一个简单的词法分析器,它可以识别数字和运算符。
现在,我们需要实现一个语法分析器来解析输入的表达式。语法分析器通常使用递归下降分析法,也就是说,它会从输入的表达式的最外层开始,逐步解析内层的子表达式。以下是我们的语法分析器:
%{
#include <stdio.h>
#include <stdlib.h>
#define YY_DECL int yylex()
int yylex();
void yyerror(char *);
int brace = 0;
%}
%union {
int num;
char op;
}
%token NUMBER
%token PLUS MINUS TIMES DIVIDE LPAREN RPAREN LBRACE RBRACE
%left PLUS MINUS
%left TIMES DIVIDE
%left UMINUS
%type <num> expr term factor
%%
input: /* nothing */
| input line ;
line: '\n' { brace = 0; }
| expr '\n' { printf("= %d\n", $1); brace = 0; }
| error '\n' { yyerror("Syntax error"); brace = 0; }
expr: term
| expr PLUS term { $$ = $1 + $3; }
| expr MINUS term { $$ = $1 - $3; }
term: factor
| term TIMES factor { $$ = $1 * $3; }
| term DIVIDE factor { if ($3 == 0) yyerror("Divide by zero"); else $$ = $1 / $3; }
factor: NUMBER
| LPAREN expr RPAREN { $$ = $2; }
| MINUS factor %prec UMINUS { $$ = -$2; }
%%
int main()
{
yyparse();
return 0;
}
int yyerror(char *s) {
fprintf(stderr, "%s\n", s);
return 0;
}
上述代码实现了一个简单的语法分析器,它可以识别四则运算和括号。
现在,我们可以将上面两个步骤中的代码片段合并到一个文件中,并使用下面的命令将其编译:
$ lex calculator.l
$ gcc lex.yy.c -o calculator -ll
接下来,我们可以运行程序:
$ ./calculator
1+2*3
= 7
(1+2)*3
= 9
-1+(1+2)*-3
= -8
本文介绍了如何使用Lex程序实现一个简单的计算器。通过词法分析器和语法分析器的组合,我们可以解析输入的表达式并计算其值。这里只是一个简单的例子,但是它可以作为您自己的项目的起点。