将yyin指向mfcalc示例中的FILE *

时间:2016-10-27 21:11:35

标签: c bison

编辑:接受以下解决方案。

我正在研究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;
}

3 个答案:

答案 0 :(得分:3)

这与野牛无关。

在C getchar中读取stdin。如果您想使用其他FILE *,请改用getc。请仔细阅读上面的yylex代码,将getchar()替换为getc(yyin)(或FILE *的名称),并替换所有其他对{{1}的引用与stdin。同样,yyinscanf读取,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可以是(或不是)输入中的一个标记,并且某些状态必须被推回。