3
votes

I'm trying to learn flex and lemon, in order to parse a (moderately) complex file format. So far, I have my grammar and lex file and I believe it is correctly parsing an example file. Right now, I want to pass the token text scanned with flex to lemon.

The flex YYSTYPE is defined as

#define YYSTYPE char*

The lemon token type is

%token_type {char *}

However, if I have a set of rules in lemon:

start ::= MATDEF IDENTIFIER(matName) LEFT_CURLY_BRACE(left) materialDefinitionBody(mBody) RIGHT_CURLY_BRACE(right) .
{
std::string r = std::string(matName) + std::string(left) + mBody + std::string(right);
std::cout << "result " << r << std::endl;
}

materialDefinitionBody(r) ::= techniqueList .
{
r = "a";
}

the output will be

result a

when it should be something like

mat1 { a }

My main parsing loop is:

void parse(const string& commandLine) {
    // Set up the scanner
    yyscan_t scanner;
    yylex_init(&scanner);
    YY_BUFFER_STATE bufferState = yy_scan_string(commandLine.c_str(), scanner);

    // Set up the parser
    void* shellParser = ParseAlloc(malloc);

    yylval = new char[512];
    int lexCode;
    do {
        yylval[0] = 0;
        lexCode = yylex(scanner);
        cout << lexCode << " : " << yylval << std::endl;
        Parse(shellParser, lexCode, yylval);
    }
    while (lexCode > 0);

    if (-1 == lexCode) {
        cerr << "The scanner encountered an error.\n";
    }

    // Cleanup the scanner and parser
    yy_delete_buffer(bufferState, scanner);
    yylex_destroy(scanner);
    ParseFree(shellParser, free);
}

The cout line is printing the correct lexCode/yylval combination.

What is the best way? I can't find anything that works.

1

1 Answers

0
votes

You need to have

yylval = new char[512];

inside the do-while loop.