Home > Enterprise >  What might cause an "unrecognized rule" error with Flex
What might cause an "unrecognized rule" error with Flex

Time:11-24

I have this .lex file:

%option noyywrap

%{
#include <string.h>

#include "ncc.h"
#include "tok/tokens.h"

static void addToken(Token t);

#define TK_NL ((Token){ \
    .type = NL          \
})
%}

LETTER      [a-zA-Z]
DIGIT       [0-9]
NONDIGIT    {LETTER}|"_"

/* Digits */
OCTAL_DIGIT [0-7]
HEX_DIGIT   [0-9a-fA-F]
HEX_QUAD    {HEX_DIGIT} {HEX_DIGIT} {HEX_DIGIT} {HEX_DIGIT}

/* Escape sequences */
SIMPLE_ESC  "\\'"|"\\\""|"\\?"|"\\\\"|"\\a"|"\\b"|"\\f"|"\\n"|"\\r"|"\\t"|"\\v"
OCTAL_ESC   "\\" {OCTAL_DIGIT} ({OCTAL_DIGIT}?) ({OCTAL_DIGIT}?)
HEX_ESC     "\\" {HEX_DIGIT} 
UCHRNAME    ("\\u" {HEX_QUAD}) | ("\\U" {HEX_QUAD} {HEX_QUAD})

ESCAPE_SEQ  {SIMPLE_ESC}|{OCTAL_ESC}|{HEX_ESC}|{UCHRNAME}
C_CHAR      [^'\\]|{ESCAPE_SEQ}
C_CHAR_SEQ  {C_CHAR} 

/* Literals */
CHAR_LITERAL "'" {C_CHAR_SEQ} "'"

%%

"\n"                    { addToken(TK_NL); }

{CHAR_LITERAL}          {
                        char c;

                        if (yytext[1] == '\\')
                        {
                            // Escape sequence
                            switch (yytext[2])
                            {
                            case 'n':
                                c = '\n';
                                break;
                            case 't':
                                c = '\t';
                                break;
                            case 'r':
                                c = '\r';
                                break;
                            case 'v':
                                c = '\v';
                                break;
                            case 'a':
                                c = '\a';
                                break;
                            case 'f':
                                c = '\f';
                                break;
                            case 'b':
                                c = '\b';
                                break;
                            case '\'':
                                c = '\'';
                                break;
                            case '"':
                                c = '"';
                                break;
                            case '?':
                                c = '?';
                                break;
                            case '\\':
                                c = '\\';
                                break;
                            default:
                                break;
                            }
                        }
                        addToken((Token){
                            .type = CHAR_CNST,
                            .char_literal = c
                        }); }

.                       {/* eat up other characters */}
%%

static Token *tokens;
static size_t tokens_len = 0;

Token *LexStream(FILE *s, size_t *len_out)
{
    tokens = NULL;
    yyin = s;

    yylex();
    
    *len_out = tokens_len;
    return tokens;
}

char *GetTokenAsString(Token token)
{
    char *result = NULL;
    
    switch (token.type)
    {
    case NL:
        result = strdup("NL");
        break;
    case CHAR_CNST:
        result = strdup("CHAR_CNST");
        break;
    }

    if (result == NULL)
    {
        Crash(CR_NOMEM);
    }

    return result;
}

static void addToken(Token t)
{
      tokens_len;
    if (tokens == NULL)
    {
        tokens = malloc(sizeof(*tokens));
    }
    else
    {
        tokens = realloc(tokens, sizeof(*tokens) * tokens_len);
    }

    if (tokens == NULL)
    {
        Crash(CR_NOMEM);
    }

    tokens[tokens_len - 1] = t;
}

It's the top of this that is important, but I included the rest too for context.

When I try to compile it, I get the following error:

../ncc/tok/tokens.lex:41: unrecognized rule

I've tried googling, randomly changing things, replacing the parts myself, but all without success. At this point, I have no idea what the issue might be.

Thanks for reading!

CodePudding user response:

Lex patterns cannot include unquoted spaces. so all of your macros whose expansions include unquoted spaces will create syntax errors in the patterns in which they are used.

  • Related