Множественное определение `main 'при компиляции выходного файла бизона - PullRequest
0 голосов
/ 07 июня 2019

Итак, я пишу синтаксический анализатор бизонов (без lex), и теперь я хочу прочитать входной код из файла и записать вывод в другой файл.

В течение некоторого времени поиска в стеке я обнаружил, что этот путь должен быть хорошим.bison.y:

%{
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    extern FILE *yyin;

    int yylex() { return getc(stdin); }
    void yyerror(char *s) {
      fprintf (stderr, "%s\n", s);
    }
    int counter = 1;
    char filename2[10] = "dest.ll";
    FILE *f2;
%}
%name parse

%%

//grammars

%%

int main(int argc, char *argv[]) {
    yyin = fopen(argv[1], "r");
    if (argc > 2)
      f2 = fopen(argv[2], "w");
    else
      f2 = fopen(filename2, "w");
    yyparse();

    return 0;
} 

Затем я скомпилирую его так:

bison bison.y
cc -ly bison.tab.c

И вот результат компиляции cc:

/tmp/ccNqiuhW.o: In function `main':
bison.tab.c:(.text+0x960): multiple definition of `main'
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/liby.a(main.o):(.text.startup+0x0): first defined here
/tmp/ccNqiuhW.o: In function `main':
bison.tab.c:(.text+0x98c): undefined reference to `yyin'
collect2: error: ld returned 1 exit status

Выходной бизонФайл .tab.c имеет только 1 основной.Ofc int / void main не имеет значения.Можете ли вы научить меня, как это правильно делать?

PS Кстати, я не хочу спамить разные посты, и у меня есть небольшой вопрос здесь.Как я могу сохранить строку (char *) в $$ в зубрах?Например, я хочу создать строку кода после того, как встретил грамматику int.У меня есть эта ошибка, и я не могу найти ответ:

bison.y:94:8: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
 INTNUM: NUMBER | DIGIT INTNUM {$$ = "string"};

bison.y: In function ‘yyparse’:
bison.y:28:15: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Wformat=]
 PROGRAM: EXPRS { fprintf(f2, "%s: string here %d.\n", $$, counter++) };

будет очень хорошо, если я найду помощь.

1 Ответ

2 голосов
/ 07 июня 2019

Вы связываете библиотеку liby (опция компоновщика -ly). В руководстве Bison есть следующее:

Библиотека Yacc содержит стандартные реализации функций yyerror и main.

Так вот почему у вас есть несколько определений main.Вы предоставляете один, и есть один в liby.

Более того, в документах говорится, что

Эти реализации по умолчанию обычно бесполезны , но POSIXтребует их.

(выделение добавлено)

Вам не нужно связывать liby , чтобы создать программу, включающую в себя созданный бизоном синтаксический анализатор, иобычно вы не должны этого делать.Вместо этого предоставьте свои main() и свои yyerror(), которые вы уже сделали.

Кроме того, ожидается, что вы предоставите определение из yyin,не просто декларация, ссылаетесь ли вы на Либи или нет.Для этого удалите ключевое слово extern из объявления yyin в вашем файле грамматики.

Ваша грамматика не завершена (правил вообще нет), а директива %name не задокументированаи не распознается моим Bison, но если я добавлю фиктивное правило и закомментирую %name в сочетании с другими обсужденными изменениями, то bison создаст для меня исходный файл C, который может быть успешно скомпилирован в исполняемый файл(без Либи).

...