野牛意外令牌导致语法错误

时间:2018-10-23 00:15:56

标签: compiler-construction syntax-error bison flex-lexer unexpected-token

该编译器来自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

运行

但是仍然存在这些问题,您能帮我吗?

0 个答案:

没有答案