编辑:接受以下解决方案。
我正在研究Bison mfcalc示例: https://www.gnu.org/software/bison/manual/bison.html#Mfcalc-Main
我希望能够从文件中读取,而不是stdin。我已经启动并运行了它们的示例,但是因为它们已经重新定义了yylex(),所以让解析器从文件中读取并不像通常那样简单。
任何能提供帮助的人都将不胜感激!
PS。这样的事情:http://beej.us/guide/bgc/output/html/multipage/getc.html 但我对C不太好。我会在此期间尝试实现这一点。
所以你需要修改它:
int
yylex (void)
{
int c;
/* Ignore white space, get first nonwhite character. */
while ((c = getchar ()) == ' ' || c == '\t')
continue;
if (c == EOF)
return 0;
/* Char starts a number => parse the number. */
if (c == '.' || isdigit (c))
{
ungetc (c, stdin);
scanf ("%d", &yylval.NUM);
return NUM;
}
/* Char starts an identifier => read the name. */
if (isalpha (c))
{
/* Initially make the buffer long enough
for a 40-character symbol name. */
static size_t length = 40;
static char *symbuf = 0;
symrec *s;
int i;
if (!symbuf)
symbuf = (char *) malloc (length + 1);
i = 0;
do
{
/* If buffer is full, make it bigger. */
if (i == length)
{
length *= 2;
symbuf = (char *) realloc (symbuf, length + 1);
}
/* Add this character to the buffer. */
symbuf[i++] = c;
/* Get another character. */
c = getchar ();
}
while (isalnum (c));
ungetc (c, stdin);
symbuf[i] = '\0';
s = getsym (symbuf);
if (s == 0)
s = putsym (symbuf, VAR);
*((symrec**) &yylval) = s;
return s->type;
}
/* Any other character is a token by itself. */
return c;
}
答案 0 :(得分:3)
这与野牛无关。
在C getchar
中读取stdin
。如果您想使用其他FILE *
,请改用getc
。请仔细阅读上面的yylex代码,将getchar()
替换为getc(yyin)
(或FILE *
的名称),并替换所有其他对{{1}的引用与stdin
。同样,yyin
从scanf
读取,stdin
从不同的fscanf
读取
答案 1 :(得分:0)
鉴于我现在看到的代码,如何更改getchar()以从指定的FILE *(即fgetc)读取。然后将FILE *(不幸的是全局)设置为stdout或fopen()调用的结果。
显然也要改变ungetc来使用那个FILE *。
if (condition){
globalFilePointer = fopen("something.txt","r");
} else {
globalFilePointer = stdin;
}
答案 2 :(得分:0)
这个问题与Bison无关。 Bison是一个解析器生成器,通常与flex(1)
一起使用,以提供用于获取令牌的输入例程。对于输入委托,它使用一个通常名为yylex()
的例程,提供下一个令牌,这个例程,当你提供时,必须处理实际输入(你可以自由地选择是否使用getchar(3)
,fgetc(3)
或仅使用read(2)
来阅读输入内容。
如果您从yylex()
处理的扫描程序说明中提供flex(2)
,则必须阅读flex(1)
的texinfo文档,以了解如何正确地将输入切换到另一个文件,因为flex(1)
没有为此目的使用getchar(3)
,并在内部缓冲必要的输入以允许无限制的回退。实际上,它是一个问题(并且 flex提供了几个宏来帮助您切换缓冲区)以在扫描过程中更改输入(例如,解决include file
问题)因为当你决定切换缓冲区时,flex可以是(或不是)输入中的一个标记,并且某些状态必须被推回。