【发布时间】:2023-03-19 14:11:02
【问题描述】:
当我试图检查表达式“boolean x;”时我收到“语法错误”,我不明白为什么。 当我检查表达式“x = 3;”时或“2 = 1;”,生成抽象语法树并且不出现错误。 (我不允许在这个项目中使用 Lex 和 Yacc 之外的任何东西,我使用的是 Ubuntu)
Lex 文件:
%%
[\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);}
【问题讨论】:
-
拼写:是“bool”还是“boolean”?
-
对不起。我正在尝试检查表达式“boolean x;”
-
请格式化这个难以辨认的混乱。
-
首先修复由 yacc/bison 产生的所有警告。最相关的是“错误:使用了符号 boolST,但未定义为令牌并且没有规则”。 (如果你仔细观察,规则
boolSt: BOOL并没有定义符号boolST。)我不清楚为什么你觉得你需要一个非终端。你可以写boolExp: BOOL id。或者,如果您使用过%token BOOL "boolean",您可以使用更具可读性的boolExp: "boolean" id。 -
@sophievi:字符类将匹配字符列表中的字符。
[\n\t ]将匹配换行符、制表符或空格。[ \n\t]也是如此。但[\n\t]只匹配换行符或制表符。您的问题具有正确的字符类,但由于 sepp2k 指出的原因而失败。您在任何地方都没有表明您删除了字符类中的空格。
标签: parsing ubuntu compiler-construction yacc lex