Стог зубров

Это лексический анализатор, использующий Flex.

#include <iostream> 
#include <cstdio>

#define YY_DECL extern "C" int yylex()

#include "conv.tab.h"
using namespace std;

%}
eq [ \t]*=
%%

[ \t]           ;
(?:POINT|LINE)  { yylval.ename = strdup(yytext); return ENAME; }
x{eq}           { yylval.xval = atof(yytext);
                    return XVAL; }
y{eq}           { yylval.yval = atof(yytext);
                    return YVAL; }
.               ;
%%

И другой файл - файл грамматики зубров

%{
#include <iostream>
#include <cstdio>
#include <stdio.h>
using namespace std;

extern "C" int yylex ();
extern "C" int yyparse (void);
extern "C" FILE *yyin;
extern int line_no;

void yyerror(const char *s);

%}

%union{
    float xval;
    float yval;
    char *ename;
}

%token <ename> ENAME
%token XVAL
%token YVAL

%%

converter:
    converter ENAME { cout << "entity = " << $2 << endl; }
    | converter XVAL {// x -> xval = $2; 
      cout << "x value = " << endl; }
    | converter YVAL {// y -> yval = $2; 
       cout << "y value = " << endl; }
    | ENAME { cout << "entity = " << $1 << endl; }
    | XVAL { cout << "xvalue " << endl; }
    | YVAL { cout << "yvalue " << endl; }

%%
main() {
    FILE *myfile = fopen("conv.aj", "r");

    if (!myfile) {
            cout << "I can't open file" << endl;
            return -1;
    }

    yyin = myfile;

    do{
            yydebug = 1;
            yyparse();
    } while (!feof(yyin));
    yydebug = 2;
}

void yyerror(const char *s) {
    cout << "Parser error! Message: " << s << endl;
    exit(-1);
}

На самом деле, я хочу получить значения из файла. Я использовал Bison Debugger и узнал, что эти значения не могут быть добавлены в Bison Stack. Поэтому я хочу поместить эти значения в стек. Мой файл выглядит так: POINT x=38 y=47

1 ответ

Ничто в вашем лексическом анализаторе не соответствует числу, поэтому 38 а также 47 из входных данных оба будут обработаны вашим правилом по умолчанию (. ;) что приведет к их игнорированию. В ваших правилах для XVAL а также YVAL, ты звонишь atoi на yytext, которые будут x= (или же y=); это явно не число и atoi вероятно вернется 0,

Мне непонятно, что вы подразумеваете под "этими значениями не в состоянии протолкнуть стек Bison", но я думаю, что эта проблема не имеет ничего общего с зубром или его стеком.

Кстати:

  1. Нет необходимости иметь два разных члена в вашем семантическом типе для xval а также yval, Тип является unionне structтаким образом, имея два члена одного типа (float) является излишним.

  2. flex не делает регулярные выражения. Так что нет смысла избегать захвата с (?:...); это просто затемняет вашу грамматику. Вы также можете использовать:

    POINT | LINE: {yylval.ename = strdup (yytext); возврат ENAME; }

    С другой стороны, вам лучше определить два разных типа токенов, что позволит избежать необходимости strdup, (Вы, кажется, не freeдублирующую строку, поэтому strdup это также утечка памяти.) В качестве альтернативы, вы можете использовать перечисляемое значение в вашем семантическом типе:

    POINT  { yylval.ename_enum=POINT; return ENAME; }
    LINE   { yylval.ename_enum=LINE;  return ENAME; }
    
  3. . ; это не очень хорошая идея, особенно во время разработки, потому что она скрывает ошибки (например, ту, которая у вас есть). Ты можешь использовать %option nodefault избежать flexправило по умолчанию, а затем flex представит ошибку при обнаружении недопустимого символа.

  4. Если вы не используете действительно старые версии bison а также flex, вы можете просто скомпилировать сгенерированный код как c++, Там не должно быть необходимости использовать extern "C"

Другие вопросы по тегам