📜  YACC程序,用于二进制到十进制的转换(1)

📅  最后修改于: 2023-12-03 15:06:05.653000             🧑  作者: Mango

YACC程序介绍 - 二进制到十进制转换

什么是YACC?

YACC是一个强大的编译器开发工具,用于生成编译器的语法分析部分。它接受一个上下文无关文法作为输入,并生成一个解析器(也称为语法分析器)来解析输入。它常常与Lex一起使用,因为Lex可以生成词法分析器,YACC则可以生成语法分析器。

程序功能

本文所介绍的YACC程序用于将二进制转换为十进制。

实现

首先,我们需要定义上下文无关文法来描述二进制数和十进制数之间的转换规则。

%token DIGIT
%left '+''-'
%left '*''/'

%%

expression: /* empty */
    | expression '+' term { $$ = $1 + $3; }
    | expression '-' term { $$ = $1 - $3; }
term:
    | term '*' factor { $$ = $1 * $3; }
    | term '/' factor { $$ = $1 / $3; }
factor:
    | DIGIT
    | factor '*' 2 { $$ = $1 * 2; }
    | factor '/' 2 { $$ = $1 / 2; }
    ;

这个文法定义了如下的规则:

  1. 表达式可以是一个空串,或是由一个数字和一系列加减号、乘除号组成的计算表达式。
  2. 项为数字或因子与乘除号的运算结果。
  3. 因子为数字或因子与2的乘除结果。

具体而言,由于二进制数的位数与2的幂次有关,因此该文法中以2的幂次作为乘除的基准。

接下来,我们需要编写Lex扫描器,以匹配输入的二进制数。

%{
#include <stdlib.h>
#include "y.tab.h"
%}

%%

[01]+  { yylval = strtol(yytext, NULL, 2); return DIGIT; }
\n     { return 0; }
.      { return -1; }

%%

该扫描器匹配输入中的二进制数,将其转换为十进制数并保存在yylval中,然后返回关键字DIGIT。同时,我们使用y.tab.h来定义与关键字交互的值。

最后,我们需要编写主程序以调用yyparse()函数来解析输入,如下所示。

#include <stdio.h>
#include "y.tab.h"

int main(void) {
    yyparse();
    return 0;
}

void yyerror(const char *error_message) {
    fprintf(stderr, "%s\n", error_message);
}

该程序首先调用yyparse()解析输入结果,然后在必要时显示错误信息。

使用方法
  1. 将程序保存在名为"calculator.y"的文件中。
  2. 在终端中,输入以下命令创建目标文件和可执行文件。
yacc -d calculator.y
lex calculator.l
gcc -o calculator y.tab.c lex.yy.c -ll
  1. 查看生成的可执行文件名为"calculator",使用以下命令即可执行该程序。在程序提示符下,输入二进制数,然后按回车键。你将看到转换后的十进制数。
./calculator
1010
10
总结

通过上述步骤,我们已成功地实现了一个将二进制转换为十进制的YACC程序。此外,在编写YACC程序时,我们需要定义上下文无关文法以描述输入和输出的规则,然后编写Lex扫描器来匹配输入,最后在主程序中调用yyparse()解析输入。