1
votes

I am learning flex and bison from John R. Levine's book. I would like to read a single 'SELECT;' statement (this is the content of the file my code reads), but I receive 'flex scanner jammed'. What is wrong with the code?

The lexer: pmysql.l

%option noyywrap nodefault yylineno case-insensitive
%{
#include "pmysql.tab.h"
#include <stdarg.h>
#include <string.h>

void yyerror(char *s, ...);

%}

%%

"SELECT"  { return SELECT; }
[-+&~|^/%*(),.;!]   { return yytext[0]; }

%%

The lexer: pmysql.y

%{
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
void yyerror(char *s, ...);
void emit(char *s, ...);
%}

%token SELECT
%start stmt_list

%%

stmt_list: stmt ';'
| stmt_list stmt ';'       
;
stmt: select_stmt { emit("STMT"); };
select_stmt: SELECT {emit("SELECT"); };

%%

void emit(char *s, ...) {
    extern yylineno;
    va_list ap;
    va_start(ap, s);
    printf("rpn: ");
    vfprintf(stdout, s, ap);
    printf("\n");
}

void yyerror(char *s, ...) {
    extern yylineno;
    va_list ap;
    va_start(ap, s);
    fprintf(stderr, "%d: error: ", yylineno);
    vfprintf(stderr, s, ap);
    fprintf(stderr, "\n");
}

main(int ac, char **av){
    extern FILE *yyin;
    if(ac > 1 && (yyin = fopen(av[1], "r")) == NULL) {
        perror(av[1]);
        exit(1);
    }

    if(!yyparse())
        printf("SQL parse worked\n");
    else
        printf("SQL parse failed\n");
}

My output is:

rpn: SELECT
rpn: STMT
flex scanner jammed
1
Sorry, it seems that I forgot to deal with newline character. Addong [ \t\n] to the lexer solves the problem. - robogos

1 Answers

1
votes

If it doesn't find the word "SELECT", or any of the punctuation -+&~|^/%*(),.;!, then the scanner doesn't know what to do. Add a catch-all at the end:

 . { printf("unknown character in input: %c\n", *yytext) }