cgccbisonflex-lexeryacc

Flex + Bison integration errors: stray '\' and expected ';' before '{' token


I'm encountering issues with my Flex and Bison integration, specifically related to errors like "stray ` in program"and"expected ';' before '{' token." I've checked my code, but I'm unable to pinpoint the exact problem.

The errors:

lab4.l: In function 'yylex':
lab4.l:10:18: error: expected ';' before '{' token
  "#include"      { return INCLUDE; }
                  ^
lab4.l:29:13: error: stray '\' in program
  [-]?[0-9]+(\.[0-9]+)?  { return CONST; }
             ^
lab4.l:52:3: error: stray '\' in program
  [\n]       { line++; }
   ^

The lex code:

%{
    #include "lab4.tab.h"
    
    int line = 1;
%}

%option noyywrap
    
%%  
    "#include"              { return INCLUDE; }
    "cin"                   { return CIN; }
    "cout"                  { return COUT; }
    "main()"                { return MAIN; }
    "namespace"             { return NAMESPACE; }
    "std"                   { return STD; }
    "int"                   { return INT; }
    "void"                  { return VOID; }
    "double"                { return DOUBLE; }
    "<iostream>"            { return IOSTREAM; }
    "<fstream>"             { return IOSTREAM; }
    "using"                 { return USING; }
    "if"                    { return IF; }
    "else"                  { return ELSE; }
    "while"                 { return WHILE; }
    "struct"                { return STRUCT; }
    
    [1-9]*                  { return DIGIT; }
    [a-zA-Z][1-9]* {0, 250} { return ID; }
    [-]?[0-9]+(\.[0-9]+)?   { return CONST; }
    [1-9]*                  { return NZD; }
    [a-zA-Z]*               { return CHAR }
    
    "{"                     { return LBR; }
    "}"                     { return RBR; }
    "("                     { return LPR; }
    ")"                     { return RPR; }
    ">>"                    { return RS; }
    "<<"                    { return LS; }
    "<"                     { return LT; }
    ">"                     { return GT; }
    ">="                    { return GTE; }
    "<="                    { return LTE; }
    "+"                     { return PLUS; }
    "-"                     { return MINUS; }
    "*"                     { return MUL; }
    "/"                     { return DIV; }
    ";"                     { return SEMICOLON; }
    "="                     { return ASSIGN; }
    "!="                    { return DIFF; }
    "."                     { return DOT; }
    
    [\n]                    { line++; }
%%

The bison code:

%{
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    extern int yylex();
    extern int yyparse();
    extern FILE* yyin;
    extern int line;
    void yyerror();
%}
    %token DIGIT CONST ID CHAR NZD
    %token INCLUDE USING NAMESPACE STD IOSTREAM FSTREAM 
    %token INT MAIN DOUBLE VOID STRUCT
    %token LPR RPR LBR RBR 
    %token CIN COUT 
    %token IF WHILE SEMICOLON DOT
    
    %left ELSE 
    %left ASSIGN DIFF LS RS
    %left LT GT LTE GTE 
    %left PLUS MINUS MUL DIV
%%
    program         : headers_block main_block
                    ;
                  
    headers_block   : headers_list USING NAMESPACE STD SEMICOLON
                    ;
                    
    headers_list    : header headers_list
                        | header
        
    header          : INCLUDE library
                    ;
                    
    library         : IOSTREAM  
                        | FSTREAM
                    ;
                    
    main_block      : type MAIN LBR instr_list RBR
                    ;
    
    type            : VOID 
                        | INT
                        | DOUBLE
                        | triple
                        | point
                    ;
    
    triple          : NZD DOT DIGIT DIGIT DIGIT
                    ;
                    
    point           : STRUCT LBR INT ID SEMICOLON INT ID SEMICOLON RBR ID SEMICOLON
                    ;
                    
    instr_list      : instr instr_list
                        | instr 
                    ;
                    
    instr           : atribuire
                        | read
                        | write
                        | if_instr
                        | while_instr
                    ;
    
    atribuire       : type ID SEMICOLON 
                        | ID ASSIGN expr SEMICOLON
                    ;
    
    expr            : ID 
                        | CONST
                        | operand expr
                    ;
                    
    operand         : ID
                        | CONST
                        | CONST operator ID
                        | id_expr
                    ;
                    
    id_expr         : ID operator ID
                    ;
                    
    operator        : PLUS
                        | MINUS
                        | DIV
                        | MUL
                        | LT
                        | GT
                        | DIFF
                        | LTE
                        | GTE
                        | ASSIGN
                        | RS
                        | LS
                    ;
                    
    read            : CIN RS ID SEMICOLON
                    ;
    
    write           : COUT LS ID SEMICOLON
                    ;
                    
    if_instr        : IF LPR expr RPR LBR atribuire RBR else_instr
                        | IF LPR expr RPR LBR atribuire RBR
                    ;
                    
    else_instr      : ELSE LBR atribuire RBR
                    ;

    while_instr     : WHILE LPR expr RPR LBR instr RBR 
                    ;
                    
%%

int main(int argc, char* argv[]){
    ++argv, --argc;
    
    if(argc > 0){
        yyin = fopen(argv[0], "r");
    } else {
        yyin = stdin;
    }

    while(!feof(yyin)){
        yyparse();
    }
    
    printf("Result: OK\n");
    return 0;
}

void yyerror(){
    printf("Error at line %d!\n", line);
    exit(1);
}

How can I resolve these errors in the context of Flex and Bison interaction? I've included relevant sections of my code above for reference.


Solution

  • You have several issues with your Flex input, among them:

    • Flex is sensitive to indentation. The pattern in each rule must not be indented. It must start at the beginning of its line.

    • You are missing a semicolon in the action for this rule:

          [a-zA-Z]*               { return CHAR }
      
    • You have two different rules with pattern [1-9]*, returning different token types.

    • Patterns must not contain unquoted whitespace characters, such as in this rule:

          [a-zA-Z][1-9]* {0, 250} { return ID; }
      

      Remove the spaces in the pattern.