Определите условия операторов if, используя Bison и Flex в переполнении стека

Я хочу получить все условия оператора if в C ++. Если я поставлю (foo&&bar&&(one&&two))тогда я хочу распечатать foo - bar - one - two,

Я скомпилировал файлы scanner.l и parser.y и проверил индивидуально: my yy.lex.c работает: если я поставлю (a&&b)тогда я получаю 5 жетонов: (, a, &&, b а также ) как я хочу. Но когда я использую файл .y, если я помещаю тот же самый ввод, тогда я получаю a&&b а также b), Обратите внимание, что в этом случае я получаю 2 токена, потому что токен a&&b следует разделить на 3 токена a, && а также b , Я попытался ввести более простое условие: (a) тогда я получаю: ( а также a) но я хочу получить (, a, ),

Я не знаю, делаю ли я что-то не так или это ошибка; Я надеюсь, что это моя вина.

parser.y

%{
#include <iostream>
#include <list>
#include <stdio.h>
#include <sstream>
#include <string>

using namespace std;

int yylex(void);
void yyerror(char *);

list<string> tokenList;

#define YYSTYPE char *
%}

%token  PAR_IZQ
PAR_DER
SIMBOLO
FIN
NADA
AND
OR

%start input

%%

input:

|   input terminos
;

terminos:
PAR_IZQ terminos PAR_DER    { }
|   PAR_IZQ condicion PAR_DER   { }
;

condicion:
terminos AND terminos       { }
|   SIMBOLO AND terminos        { cout << " 1) CONDITION FOUND: " << $1 << endl; }
|   terminos AND SIMBOLO        { cout << " 2) CONDITION FOUND: " << $3 << endl; }
|   SIMBOLO AND SIMBOLO         { cout << " 3) CONDITION FOUND: " << $3 << " AND " << $1 << endl; }
|   SIMBOLO                     { cout << " 4) CONDITION FOUND: " << $1 << endl; }
;

%%

void yyerror(char *s) {
fprintf(stderr, "%s\n", s);
}

int main(void) {
yyparse();
return 0;
}

scanner.l

%option noyywrap
%{
#include <iostream>
#include "parser.tab.c"using namespace std;
%}

%%

[a-zA-Z0-9]+  {
yylval = yytext;
return SIMBOLO;
}

"&&" {
return AND;
}

"||" {
return OR;
}

[ \0\0] {
return FIN;
}

"("     {
yylval = yytext;
return PAR_IZQ;
}

")"     {
yylval = yytext;
return PAR_DER;
}

.       {
cout << "Entrada no permitida.";
cout << endl << yytext << endl;
exit(1);
}

%%

main.cpp

#include "mainwindow.h"#include <QApplication>
#include "lex.yy.c"#include <iostream>
#include <vector>
#include <string>

using namespace std;

typedef yy_buffer_state *YY_BUFFER_STATE;
extern int yyparse();
extern YY_BUFFER_STATE yy_scan_buffer(char *, size_t);

int main(int argc, char** argv) {

char condition[] = "(a) \0\0";
// note yy_scan_buffer is looking for a double null string
yy_scan_buffer(condition, sizeof(condition));
yyparse();
return 0;
}

Обратите внимание, что ввод синтаксического анализатора является строкой, поэтому я должен передать его в качестве параметра yy_scan_buffer функция. \0\0 необходимо, потому что в противном случае программа никогда не закончит свое выполнение. Консоль говорит красным «ошибка синтаксиса», но я не знаю почему!

введите описание изображения здесь

Знаешь ли ты, как я могу это исправить и получить нужные мне токены?

Спасибо!

PS: Я использую Windows 8.1, Qt Creator 2.8.1, win_bison 2.7 и win_flex 2.5.37.

0

Решение

Проблема в том, что ваш лексер возвращается yytext парсеру как yylval ассоциируется с символами, но yytext является указателем на внутренний буфер токенов лексера, который будет действителен только до чтения следующего токена. Поэтому, когда вы позже приступите к распечатке токенов в своем состоянии, вы получите полуслучайный мусор (так как вскоре после этого вы в основном получаете тот же необработанный буфер токенов без завершающих нулевых символов).

Вам нужно сделать копию строки, на которую указывает yytext перед возвратом парсеру:

[a-zA-Z0-9]+  {
yylval = strdup(yytext);
return SIMBOLO;
}

конечно, вам также нужно отслеживать, когда строка больше не нужна, и free Это.

Альтернативно, так как вы не используете %unionпоменяй #define за YYSTYPE в

#define YYSTYPE  std::string
3

Другие решения


По вопросам рекламы [email protected]