parsing - Yacc 和 Lex "syntax error"

标签 parsing ubuntu compiler-construction yacc lex

当我试图检查表达式“boolean x;”时我收到“语法错误”,我不明白为什么。
当我检查表达式“x = 3;”时或“2 = 1;”,生成抽象语法树并且不出现错误。
(我不允许在这个项目中使用 Lex 和 Yacc 之外的任何东西,我使用的是 Ubuntu)

莱克斯文件:

%%
[\n\t ]+; 
boolean {return BOOL;}
TRUE {return TRUE;}
FALSE {return FALSE;}
[0-9]+ {return NUM;}
[a-zA-Z][0-9a-zA-Z]* {return ID;}
. {return yytext[0];}
%%

yacc 文件:
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node{
    struct node *left;
    struct node *right;
    char *token;
    } node;
node *mknode(node *left, node *right, char *token);
void printtree(node *tree);
#define YYSTYPE struct node *
%}
%start code
%token ID,NUM,TRUE,FALSE,BOOL
%right '='
%%

code:lines{printtree($1); printf("\n");}
lines:calcExp';'|assignExp';'|boolExp ';'{$$ = $1;}
boolExp: boolST id{$$=$2;} 
calcExp: number '+' number {$$ = mknode($1,$3,"+");}
assignExp: id '=' number{$$ = mknode($1,$3,"=");}
boolSt : BOOL;
id : ID {$$ = mknode(0,0,yytext);}
number : NUM{$$ = mknode(0,0,yytext);}

%%
#include "lex.yy.c"
int main (void) {return yyparse();}

node *mknode(node *left, node *right, char *token){
    node *newnode = (node *)malloc(sizeof(node));
    char *newstr = (char *)malloc(strlen(token)+1);
    strcpy(newstr, token);
    newnode->left = left;
    newnode->right = right;
    newnode->token = newstr;
    return newnode;
 }

void printtree(node *tree){
    if (tree->left || tree->right)
        printf("(");
    printf(" %s ", tree->token);
    if(tree->left)
        printtree(tree->left);
    if(tree->right)
        printtree(tree->right);
    if(tree->left || tree->right)
        printf(")");
}
void yyerror (char *s) {
    fprintf (stderr, "%s\n",s);}

最佳答案

调试语法错误的第一步是启用 %error-verbose在野牛文件中。现在,它不再只是说“语法错误”,而是告诉我们 boolean 之后有一个意外字符。需要标识符时的关键字。

所以让我们在 . 中添加一条打印语句。词法分析器中的规则打印匹配的字符,以便我们可以看到它在哪里产生了意外的字符。现在我们看到它打印了一个空格,但是空格应该被忽略了,对吧?所以让我们看看应该这样做的规则:

[\n\t ]+;

如果你的编辑器对 flex 文件有正确的语法高亮,问题现在应该很明显了:;被视为规则的一部分,而不是行动的一部分。也就是说,规则匹配空格,后跟分号,而不是仅仅匹配空格。

所以删除分号,它应该可以工作。

关于parsing - Yacc 和 Lex "syntax error",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47555392/

相关文章:

parsing - 解析表中非终结符 A 的可为空性

c++ - 一种省略为仅用于构造最终对象的对象命名的方法

parsing - 如何解析上下文相关的语法?

python - 使用 pyparsing 的这项特定工作的难度? (初学者)

java - 以秒为单位的时差给了我错误的答案

ubuntu - 如何在 Ubuntu 14.04 上安装 MarkLogic 8?

linux - 将多行记录的日志文件中的数据提取到 CSV

ubuntu - X11 转发仅在首次使用 Putty 后才能在 Ubuntu 上使用 Windows 10 cmd-line ssh

html - Yaws 文件未正确渲染

c++ - 编译器/解释器在解释时创建函数通常是个好主意吗?