c - 算术表达式也无法在 yacc 语法中正确解析

标签 c bison flex-lexer yacc

我有以下yacc:

%{
#include  <stdio.h>
extern FILE* yyin;
extern char* yytext;

%}

%token VAR ID_NAME TYPE_STRING TYPE_BOOL TYPE_NUMBER
%token CONST VALUE_STRING VALUE_BOOL VALUE_NUMBER

%left '*' '/'
%left '+' '-'

%%

program
    : declarations
    ;

declarations
    : declaration
    | declarations declaration
    ;

declaration
    : var_declaration
    | const_declaration
    ;

value
    : VALUE_BOOL
    | VALUE_STRING
    ;

arithmetic_expression
    : arithmetic_expression '+' arithmetic_expression
    | arithmetic_expression '-' arithmetic_expression
    | arithmetic_expression '*' arithmetic_expression
    | arithmetic_expression '/' arithmetic_expression
    | '(' arithmetic_expression ')'
    | VALUE_NUMBER
    ;

initializer
    : value
    | arithmetic_expression
    ;

initialization
    : ID_NAME '=' initializer
    ;

init_list
    : initialization
    | init_list ',' initialization
    ;

init_or_id
    : initialization
    | ID_NAME
    ;

init_or_id_list
    : init_or_id
    | init_or_id_list ',' init_or_id
    ;

var_declaration
    : VAR ':' type init_or_id_list ';' { printf("%s booyah\n", $1);  } 
    ;

const_declaration: CONST ':' type init_list ';' {printf("koskos\n");}
    ;

type: TYPE_NUMBER 
    | TYPE_STRING
    | TYPE_BOOL
    ;

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

int main(int argc, char** argv[])
{

    yyparse();
    return 0;
}

功能之一应该是允许用户使用算术表达式(的值)初始化变量和常量。像这样的var:number = (1+2+3);。但是,我不确定为什么,但解析器仅识别使用运算符 */ 的表达式。当我使用使用运算符 +- 的表达式时,出现语法错误。

这是关联的 lex 文件:

%{

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

%}

id_name [a-zA-Z]([a-zA-Z0-9])*
value_string \"([a-zA-Z0-9*+z=])*\"
value_number [+-]?([0-9]*[.])?[0-9]+

%%

"var"                   { return VAR;  }
"const"                 { return CONST; }
"string"                { return TYPE_STRING; }
"number"                { return TYPE_NUMBER; }
"bool"                  { return TYPE_BOOL; }
"true"                  { return VALUE_BOOL; }
"false"                 { return VALUE_BOOL; }

{value_number}          { return VALUE_NUMBER; }
{value_string}          { return VALUE_STRING; }
{id_name}               { return ID_NAME; }


","                     { return ','; }
":"                     { return ':'; }
";"                     { return ';'; }
"="                     { return '='; }
"+"                     { return '+'; }
"-"                     { return '-'; }
"*"                     { return '*'; }
"/"                     { return '/'; }
"("                     { return '('; }
")"                     { return ')'; }


%%

我使用以下命令编译该文件:

yacc -vd grammar.y
flex -l lex.l
gcc -Wall -o lang lex.yy.c y.tab.c -ll -lfl

例如,以下表达式:var:number var1=12*12; 被成功识别。但这一个: var:number var1=12+12; 会导致语法错误。我不确定我错了什么。

最佳答案

尝试使用 Flex --debug选项。这将生成一个扫描仪,向您显示它正在做什么的痕迹。我想您很快就会发现问题。

剧透

+12被词法化为单个数字标记,而不是后跟数字的运算符

关于c - 算术表达式也无法在 yacc 语法中正确解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41688020/

相关文章:

c - 用 C 语言编写位图

C - 矩阵主线和反对角线(替换)

c++ - 为什么我们在解析器文件中定义 union 时使用复杂类的指针?

yacc - 从 BNF 语法派生状态机

c++ - 错误时会发生什么 - Bison

c - 建立 TCP 套接字连接时出现问题

c++ - 如何在原生 Node 插件中成功链接 Flex、Bison 和 Node.js?

grammar - Flex 和 Bison 的使用

c - 将匹配的字符存储在flex中

c - 为什么这种移位有效? (用于将数字打印为二进制)