YACC LEX IF和ELSE计算器

s8vozzvw  于 2023-01-20  发布在  其他
关注(0)|答案(1)|浏览(147)

我有一个关于这个代码的问题,我想在YACC和LEX中创建一个IF / ELSE。但是我很难检测到条件并执行正确的块(因为它依赖于条件!)
我必须做一个计算器,考虑到IF和ELSE我已经添加了TOKEN。expr允许计算表达式stmtstmtlist允许嵌套。

%%
//  US : liste de ... (commande, assignation, expression)
liste : 
    | liste error RC    { yyerrok; yyclearin; code (STOP); return 1;}
    | liste stmtList RC { printf("stmtList\n"); code((instr_t)printExprCode); code (STOP); return 3;}
    | liste cmd   RC    { code (STOP); return 6;}
    ;
//  US : Commande
cmd : 
      opCmd             { code ((instr_t)*($1->U.pFct));}
    | DBG sym           { dbgSymbol($2); }
    ;

// US : Expression algébrique
expr :  ENTIER          { code2((instr_t)intPush, (instr_t)$1);  }
    | REEL              { code2((instr_t)floPush, (instr_t)$1);}
    | IVAR              { code3((instr_t)varPush, (instr_t)$1, (instr_t)varEval);}
    | FVAR              { code3((instr_t)varPush, (instr_t)$1, (instr_t)varEval);}
    | UNDEF
    | PO expr PF        { printf("test&\n, $$=%f"); $$=$2; }
    | expr opAlg expr   { code ((instr_t)*($2->U.pFct)); }
    | SUB expr          { code((instr_t)negate); } %prec UNARY_MINUS
    | PREDEF PO expr PF { code2((instr_t)predef, (instr_t)$1); }
    | PO ENTIER LT ENTIER PF    { code3((instr_t)intPush, (instr_t)$1, (instr_t)intPush);}
    | expr opCOMP expr  { code ((instr_t)*($2->U.pFct)); }
    
    ;
assgn :
      IVAR AFF expr     { code3((instr_t)varPush, (instr_t)$1, (instr_t)varAssign); }
    | FVAR  AFF expr    { code3((instr_t)varPush, (instr_t)$1, (instr_t)varAssign); }
    | UNDEF AFF expr    { code3((instr_t)varPush, (instr_t)$1, (instr_t)varAssign); }
    ;

//  US : Statement
cond :  PO expr PF { printf("Condition");} ;

//cond :    PO ENTIER LT ENTIER PF { printf("ok"); if($1<$3){$$=1;}else{$$=0;}};

stmt : expr 
    | assgn
    | IF expr stmt {$$ = code(IF,)}
    ;   

//  US : Statement List
stmtList :              {data_t d; d.value = 0; push(d);}
    | stmt
    | stmtList DEL stmtList
    | AO stmtList AF
    ;

//  US : Statement List
block :
     AO stmtList AF         
    ;

// US : sym, nbr, var, opAlg, opCmc
sym : nbr | var | PREDEF | opAlg | opCmd | opCOMP
    ;
nbr : ENTIER | REEL
    ;
var : UNDEF |  IVAR | FVAR 
    ;
opAlg : ADD | SUB | MUL | DIV  
    ;
opCmd : PR_TS | PR_TS2 | DBG_TS | DBG_TS2
    ;
opCOMP : LT | GT | EQ | NE
    ;
%%
vmdwslir

vmdwslir1#

一般来说,为此,您需要在规则的中间插入一个“嵌入式”操作。

stmt: IF expr {
          // generate code to branch to a label if the preceeding expression was false
      } stmtList {
          // generate the label that is branched to
      }

通过在第一个操作中将$$设置为某个值,然后在第二个操作中使用该值(如$3),可以在这两个片段之间进行通信。最后一个操作需要为规则的最终结果设置$$
对于IF/ELSE,需要更复杂的东西,它有两个标签(一个在末尾,一个在ELSE后面)和两个分支(条件分支与简单的if一样,条件分支与else标签相同,无条件分支与else标签前面的end标签相同)

相关问题