Я создавал парсер для очень простого парсера, когда внезапно начал получать SEGFAULT.Я сократил свой код до минимума, где он идет не так:
Это мой файл test.flex:
%{
#include "test.tab.h"
#include <iostream>
using namespace std;
%}
%option noyywrap
%%
model { yylval.a = new double(); return IDENTIFIER; }
. { cerr << "Unrecognized token!" << endl; exit(1); }
%%
Это мой файл test.y:
%{
#include <iostream>
using namespace std;
int yylex();
int yyerror(const char *p) { cerr << "Error" << endl; }
%}
%union YYSTYPE {
double* a;
int* b;
};
%token <a> IDENTIFIER
%type <b> expression
%%
expression : IDENTIFIER { cout << "got here! " << $1 << "|" << $$ << endl; };
%%
int main()
{
yyparse();
cout << "Success!" << endl;
return 0;
}
Наш союз состоит из двух указателей, a и b.$ 1 и $$ имеют разные типы (a и b соответственно).
При вводе «model» вывод «получен здесь! 0x372a28 | 0x372a28» (и «Success!» Во второй строке),это означает, что $ 1 и $$ указывают на одно и то же место в памяти!Это, конечно, приводит к возникновению всевозможных плохих вещей.
Назначение yylval.a в лексере необходимо для проявления ошибки.
Я использую Bison 2.4.1 и Flex 2.5.4, оба для Windows (используя GnuWin32).Я делаю что-то неправильно?Это (известная) ошибка?
РЕДАКТИРОВАТЬ: Если я изменяю объединение на:
%union YYSTYPE {
int a;
int b;
};
и правило на
expression : IDENTIFIER { cout << "got here! " << &$1 << "|" << &$$ << endl; };
(и удаляем назначениев лексере) результирующие области памяти, описанные , различаются , что позволяет мне полагать, что области памяти самих переменных различны, если не используются указатели.Однако, если бы это было так, если я использую указатели, присваивание "yylval.a = new double ();"следует только изменить $ 1 и оставить $ $ нетронутым.