该编译器来自miniC compiler。
我正在构建一个到PDL的转换器,并添加FACTOR TERM MathEql MathRel
以解决偏移减少错误,我在语法上遇到了问题。
miniC.y
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "AST.h"
#include "print.h"
#include "lex.yy.h"
#include "Converter.h"
#include "symboltable.h"
//global variables which can be used in other .c .h
struct PROGRAM *head;
FILE *fp; //for AST
FILE *fp2; //for symboltable
void yyerror(char const*text){
fprintf(stderr, "%s\n", text);
}
/*
void lyyerror(YYLTYPE t, char *s, ...)
{
va_list ap;
va_start(ap, s);
if(t.first_line)
fprintf(stderr, "%d.%d-%d.%d: error: ", t.first_line, t.first_column, t.last_line, t.last_column);
vfprintf(stderr, s, ap);
fprintf(stderr, "\n");
}
*/
%}
%union{
struct PROGRAM *ptr_program;
struct DECLARATION *ptr_declaration;
struct IDENTIFIER *ptr_identifier;
struct FUNCTION *ptr_function;
struct PARAMETER *ptr_parameter;
struct COMPOUNDSTMT *ptr_compoundstmt;
struct STMT *ptr_stmt;
struct ASSIGN *ptr_assign;
struct CALL *ptr_call;
struct ARG *ptr_arg;
struct WHILE_S *ptr_while_s;
struct FOR_S *ptr_for_s;
struct IF_S *ptr_if_s;
struct ID_S *ptr_id_s;
struct EXPR *ptr_expr;
struct ADDIOP *ptr_addiop;
struct MULTOP *ptr_multop;
struct RELAOP *ptr_relaop;
struct EQLTOP *ptr_eqltop;
struct FACTOR *ptr_factor;
struct TERM *ptr_term;
struct MATHEQL *ptr_math_eql;
struct MATHREL *ptr_math_rel;
Type_e type;
//TODO int, float to char*
int intnum;
float floatnum;
char* id;
}
%token <intnum>INTNUM <floatnum>FLOATNUM <id>ID
%token INT FLOAT MINUS PLUS MULT DIV LE GE EQ NE GT LT
%token IF ELSE FOR WHILE DO RETURN DQUOT_T SQUOT_T AMP_T
%right ELSE then;
%type <type> Type
%define parse.error verbose
%type <ptr_program> Program
%type <ptr_declaration> Declaration DeclList
%type <ptr_identifier> Identifier IdentList
%type <ptr_function> Function FuncList
%type <ptr_parameter> Parameter ParamList
%type <ptr_compoundstmt> CompoundStmt
%type <ptr_stmt> Stmt StmtList
%type <ptr_assign> Assign AssignStmt
%type <ptr_call> Call CallStmt
%type <ptr_arg> Arg ArgList
%type <ptr_while_s> While_s
%type <ptr_for_s> For_s
%type <ptr_if_s> If_s
%type <ptr_expr> Expr RetStmt
%type <ptr_addiop> Addiop
%type <ptr_multop> Multop
%type <ptr_relaop> Relaop
%type <ptr_eqltop> Eqltop
%type <ptr_factor> FACTOR
%type <ptr_term> TERM
%type <ptr_id_s> Id_s
%type <ptr_math_eql> MathEql
%type <ptr_math_rel> MathRel;
%start Program
%%
//입력이 없는 경우는 main() 에서 head = NULL 인 상태로 처리됨.
//"DeclList" in "Program" denotes global declaration
Program: DeclList FuncList {
struct PROGRAM *prog = (struct PROGRAM*) malloc (sizeof (struct PROGRAM));
prog->decl = $1;
prog->func = $2;
head = prog;
$$ = prog;
}
| DeclList {
struct PROGRAM *prog = (struct PROGRAM*) malloc (sizeof (struct PROGRAM));
prog->decl = $1;
prog->func = NULL;
head = prog;
$$ = prog;
}
| FuncList {
struct PROGRAM *prog = (struct PROGRAM*) malloc (sizeof (struct PROGRAM));
prog->decl = NULL;
prog->func = $1;
head = prog;
$$ = prog;
}
;
DeclList: Declaration {
$$ = $1;
}
| DeclList Declaration {
struct DECLARATION *decl;
decl = $2;
decl->prev = $1;
$$ = decl;
}
;
FuncList: Function {
$$ = $1;
}
| FuncList Function {
struct FUNCTION *func;
func = $2;
func->prev = $1;
$$ = func;
}
;
Declaration: Type IdentList ';' {
struct DECLARATION *decl = (struct DECLARATION*) malloc (sizeof (struct DECLARATION));
decl->t = $1;
decl->id = $2;
$$ = decl;
}
;
IdentList: Identifier {
$$ = $1;
}
| IdentList ',' Identifier {
struct IDENTIFIER *iden;
iden = $3;
iden->prev = $1;
$$ = iden;
}
;
Identifier: ID {
struct IDENTIFIER *iden = (struct IDENTIFIER*) malloc (sizeof (struct IDENTIFIER));
iden->ID = $1;
iden->intnum = 0; // zero, If scalar
iden->prev = NULL;
$$ = iden;
}
| ID '[' INTNUM ']' {
struct IDENTIFIER *iden = (struct IDENTIFIER*) malloc (sizeof (struct IDENTIFIER));
iden->ID = $1;
iden->intnum = $3; // zero, If scalar
iden->prev = NULL;
$$ = iden;
}
;
ParamList: Parameter {
struct PARAMETER *param;
param = $1;
param->prev = NULL;
$$ = param;
}
| ParamList ',' Parameter {
struct PARAMETER *param;
param = $3;
param->prev = $1;
$$ = param;
}
Parameter: Type Identifier {
struct PARAMETER *param = (struct PARAMETER*) malloc (sizeof (struct PARAMETER));
param->t = $1;
param->id = $2;
param->prev = NULL;
$$ = param;
}
Function: Type ID '(' ')' CompoundStmt {
struct FUNCTION *func = (struct FUNCTION*) malloc (sizeof (struct FUNCTION));
func->t = $1;
func->ID = $2;
func->param = NULL;
func->cstmt = $5;
$$ = func;
}
| Type ID '(' ParamList ')' CompoundStmt {
struct FUNCTION *func = (struct FUNCTION*) malloc (sizeof (struct FUNCTION));
func->t = $1;
func->ID = $2;
func->param = $4;
func->cstmt = $6;
$$ = func;
}
;
Type: INT { $$ = eInt;}
| FLOAT { $$ = eFloat;}
;
//cf. Stmt 안에 CompoundStmt 존재
//StmtList 에서 empty 입력을 허용하지 않도록 StmtList 가 없는 Compound 정의
CompoundStmt: '{' '}' {
struct COMPOUNDSTMT *comp = (struct COMPOUNDSTMT*) malloc (sizeof (struct COMPOUNDSTMT));
comp->decl = NULL;
comp->stmt = NULL;
$$ = comp;
/*
{ } 안에 { } 만 들어 있는 경우도 표현하기 위하여,
NULL을 반환하지 않고 내용이 비어있어도 동적할당을 하였다.
*/
}
| '{' StmtList '}' {
struct COMPOUNDSTMT *comp = (struct COMPOUNDSTMT*) malloc (sizeof (struct COMPOUNDSTMT));
comp->decl = NULL;
comp->stmt = $2;
$$ = comp;
}
| '{' DeclList StmtList '}' {
struct COMPOUNDSTMT *comp = (struct COMPOUNDSTMT*) malloc (sizeof (struct COMPOUNDSTMT));
comp->decl = $2;
comp->stmt = $3;
$$ = comp;
}
| '{' DeclList '}' {
struct COMPOUNDSTMT *comp = (struct COMPOUNDSTMT*) malloc (sizeof (struct COMPOUNDSTMT));
comp->decl = $2;
comp->stmt = NULL;
$$ = comp;
}
;
StmtList: Stmt {
struct STMT *stmt;
stmt = $1;
stmt->prev = NULL;
$$ = stmt;
}
| StmtList Stmt {
struct STMT *stmt;
stmt = $2;
stmt->prev = $1;
$$ = stmt;
}
;
Stmt: AssignStmt {
struct STMT *stmt = (struct STMT*) malloc (sizeof (struct STMT));
stmt->s = eAssign;
stmt->stmt.assign_ = $1;
$$ = stmt;
}
| CallStmt {
struct STMT *stmt = (struct STMT*) malloc (sizeof (struct STMT));
stmt->s = eCall;
stmt->stmt.call_ = $1;
$$ = stmt;
}
| RetStmt {
struct STMT *stmt = (struct STMT*) malloc (sizeof (struct STMT));
stmt->s = eRet;
stmt->stmt.return_ = $1;
$$ = stmt;
}
| While_s {
struct STMT *stmt = (struct STMT*) malloc (sizeof (struct STMT));
stmt->s = eWhile;
stmt->stmt.while_ = $1;
$$ = stmt;
}
| For_s {
struct STMT *stmt = (struct STMT*) malloc (sizeof (struct STMT));
stmt->s = eFor;
stmt->stmt.for_ = $1;
$$ = stmt;
}
| If_s {
struct STMT *stmt = (struct STMT*) malloc (sizeof (struct STMT));
stmt->s = eIf;
stmt->stmt.if_ = $1;
$$ = stmt;
}
| CompoundStmt {
struct STMT *stmt = (struct STMT*) malloc (sizeof (struct STMT));
stmt->s = eCompound;
stmt->stmt.cstmt_ = $1;
$$ = stmt;
}
| ';' {
struct STMT *stmt = (struct STMT*) malloc (sizeof (struct STMT));
stmt->s = eSemi;
$$ = stmt;
}
;
AssignStmt: Assign ';' {
$$ = $1;
}
;
Assign: ID '=' Expr {
struct ASSIGN *assign = (struct ASSIGN*) malloc (sizeof (struct ASSIGN));
assign->ID = $1;
assign->index = NULL; //NUL, if LHS is scalar variable
assign->expr = $3;
$$ = assign;
}
| ID '[' Expr ']' '=' Expr {
struct ASSIGN *assign = (struct ASSIGN*) malloc (sizeof (struct ASSIGN));
assign->ID = $1;
assign->index = $3;
assign->expr = $6;
$$ = assign;
}
;
CallStmt: Call ';' {
$$ = $1;
}
;
/*
ArgList의 정의에서 empty가 되지 않도록
Call의 정의에서 ArgList가 빠진 형태를 추가하였다.
*/
Call: ID '(' ')' {
struct CALL *call = (struct CALL*) malloc (sizeof (struct CALL));
call->ID = $1;
call->arg = NULL;
$$ = call;
}
| ID '(' ArgList ')' {
struct CALL *call = (struct CALL*) malloc (sizeof (struct CALL));
call->ID = $1;
call->arg = $3;
$$ = call;
}
;
ArgList: Arg { $$ = $1;}
| ArgList ',' Arg {
struct ARG *arg;
arg = $3;
arg->prev = $1;
$$ = arg;
}
;
Arg: Expr {
struct ARG *arg = (struct ARG*) malloc (sizeof (struct ARG));
arg->expr = $1;
arg->prev = NULL;
$$ = arg;
}
;
RetStmt: RETURN ';' {
$$ = NULL;
}
| RETURN Expr ';' {
$$ = $2;
}
;
Expr: MINUS Expr {
struct UNOP *unop = (struct UNOP*) malloc (sizeof (struct UNOP));
unop->u = eNegative;
unop->expr = $2;
struct EXPR *expr = (struct EXPR*) malloc (sizeof (struct EXPR));
expr->e = eUnop;
expr->expression.unop_ = unop;
$$ = expr;
}
| MathRel Eqltop Expr {
struct EQLTOP *eqltop;
eqltop = $2;
eqltop->lhs=$1;
eqltop->rhs=$3;
struct EXPR *expr = (struct EXPR*) malloc (sizeof (struct EXPR));
expr->e = eEqlt;
expr->expression.eqltop_ = eqltop;
$$ = expr;
}
| MathRel {
struct EXPR *expr = (struct EXPR*) malloc (sizeof (struct EXPR));
expr->e = eMathRel;
expr->expression.mathrel_ = $1;
$$ = expr;
}
| Call {
struct EXPR *expr = (struct EXPR*) malloc (sizeof (struct EXPR));
expr->e = eCallExpr;
expr->expression.call_ = $1;
$$ = expr;
}
| Id_s {
struct EXPR *expr = (struct EXPR*) malloc (sizeof (struct EXPR));
expr->e = eId;
expr->expression.ID_ = $1;
$$ = expr;
}
;
MathRel: MathEql Relaop MathRel {
struct RELAOP *relaop;
relaop = $2;
relaop->lhs=$1;
relaop->rhs=$3;
struct MATHREL *math = (struct MATHREL*) malloc (sizeof (struct MATHREL));
math->r = eRela;
math->math_rel.relaop_ = relaop;
$$ = math;
}
| MathEql {
struct MATHREL *math = (struct MATHREL*) malloc (sizeof (struct MATHREL));
math->r = eMathEql;
math->math_rel.MathEql_ = $1;
$$ = math;
}
;
MathEql: TERM Addiop MathEql {
struct ADDIOP *addiop;
addiop = $2;
addiop->lhs=$1;
addiop->rhs=$3;
struct MATHEQL *math = (struct MATHEQL*) malloc (sizeof (struct MATHEQL));
math->e = eAddi;
math->math_eql.addiop_ = addiop;
$$ = math;
}
| TERM {
struct MATHEQL *math = (struct MATHEQL*) malloc (sizeof (struct MATHEQL));
math->e = eTerm;
math->math_eql.term_ = $1;
$$ = math;
}
;
TERM: FACTOR Multop TERM {
struct MULTOP *multop;
multop = $2;
multop->lhs=$1;
multop->rhs=$3;
struct TERM *term = (struct TERM*) malloc (sizeof (struct TERM));
term->t = eMulti; // eMult와 다름
term->ter.multop_ = multop;
$$ = term;
}
| FACTOR {
struct TERM *term = (struct TERM*) malloc (sizeof (struct TERM));
term->t = eFactor;
term->ter.Facop_ = $1;
$$ = term;
}
;
FACTOR: '(' Expr ')' {
struct FACTOR *factor = (struct FACTOR*) malloc (sizeof (struct FACTOR));
factor->f = eExpre;
factor->fac.bracket = $2;
}
| FLOATNUM {
struct FACTOR *factor = (struct FACTOR*) malloc (sizeof (struct FACTOR));
factor->f = eFloatnum;
factor->fac.floatnum = $1;
$$ = factor;
}
| INTNUM {
struct FACTOR *factor = (struct FACTOR*) malloc (sizeof (struct FACTOR));
factor->f = eIntnum;
factor->fac.intnum = $1;
$$ = factor;
}
;
Id_s: ID {
struct ID_S *id_s = (struct ID_S*)malloc(sizeof (struct ID_S));
id_s->ID = $1;
id_s->expr = NULL;
$$ = id_s;
}
| ID '[' Expr ']' {
struct ID_S *id_s = (struct ID_S*)malloc(sizeof (struct ID_S));
id_s->ID = $1;
id_s->expr = $3;
$$ = id_s;
}
;
Addiop: MINUS {
struct ADDIOP *addiop = (struct ADDIOP*) malloc (sizeof (struct ADDIOP));
addiop->a = eMinus;
$$ = addiop;
}
| PLUS {
struct ADDIOP *addiop = (struct ADDIOP*) malloc (sizeof (struct ADDIOP));
addiop->a = ePlus;
$$ = addiop;
}
;
Multop: MULT {
struct MULTOP *multop = (struct MULTOP*) malloc (sizeof (struct MULTOP));
multop->m = eMult;
$$ = multop;
}
| DIV {
struct MULTOP *multop = (struct MULTOP*) malloc (sizeof (struct MULTOP));
multop->m = eDiv;
$$ = multop;
}
;
Relaop: LE {
struct RELAOP *relaop = (struct RELAOP*) malloc (sizeof (struct RELAOP));
relaop->r = eLE;
$$ = relaop;
}
| GE {
struct RELAOP *relaop = (struct RELAOP*) malloc (sizeof (struct RELAOP));
relaop->r = eGE;
$$ = relaop;
}
| GT {
struct RELAOP *relaop = (struct RELAOP*) malloc (sizeof (struct RELAOP));
relaop->r = eGT;
$$ = relaop;
}
| LT {
struct RELAOP *relaop = (struct RELAOP*) malloc (sizeof (struct RELAOP));
relaop->r = eLT;
$$ = relaop;
}
;
Eqltop: EQ {
struct EQLTOP *eqltop = (struct EQLTOP*) malloc (sizeof (struct EQLTOP));
eqltop->e = eEQ;
$$ = eqltop;
}
| NE {
struct EQLTOP *eqltop = (struct EQLTOP*) malloc (sizeof (struct EQLTOP));
eqltop->e = eNE;
$$ = eqltop;
}
;
While_s: WHILE '(' Expr ')' Stmt {
struct WHILE_S* while_s = (struct WHILE_S*) malloc (sizeof(struct WHILE_S));
while_s->do_while = false;
while_s->cond = $3;
while_s->stmt = $5;
$$ = while_s;
}
| DO Stmt WHILE '(' Expr ')' ';' {
struct WHILE_S* while_s = (struct WHILE_S*) malloc (sizeof(struct WHILE_S));
while_s->do_while = true;
while_s->cond = $5;
while_s->stmt = $2;
$$ = while_s;
}
;
For_s: FOR '(' Assign ';' Expr ';' Assign ')' Stmt {
struct FOR_S *for_s = (struct FOR_S*) malloc (sizeof(struct FOR_S));
for_s->init = $3;
for_s->cond = $5;
for_s->inc = $7;
for_s->stmt = $9;
$$ = for_s;
}
;
If_s: IF '(' Expr ')' Stmt %prec then{
struct IF_S *if_s = (struct IF_S*) malloc (sizeof(struct IF_S));
if_s->cond=$3;
if_s->if_=$5;
if_s->else_=NULL;
$$ = if_s;
}
| IF '(' Expr ')' Stmt ELSE Stmt {
struct IF_S *if_s = (struct IF_S*) malloc (sizeof(struct IF_S));
if_s->cond=$3;
if_s->if_=$5;
if_s->else_=$7;
$$ = if_s;
}
;
%%
void doProcess();
int main(int argc, char* argv[]) {
//헤드 초기화, 만일 토큰이 없다면 dfs(), bfs() 를 작동하지 않게 함.
head = NULL;
scopeHead = NULL;
scopeTail = NULL;
//print AST
fp = fopen("tree.txt","w");
fp2 = fopen("table.txt","w");
if(!yyparse())
doProcess();
fprintf(fp, "\n");
pclose(fp);
pclose(fp2);
return 0;
}
void doProcess() {
//TODO
if(head == NULL)
exit(1);
//make global node
scopeHead = newScope(sGLOBAL, NULL);
scopeTail = scopeHead;
if(head->decl != NULL)
visitDeclaration(head->decl);
if(head->func != NULL)
visitFunction(head->func);
BuildTree(head);
}
miniC.l
%{
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "AST.h"
#include "miniC.tab.h"
%}
intnum [0-9]+
floatnum [0-9]+.[0-9]+
id [A-Za-z][A-Za-z0-9_]*
space [ \t\r\n]
%%
int return INT;
float return FLOAT;
if return IF;
else return ELSE;
for return FOR;
while return WHILE;
do return DO;
return return RETURN;
"[" |
"]" |
"{" |
"}" |
"(" |
")" |
";" |
"." |
"," |
"=" {return yytext[0];} //character 자체로 token
"\"" {return DQUOT_T;}
"\'" {return SQUOT_T;}
"\&" {return AMP_T;}
"-" return MINUS;
"+" return PLUS;
"*" return MULT;
"/" return DIV;
"<=" return LE;
">=" return GE;
">" return GT;
"<" return LT;
"==" return EQ;
"!=" return NE;
{intnum} {
yylval.intnum = atoi(yytext);
return INTNUM;
}
{floatnum} {
yylval.floatnum = atof(yytext);
return FLOATNUM;
}
{id} {
yylval.id = strndup(yytext, yyleng);
return ID;
}
{space} { break;}
%%
AST.h
#ifndef AST_H
#define AST_H
#define bool char
#define true 1
#define false 0
typedef enum
{eInt,eFloat} Type_e;
typedef enum
{eNegative} Unop_e;
typedef enum
{eAssign,eCall,eRet,eWhile,eFor,eIf,eCompound,eSemi} Stmt_e;
typedef enum
{eUnop,eEqlt,eCallExpr,eId,eMathRel} Expr_e;
typedef enum
{eRela,eMathEql} MathRel_r;
typedef enum
{eAddi,eTerm} MathEql_e;
typedef enum
{eCom,eInc} Cond_c;
typedef enum
{eStmt,eIncom,eComp} Sta_s;
typedef enum
{eFactor,eMulti} Term_t;
typedef enum
{eIntnum,eFloatnum,eExpre} Factor_f;
typedef enum
{ePlus,eMinus} Addi_e;
typedef enum
{eMult,eDiv} Mult_e;
typedef enum
{eLT,eGT,eLE,eGE} Rela_e;
typedef enum
{eEQ,eNE} Eqlt_e;
struct PROGRAM
{
struct DECLARATION *decl;
struct FUNCTION *func;
};
struct DECLARATION
{
Type_e t;
struct IDENTIFIER *id;
struct DECLARATION *prev;
};
struct IDENTIFIER
{
char *ID;
int intnum; // zero , if scalar
struct IDENTIFIER *prev;
};
struct FUNCTION // *prev type id (parameter) {}
{
Type_e t;
char *ID;
struct PARAMETER *param;
struct COMPOUNDSTMT *cstmt;
struct FUNCTION *prev;
};
struct PARAMETER
{
Type_e t;
struct IDENTIFIER *id;
struct PARAMETER *prev;
};
struct COMPOUNDSTMT // {}
{
struct DECLARATION *decl;
struct STMT *stmt;
};
/*
break,semi stmt union stmt -> no value;
*/
struct STMT
{
Stmt_e s;
union {
struct ASSIGN *assign_; // id=expr;
struct CALL *call_; // id(arg)
struct EXPR *return_; // return expr
struct WHILE_S *while_; // while()stmt | do_while() stmt
struct FOR_S *for_; // for()stmt
struct IF_S *if_; // if()stmt
struct COMPOUNDSTMT *cstmt_; // {}
} stmt;
struct STMT *prev;
};
/* id[index]=expr; */
struct ASSIGN
{
char *ID;
struct EXPR *index; // Null, if LHS is scalar variable
struct EXPR *expr; // RHS
};
/* id(arglist?); */
struct CALL
{
char *ID;
struct ARG *arg;
};
/* (expr,expr*) */
struct ARG
{
struct EXPR *expr;
struct ARG *prev;
};
/* while(cond)stmt; | do stmt while (cond) */
struct WHILE_S
{
bool do_while;
struct EXPR *cond;
struct STMT *stmt;
};
/* for(init;cond;inc)stmt; */
struct FOR_S
{
struct ASSIGN *init;
struct EXPR *cond;
struct ASSIGN *inc;
struct STMT *stmt;
};
/* if(cond)if_s else else_s */
struct IF_S
{
struct EXPR *cond;
struct STMT *if_;
struct STMT *else_; // NUll, if 'else' not exist
};
struct EXPR
{
Expr_e e; // EXPR type (enumeration type)
union
{
struct UNOP *unop_; // -expr
struct MATHREL *mathrel_;
struct ADDIOP *addiop_; // epxr + expr
struct EXPR *bracket;
struct EQLTOP *eqltop_;
struct CALL *call_; // call
struct ID_S *ID_; // id[expr]
} expression;
};
struct MATHREL
{
MathRel_r r;
union
{
struct RELAOP *relaop_; // expr >= expr
struct MATHEQL *MathEql_; // expr >= expr
} math_rel;
};
struct MATHEQL
{
MathEql_e e;
union
{
struct ADDIOP *addiop_; // expr == expr
struct TERM *term_;
} math_eql;
};
struct TERM
{
Term_t t;
union
{
struct MULTOP *multop_;
struct FACTOR *Facop_;
} ter;
};
struct FACTOR
{
Factor_f f;
union
{
int intnum; // int
float floatnum; // float
struct EXPR *bracket;
} fac;
};
struct UNOP
{
Unop_e u;
struct EXPR *expr;
};
/* lhs addiop rhs */
struct ADDIOP
{
Addi_e a;
struct TERM *lhs;
struct MATHEQL *rhs;
};
/* lhs multiop rhs */
struct MULTOP
{
Mult_e m;
struct FACTOR *lhs;
struct TERM *rhs;
};
/* lhs relaop rhs */
struct RELAOP
{
Rela_e r;
struct MATHEQL *lhs;
struct MATHREL *rhs;
};
/* lhs eqltop rhs */
struct EQLTOP
{
Eqlt_e e;
struct MATHREL *lhs;
struct EXPR *rhs;
};
/* id[expr] */
struct ID_S
{
char *ID;
struct EXPR *expr; // NULL , if scalar variable
};
#endif
input.txt
int main ()
{
int result;
result = 0;
if (result > 0)
{
result = 1;
} else {
result = 2;
result = 32;
}
return result;
}
错误:
syntax error, unexpected GT, expecting ')'
如何运行:
./miniC <input.txt
更多信息here
它应该按照Grammar for parsing simple mathematical expression
运行但是仍然存在这些问题,您能帮我吗?