📜  YACC程序,用于将中缀转换为后缀表达式(1)

📅  最后修改于: 2023-12-03 14:48:40.079000             🧑  作者: Mango

YACC程序,用于将中缀转换为后缀表达式

简介

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的使用,同时深入理解中缀表达式和后缀表达式的转换原理。