我有一个语法文件:这是简单表达式的语法。
%{
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "../C_routines/SyntaxTree.h"
#define YYERROR_VERBOSE 1
extern int yylineno;
void yyerror(const char *s);
int i=0;
%}
%union {
char *lexeme;
char *value;
double dvalue;
struct SyntaxTree *Sy;
int ivalue;
char *op;
}
%type <Sy> E S
%token <lexeme> id ID
%token <value> LITERAL
%token <dvalue> FLOAT
%token <ivalue> INT
%token <op> relop arith assign
%left '+' '-'
%left UMINUS
%%
S : id assign E { $$ = newOpNode($2, newIDNode($1), $3); printSyntaxTree($$); }
;
E : E arith E { $$ = newOpNode($2, $1, $3); }
| "(" E ")" { $$ = $2; }
| "-" E %prec UMINUS { $$ = newOpNode(UMINUS, 0, $2); }
| id { $$ = newIDNode($1); }
| INT { $$ = newIntNode($1); }
| FLOAT { $$ = newDoubleNode($1); }
;
%%
void yyerror(const char *s) {
fprintf(stderr, "Parser error at %d: %s\n", yylineno, s);
}
int main() {
yyparse();
return 0;
}
我的语法树:
typedef struct SyntaxTree {
int nodetype;
union {
char *id;
int intval;
double doubleval;
char op;
} value;
struct SyntaxTree *l;
struct SyntaxTree *r;
} SyntaxTree;
#define ID_NODE 'I'
#define INT_NODE 'D'
#define DOUBLE_NODE 'F'
#define OP_NODE '+'
#define UMINUS_NODE 'M'
SyntaxTree * newOpNode(char *op, SyntaxTree *l, SyntaxTree *r){
SyntaxTree *node = malloc(sizeof(SyntaxTree));
if(!node) {
fprintf(stderr, "Out of space\n");
exit(1);
}
node->nodetype = op;
node->value.op = op;
node->l = l;
node->r = r;
printf("added new op node");
return node;
}
SyntaxTree * newDoubleNode(double value){
SyntaxTree *node = malloc(sizeof(SyntaxTree));
if(!node) {
fprintf(stderr, "Out of space\n");
exit(1);
}
node->nodetype = DOUBLE_NODE;
node->value.doubleval = value;
node->l = node->r = NULL;
printf("added new double node");
return node;
}
SyntaxTree * newIntNode(int value){
SyntaxTree *node = malloc(sizeof(SyntaxTree));
if(!node) {
fprintf(stderr, "Out of space\n");
exit(1);
}
node->nodetype = INT_NODE;
node->value.intval = value;
node->l = node->r = NULL;
printf("added new int node");
return node;
}
SyntaxTree * newIDNode(char* id){
SyntaxTree *node = malloc(sizeof(SyntaxTree));
if(!node) {
fprintf(stderr, "Out of space\n");
exit(1);
}
node->nodetype = ID_NODE;
node->value.id = strdup(id);
node->l = node->r = NULL;
printf("added new id node");
return node;
}
void printSyntaxTree(SyntaxTree *head) {
if (head != NULL) {
printSyntaxTree(head->l);
switch (head->nodetype) {
case ID_NODE:
printf("Identifier : %s ", head->value.id);
break;
case INT_NODE:
printf("Integer : %d ", head->value.intval);
break;
case DOUBLE_NODE:
printf("Double : %f ", head->value.doubleval);
break;
case OP_NODE:
printf("Arithmetic Operator ");
break;
case '=':
printf("Assignment Operator ");
break;
default:
printf("Unknown node type: %c ", head->nodetype);
break;
}
printSyntaxTree(head->r);
}
}
当我运行解析器时,
a=a+b
Identifier : a Assignment Operator
Identifier : a added new id nodeArithmetic Operator
Identifier : b added new id node
a=0
Identifier : a added new op nodeadded new id nodeadded new op nodeParser error at 2: syntax error, unexpected id, expecting $end
无论我在第二行给出什么,它都会给出
expecting $end
。
我使用
bison
表示 yacc
,使用 flex
表示具有语法树结构的 lex
。
什么是
$end
?怎么给呢?
我浏览了SO和其他网站来寻找答案,但仍然没有用。我什至搜索过这个问题但最终徒劳无功
你的语法有很多问题。您已将 +/- 定义为左关联标记,但不在语法中使用它们。您似乎已经消耗了 arith 中那些没有关联性的代币。
您需要将 +/- 添加到语法中,与 arith 分开。 您还需要使 uminus 右结合。