将 yyin 指向 mfcalc 示例中的 FILE*
pointing yyin to a FILE* inside of mfcalc example
编辑:接受以下解决方案。
我在这里处理 Bison mfcalc 示例:
https://www.gnu.org/software/bison/manual/bison.html#Mfcalc-Main
我希望能够从文件而不是标准输入中读取。我有他们的示例 运行,但是因为他们已经重新定义了 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] = '[=10=]';
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;
}
鉴于我现在看到的代码,如何将 getchar() 更改为从指定的 FILE* 中读取,即 fgetc。然后将 FILE*(不幸的是全局)设置为 stdout 或 fopen() 调用的结果。
显然也更改 ungetc 以使用该文件*。
if (condition){
globalFilePointer = fopen("something.txt","r");
} else {
globalFilePointer = stdin;
}
这与野牛无关
在 C 中 getchar
从 stdin
读取。如果您想使用不同的 FILE *
,请改用 getc
。因此,检查上面的 yylex 代码并将 getchar()
替换为 getc(yyin)
(或任何 FILE *
的名称),并替换所有其他对 [=11= 的引用] 与 yyin
。同样,scanf
从 stdin
读取,而 fscanf
从不同的 FILE *
读取
问题与Bison无关。 Bison 是一个解析器生成器,通常与 flex(1)
一起使用,以提供用于获取标记的输入例程。对于输入委托,它使用一个通常名为 yylex()
的例程来提供 下一个标记 ,而这个例程在由您提供时必须处理实际输入(您如果您使用 getchar(3)
、fgetc(3)
或仅从 read(2)
).
读取输入,则可以自由 select
如果您从 flex(2)
处理的扫描仪描述中提供 yylex()
,则必须阅读 flex(1)
的 texinfo 文档以了解如何正确地将输入切换到另一个文件,因为 flex(1)
不为此目的使用 getchar(3)
,并且在内部缓冲尽可能多的输入以允许无限制的回推。实际上,在扫描过程中改变输入(例如,解决include file
问题)是一个问题(flex提供了几个宏来帮助您切换缓冲区) ,因为 flex 可以是(也可以不是)输入中的一个标记,当您决定切换缓冲区时,必须将某些状态推回。
编辑:接受以下解决方案。
我在这里处理 Bison mfcalc 示例: https://www.gnu.org/software/bison/manual/bison.html#Mfcalc-Main
我希望能够从文件而不是标准输入中读取。我有他们的示例 运行,但是因为他们已经重新定义了 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] = '[=10=]';
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;
}
鉴于我现在看到的代码,如何将 getchar() 更改为从指定的 FILE* 中读取,即 fgetc。然后将 FILE*(不幸的是全局)设置为 stdout 或 fopen() 调用的结果。
显然也更改 ungetc 以使用该文件*。
if (condition){
globalFilePointer = fopen("something.txt","r");
} else {
globalFilePointer = stdin;
}
这与野牛无关
在 C 中 getchar
从 stdin
读取。如果您想使用不同的 FILE *
,请改用 getc
。因此,检查上面的 yylex 代码并将 getchar()
替换为 getc(yyin)
(或任何 FILE *
的名称),并替换所有其他对 [=11= 的引用] 与 yyin
。同样,scanf
从 stdin
读取,而 fscanf
从不同的 FILE *
问题与Bison无关。 Bison 是一个解析器生成器,通常与 flex(1)
一起使用,以提供用于获取标记的输入例程。对于输入委托,它使用一个通常名为 yylex()
的例程来提供 下一个标记 ,而这个例程在由您提供时必须处理实际输入(您如果您使用 getchar(3)
、fgetc(3)
或仅从 read(2)
).
如果您从 flex(2)
处理的扫描仪描述中提供 yylex()
,则必须阅读 flex(1)
的 texinfo 文档以了解如何正确地将输入切换到另一个文件,因为 flex(1)
不为此目的使用 getchar(3)
,并且在内部缓冲尽可能多的输入以允许无限制的回推。实际上,在扫描过程中改变输入(例如,解决include file
问题)是一个问题(flex提供了几个宏来帮助您切换缓冲区) ,因为 flex 可以是(也可以不是)输入中的一个标记,当您决定切换缓冲区时,必须将某些状态推回。