Парсер Bison: создание функции, которая возвращает токены

0

в моем flex, я хотел бы иметь возможность сделать что-то вроде этого:

{VARIABLE}          { 
                        yylval.string_val=strdup(yytext); 
                        return getVarType(yytext); //that is the issue
                    }

Мой вопрос: каким должен быть тип возврата функции getVarType? Я хотел бы, чтобы это выглядело примерно так:

X getVarType(const char* v){
     if(case 1...)
       return VAR_INT;
     if(case 2...)
       return VAR_DOUBLE;
    etc....
}

Что должно быть X?

  • 0
    Я полагаю, X - это тип перечисления VAR_INT, VAR_DOUBLE и т. Д.
Теги:
bison
flex-lexer

3 ответа

2
Лучший ответ

yylex возвращает int. Более того, единственный способ вернуть типы токенов, которые будут правильно поняты вашим парсером bison/yacc, состоит в том, чтобы объявить различные VAR_INT, VAR_DOUBLE и т.д. Как %token в вашем файле bison/yacc (и импортировать сгенерированный заголовочный файл, но я полагаю, вы уже это делаете). Сгенерированный заголовочный файл объявит эти переменные как int.

Таким образом, ваша функция getVarType может возвращать любой тип T до тех пор, пока вы можете getVarType int к T а затем вернуть его обратно в int без потери информации, но самым простым было бы вернуть int.


Анализ типа (и, следовательно, управление таблицей символов) в лексере создает зависимость между лексером и синтаксическим анализатором, которого обычно следует избегать, если только вы не получите от него какого-либо значения. В этом конкретном случае трудно понять, какая ценность создается, но это действительно зависит от вас. Обычно легче проводить анализ типов на законченном АСТ, чем пытаться сделать это во время разбора.

В любом случае тот факт, что у вас есть таблица символов вообще, предполагает, что нет необходимости strdup имена переменных; вы можете найти их в таблице символов, а затем вернуть указатель на запись в таблице символов. Это позволит сэкономить много работы, пытаясь отслеживать распределения памяти. (Он все еще создает зависимость между лексером и синтаксическим анализатором, но не настолько жесткой зависимостью. С точки зрения lexer таблица символов может быть доступна только для чтения и представлена как дополнительный аргумент reference/pointer для yylex.)

1

Для чего это стоит, Bison 3.0 автоматически генерирует такие функции для C++. Например, если ваш входной файл содержит что-то вроде:

%token <::std::string> TEXT;
%token <int> NUMBER;
%token END_OF_FILE 0;

он будет генерировать функции, которые вы можете вызвать из сканера следующим образом:

return parser::make_NUMBER (stage, loc);
return parser::make_TEXT ("Text all!", loc);
return parser::make_END_OF_FILE (loc);
0
void *p;
char *s;
void main()
{
void *p=myFun();
if(strcmp(s,"int")==0)
{
 Print("function return int and val: =%d",(*int)*p);
}
//similarly compare for all data types and just type cast to that data types
}

void *myFun()
{
if(case1)
{
 p=address of that data type variable suppose int;
 s="data type";
}

if(case2)
{
 p=&of that data type variable suppose char etc;
 s="data type";
}
return p;
}

Я думаю, что это единственный способ, но есть одна проблема: если функция возвращает ее, уничтожат все локальные переменные, поэтому возвращение локальных переменных не является ошибкой, но значение, возвращаемое функцией, является допустимым или нет, мы не можем сказать. указатель void называется общим указателем, мы можем предоставить любой адрес типа данных этому указателю, но во время получения значения тип литья является обязательным. Надеюсь, так это будет некоторым, как помощь полна для вас спасибо и приветствует asif aftab

Ещё вопросы

Сообщество Overcoder
Наверх
Меню