什么可能导致 Flex 出现 "unrecognized rule" 错误

What might cause an "unrecognized rule" error with Flex

我有这个 .lex 文件:

%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;
}

这是最重要的部分,但为了上下文,我也包括了其余部分。

当我尝试编译它时,出现以下错误:

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

我试过谷歌搜索、随机更改内容、自己更换零件,但都没有成功。在这一点上,我不知道问题可能是什么。

感谢阅读!

Lex 模式不能包含未加引号的空格。因此,所有扩展包含未引号空格的宏都会在使用它们的模式中产生语法错误。