我在打印一系列递归行为的令牌时遇到困难。为了更好地解释,我将展示相应代码的部分:首先,Lex上的代码:
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define YYSTYPE char*
int yylex(void);
void yyerror(char *);
extern FILE *yyin, *yyout;
extern char* yytext;
%}
%token ABREPARENTESE FECHAPARENTESE PONTOEVIRGULA VIRGULA ID PORREAL PORTEXTO PORINTEIRO LEIA
%%
programs : programs program
| program
| ABREPARENTESE {fprintf(yyout,"%s",yytext);}
| FECHAPARENTESE {fprintf(yyout,"%s",yytext);}
;
program:
leia
;
leia:
LEIA ABREPARENTESE entradas ids FECHAPARENTESE PONTOEVIRGULA
{
fprintf(yyout,"scanf(\"%s\",%s);",$3,$4);
}
;
entradas:
tipo_entrada VIRGULA entradas {fprintf(yyout,"%s,",$1);}
| tipo_entrada VIRGULA {fprintf(yyout,"%s", $1); }
;
tipo_entrada:
| PORREAL {$$ = "%f";}
| PORTEXTO {$$ = "%c";}
| PORINTEIRO {$$ = "%d";}
;
ids:
id VIRGULA ids {fprintf(yyout,"&%s,",$1);}
| id {fprintf(yyout,"&%s",$1);}
;
id:
ID {$$ = strdup(yytext);}
;
%%
void yyerror(char *s) {
fprintf(stderr, "%s\n", s);
}
int main(int argc, char *argv[]){
yyout = fopen(argv[2],"w");
yyin = fopen(argv[1], "r");
yyparse();
return 0;
}
现在,Yacc上的代码:
leia: LEIA ABREPARENTESE entradas ids FECHAPARENTESE PONTOEVIRGULA
{
fprintf(yyout,"scanf(\"%s\",%s);",$3,$4);
}
;
我相信我已经在代码中复制了我的问题的所有相关部分(有些事情我可能忘记复制和粘贴),但是我的问题是这部分代码:
leia (%real, %inteiro, id1, id2);
在输入文件中,我有以下一行:
scanf("%f,%d",&id1,&id2);
期望是输出文件:
%d%f,&id2&id1,scanf("%f",id1);
但实际上这是输出文件中的结果:
Sheet1.Cells.Clear
Dim i As Integer
Dim rng as Range
Set rng = Range("A1:E8")
For i = 1 To 40
rng
Next
你可以帮我解决这个问题吗?如何在正确的位置打印令牌?
答案 0 :(得分:0)
通常情况下,使用自下而上的解析,我们使用左递归制作,结果是制作从左到右缩小。
当你使用正确的递归时,生产会堆积到最后,然后从堆栈中弹出,因此从右到左执行缩减。
因此,例如,更常见的是写:
ids: id
| ids ',' id
然后语义规则将按预期顺序执行。