将 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 中 getcharstdin 读取。如果您想使用不同的 FILE *,请改用 getc。因此,检查上面的 yylex 代码并将 getchar() 替换为 getc(yyin)(或任何 FILE * 的名称),并替换所有其他对 [=11= 的引用] 与 yyin。同样,scanfstdin 读取,而 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 可以是(也可以不是)输入中的一个标记,当您决定切换缓冲区时,必须将某些状态推回。