📅  最后修改于: 2023-12-03 14:48:40.079000             🧑  作者: Mango
YACC是"Yet Another Compiler Compiler"的缩写,意为"仍是另一个编译器编译器"。它是一种自动生成编译器的工具,其中包括词法分析器和语法分析器。
本篇文章介绍了一个使用YACC实现的中缀表达式转换为后缀表达式的程序。
该程序可以将中缀表达式转换为后缀表达式。
例如,中缀表达式:
3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3
将被转换为后缀表达式:
3 4 2 * 1 5 - 2 3 ^ ^ / +
该程序主要由两部分组成:词法分析器和语法分析器。
词法分析器会将输入的中缀表达式字符串分解为若干个token,例如数字、运算符、括号等。这些token将被传递给语法分析器进行处理。
语法分析器使用一个栈来保存token。当一个token被读入时,根据其类型进行处理。如果是数字,则将其直接输出;如果是运算符,则判断与栈顶元素的优先级关系,若比栈顶元素优先级高,则入栈,否则将栈顶元素弹出并输出,直到该运算符可以入栈。如果是左括号,则可以直接入栈;如果是右括号,则将栈顶元素弹出并输出,直到匹配的左括号被弹出。
最终,栈中剩余的运算符都将被输出。输出的字符串即为后缀表达式。
以下是完整的代码片段:
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int yylex(void);
void yyerror(char *s);
int yyparse(void);
extern char yytext[];
%}
%token NUMBER
%token PLUS MINUS TIMES DIVIDE LPAREN RPAREN POWER
%left PLUS MINUS
%left TIMES DIVIDE
%right POWER
%%
input: /* empty */
| input line
;
line: '\n'
| exp '\n' { printf("%s ", $1); }
;
exp: factor
| exp PLUS factor { printf("+ "); }
| exp MINUS factor { printf("- "); }
;
factor: term
| factor TIMES term { printf("* "); }
| factor DIVIDE term { printf("/ "); }
;
term: primary
| primary POWER term { printf("^ "); }
;
primary: NUMBER { printf("%s ", yytext); }
| LPAREN exp RPAREN
;
%%
int main(void)
{
return yyparse();
}
int yylex(void)
{
int c = getchar();
if (c == EOF)
return 0;
if (isdigit(c))
{
int value = c - '0';
while (isdigit(c = getchar()))
value = value * 10 + c - '0';
ungetc(c, stdin);
sprintf(yytext, "%d", value);
return NUMBER;
}
if (isspace(c))
return yylex();
if (c == '+')
return PLUS;
if (c == '-')
return MINUS;
if (c == '*')
return TIMES;
if (c == '/')
return DIVIDE;
if (c == '^')
return POWER;
if (c == '(')
return LPAREN;
if (c == ')')
return RPAREN;
yyerror("invalid input");
}
void yyerror(char *s)
{
fprintf(stderr, "%s\n", s);
exit(EXIT_FAILURE);
}
本篇文章介绍了一个使用YACC实现的中缀表达式转换为后缀表达式的程序。通过这个程序,我们可以更好地了解YACC的使用,同时深入理解中缀表达式和后缀表达式的转换原理。