用C语言编写Lex和Yacc规则来检测#include

用C语言编写Lex和Yacc规则来检测#include,c,yacc,lex,C,Yacc,Lex,我正在编写Lex/Yacc代码来检测#include或#include“某些头文件”。这些是我的代码: Lex代码 %e 1019 %p 2807 %n 371 %k 284 %a 1213 %o 1117 O [0-7] D [0-9] NZ [1-9] L [a-zA-Z_] /***********************/ A [a-zA-Z_0-9] H [a-fA-F0-9] HP (0[xX]) E ([

我正在编写Lex/Yacc代码来检测#include或#include“某些头文件”。这些是我的代码:

Lex代码

%e  1019
%p  2807
%n  371
%k  284
%a  1213
%o  1117

O   [0-7]
D   [0-9]
NZ  [1-9]
L   [a-zA-Z_]            /***********************/       
A   [a-zA-Z_0-9]
H   [a-fA-F0-9]
HP  (0[xX])
E   ([Ee][+-]?{D}+)
P   ([Pp][+-]?{D}+)
FS  (f|F|l|L)
IS  (((u|U)(l|L|ll|LL)?)|((l|L|ll|LL)(u|U)?))
CP  (u|U|L)
SP  (u8|u|U|L)
ES  (\\(['"\?\\abfnrtv]|[0-7]{1,3}|x[a-fA-F0-9]+))
WS  [ \t\v\n\f]

%{
    #include <stdio.h>
    #include "y.tab.h"

    extern void yyerror(const char *);  

    extern int sym_type(const char *);  

    #define sym_type(identifier) IDENTIFIER 

    static void comment(void);
    static int check_type(void);
%}

%%
{L}                     {yylval.a=strdup(yytext); return STATEMENT;} /*****************/

"/*"                                    { comment(); }
"//".*                                    { /* consume //-comment */ }

"include"               { yylval.a=strdup(yytext); return(INCLUDE); }
"void"                  { yylval.a=strdup(yytext); return(VOID); }
"int"                   { yylval.a=strdup(yytext); return(INT); } 
"long"                  { yylval.a=strdup(yytext); return(LONG); }
"char"                  { yylval.a=strdup(yytext); return(CHAR); }
"short"                 { yylval.a=strdup(yytext); return(SHORT); }
"signed"                { yylval.a=strdup(yytext); return(SIGNED); }
"double"                { yylval.a=strdup(yytext); return(DOUBLE); }
"unsigned"              { yylval.a=strdup(yytext); return(UNSIGNED); }
"float"                 { yylval.a=strdup(yytext); return(FLOAT); }


"auto"                  { yylval.a=strdup(yytext); return(AUTO); } 
"extern"                { yylval.a=strdup(yytext); return(EXTERN); }
"register"              { yylval.a=strdup(yytext); return(REGISTER); }
"static"                { yylval.a=strdup(yytext); return(STATIC); }


"const"                 { yylval.a=strdup(yytext); return(CONST); } 
"restrict"              { yylval.a=strdup(yytext); return(RESTRICT); }
"volatile"              { yylval.a=strdup(yytext); return(VOLATILE); }
"_Atomic"               { yylval.a=strdup(yytext); return ATOMIC; }


"break"                 { yylval.a=strdup(yytext); return(BREAK); }
"case"                  { yylval.a=strdup(yytext); return(CASE); }

"continue"              { yylval.a=strdup(yytext); return(CONTINUE); }
"default"               { yylval.a=strdup(yytext); return(DEFAULT); }
"do"                    { yylval.a=strdup(yytext); return(DO); }
"else"                  { yylval.a=strdup(yytext); return(ELSE); }
"enum"                  { yylval.a=strdup(yytext); return(ENUM); }

"for"                   { yylval.a=strdup(yytext); return(FOR); }
"goto"                  { yylval.a=strdup(yytext); return(GOTO); }
"if"                    { yylval.a=strdup(yytext); return(IF); }
"inline"                { yylval.a=strdup(yytext); return(INLINE); }


"return"                { yylval.a=strdup(yytext); return(RETURN); }
"sizeof"                { yylval.a=strdup(yytext); return(SIZEOF); }

"struct"                { yylval.a=strdup(yytext); return(STRUCT); }
"switch"                { yylval.a=strdup(yytext); return(SWITCH); }
"typedef"               { yylval.a=strdup(yytext); return(TYPEDEF); }
"union"                 { yylval.a=strdup(yytext); return(UNION); }



"while"                 { yylval.a=strdup(yytext); return(WHILE); }
"_Alignas"              { yylval.a=strdup(yytext); return ALIGNAS; }
"_Alignof"              { yylval.a=strdup(yytext); return ALIGNOF; }

"_Bool"                 { yylval.a=strdup(yytext); return BOOL; }
"_Complex"              { yylval.a=strdup(yytext); return COMPLEX; }
"_Generic"              { yylval.a=strdup(yytext); return GENERIC; }
"_Imaginary"            { yylval.a=strdup(yytext); return IMAGINARY; }
"_Noreturn"             { yylval.a=strdup(yytext); return NORETURN; }
"_Static_assert"        { yylval.a=strdup(yytext); return STATIC_ASSERT; }
"_Thread_local"         { yylval.a=strdup(yytext); return THREAD_LOCAL; }
"__func__"              { yylval.a=strdup(yytext); return FUNC_NAME; }

{L}{A}*                 { return check_type(); }

{HP}{H}+{IS}?               { yylval.a=strdup(yytext); return I_CONSTANT; }
{NZ}{D}*{IS}?               { yylval.a=strdup(yytext); return I_CONSTANT; }
"0"{O}*{IS}?                { yylval.a=strdup(yytext); return I_CONSTANT; }
{CP}?"'"([^'\\\n]|{ES})+"'"     { return I_CONSTANT; } /**/

{D}+{E}{FS}?                { yylval.a=strdup(yytext); return F_CONSTANT; }
{D}*"."{D}+{E}?{FS}?        { yylval.a=strdup(yytext); return F_CONSTANT; }
{D}+"."{E}?{FS}?            { yylval.a=strdup(yytext); return F_CONSTANT; }
{HP}{H}+{P}{FS}?            { yylval.a=strdup(yytext);return F_CONSTANT; }
{HP}{H}*"."{H}+{P}{FS}?     { yylval.a=strdup(yytext); return F_CONSTANT; }
{HP}{H}+"."{P}{FS}?         { yylval.a=strdup(yytext); return F_CONSTANT; }

({SP}?\"([^"\\\n]|{ES})*\"{WS}*)+   { return STRING_LITERAL; }

"..."                   { yylval.a=strdup(yytext); return ELLIPSIS; }
">>="                   { yylval.a=strdup(yytext); return RIGHT_ASSIGN; }
"<<="                   { yylval.a=strdup(yytext); return LEFT_ASSIGN; }
"+="                    { yylval.a=strdup(yytext); return ADD_ASSIGN; }
"-="                    { yylval.a=strdup(yytext); return SUB_ASSIGN; }
"*="                    { yylval.a=strdup(yytext); return MUL_ASSIGN; }
"/="                    { yylval.a=strdup(yytext); return DIV_ASSIGN; }
"%="                    { yylval.a=strdup(yytext); return MOD_ASSIGN; }
"&="                    { yylval.a=strdup(yytext); return AND_ASSIGN; }
"^="                    { yylval.a=strdup(yytext); return XOR_ASSIGN; }
"|="                    { yylval.a=strdup(yytext); return OR_ASSIGN; }
">>"                    { yylval.a=strdup(yytext); return RIGHT_OP; }
"<<"                    { yylval.a=strdup(yytext); return LEFT_OP; }
"++"                    { yylval.a=strdup(yytext); return INC_OP; }
"--"                    { yylval.a=strdup(yytext); return DEC_OP; }
"->"                    { yylval.a=strdup(yytext); return PTR_OP; }
"&&"                    { yylval.a=strdup(yytext); return AND_OP; }
"||"                    { yylval.a=strdup(yytext); return OR_OP; }
"<="                    { yylval.a=strdup(yytext); return LE_OP; }
">="                    { yylval.a=strdup(yytext); return GE_OP; }
"=="                    { yylval.a=strdup(yytext); return EQ_OP; }
"!="                    { yylval.a=strdup(yytext); return NE_OP; }
";"                     { yylval.a=strdup(yytext); return ';'; }
("{"|"<%")              { yylval.a=strdup(yytext); return '{'; }
("}"|"%>")              { yylval.a=strdup(yytext); return '}'; }
","                     { yylval.a=strdup(yytext); return ','; }
":"                     { yylval.a=strdup(yytext); return ':'; }
"="                     { yylval.a=strdup(yytext); return '='; }
"("                     { yylval.a=strdup(yytext); return '('; }
")"                     { yylval.a=strdup(yytext); return ')'; }
("["|"<:")              { yylval.a=strdup(yytext); return '['; }
("]"|":>")              { yylval.a=strdup(yytext); return ']'; }
"."                     { yylval.a=strdup(yytext); return '.'; }
"&"                     { yylval.a=strdup(yytext); return '&'; }
"!"                     { yylval.a=strdup(yytext); return '!'; }
"~"                     { yylval.a=strdup(yytext); return '~'; }
"-"                     { yylval.a=strdup(yytext); return '-'; }
"+"                     { yylval.a=strdup(yytext); return '+'; }
"*"                     { yylval.a=strdup(yytext); return '*'; }
"/"                     { yylval.a=strdup(yytext); return '/'; }
"%"                     { yylval.a=strdup(yytext); return '%'; }
"<"                     { yylval.a=strdup(yytext); return '<'; } /***********************/
">"                     { yylval.a=strdup(yytext); return '>'; } /***********************/
"^"                     { yylval.a=strdup(yytext); return '^'; }
"|"                     { yylval.a=strdup(yytext); return '|'; }
"?"                     { yylval.a=strdup(yytext); return '?'; }

"#"                     {yylval.a=strdup(yytext); return '#'; } /***********************/




{WS}+                   { /* whitespace separates tokens */ }
.                   { /* discard bad characters */ }

%%

int yywrap(void)        
{
    return 1;           
}

static void comment(void)
{
    int c;

    while ((c = input()) != 0)
    if (c == '*')
    {
        printf("1: %d\n",c);
        while ((c = input()) == '*')
        ;
        printf("2: %d\n",c);
        if (c == '/')
        return;
        if (c == 0)
        printf("3: %d\n",c);
        break;
    }
    yyerror("unterminated comment");
}

static int check_type(void)
{
    switch (sym_type(yytext))
    {
        case TYPEDEF_NAME:                
            {
            return TYPEDEF_NAME;
            }
        case ENUMERATION_CONSTANT:        
        return ENUMERATION_CONSTANT;
        default:                          
            {
            yylval.a=strdup(yytext);
            return IDENTIFIER;
            }
    }
}
%token  IDENTIFIER I_CONSTANT F_CONSTANT STRING_LITERAL FUNC_NAME SIZEOF
%token  PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
%token  AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
%token  SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
%token  XOR_ASSIGN OR_ASSIGN
%token  TYPEDEF_NAME ENUMERATION_CONSTANT

%token  TYPEDEF EXTERN STATIC AUTO REGISTER INLINE
%token  CONST RESTRICT VOLATILE
%token  BOOL CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE VOID
%token  COMPLEX IMAGINARY
%token  STRUCT UNION ENUM ELLIPSIS

%token  CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN

%token  ALIGNAS ALIGNOF ATOMIC GENERIC NORETURN STATIC_ASSERT THREAD_LOCAL

%token INCLUDE STATEMENT  /********************/

%start translation_unit
%{

    #include<stdio.h>
    #include<string.h>
    extern FILE* yyin;
int yylex();
void yyerror(const char *s);

%}
%union{
    char* a;
    char* b;
}

%type <a>IDENTIFIER
%type <a>SIGNED UNSIGNED
%type <a>INT CHAR DOUBLE FLOAT LONG SHORT
%type <b>EXTERN STATIC AUTO REGISTER

%%

include                          /*********************/
: '#' INCLUDE '<' STATEMENT '>'  /*********************/
| '#' INCLUDE '"' STATEMENT '"'  /*********************/
;



primary_expression
: IDENTIFIER
| constant
| string
| '(' expression ')'
| generic_selection
;

constant
: I_CONSTANT        /* includes character_constant */
| F_CONSTANT
| ENUMERATION_CONSTANT  /* after it has been defined as such */
;

enumeration_constant        /* before it has been defined as such */
: IDENTIFIER
;

string
: STRING_LITERAL
| FUNC_NAME
;

generic_selection
: GENERIC '(' assignment_expression ',' generic_assoc_list ')'
;

generic_assoc_list
: generic_association
| generic_assoc_list ',' generic_association
;

generic_association
: type_name ':' assignment_expression
| DEFAULT ':' assignment_expression
;

postfix_expression
: primary_expression
| postfix_expression '[' expression ']'
| postfix_expression '(' ')'
| postfix_expression '(' argument_expression_list ')'
| postfix_expression '.' IDENTIFIER
| postfix_expression PTR_OP IDENTIFIER
| postfix_expression INC_OP
| postfix_expression DEC_OP
| '(' type_name ')' '{' initializer_list '}'
| '(' type_name ')' '{' initializer_list ',' '}'
;

argument_expression_list
: assignment_expression
| argument_expression_list ',' assignment_expression
;

unary_expression
: postfix_expression
| INC_OP unary_expression
| DEC_OP unary_expression
| unary_operator cast_expression
| SIZEOF unary_expression
| SIZEOF '(' type_name ')'
| ALIGNOF '(' type_name ')'
;

unary_operator
: '&'
| '*'
| '+'
| '-'
| '~'
| '!'
;

cast_expression
: unary_expression
| '(' type_name ')' cast_expression
;

multiplicative_expression
: cast_expression
| multiplicative_expression '*' cast_expression
| multiplicative_expression '/' cast_expression
| multiplicative_expression '%' cast_expression
;

additive_expression
: multiplicative_expression
| additive_expression '+' multiplicative_expression
| additive_expression '-' multiplicative_expression
;

shift_expression
: additive_expression
| shift_expression LEFT_OP additive_expression
| shift_expression RIGHT_OP additive_expression
;

relational_expression
: shift_expression
| relational_expression '<' shift_expression
| relational_expression '>' shift_expression
| relational_expression LE_OP shift_expression
| relational_expression GE_OP shift_expression
;

equality_expression
: relational_expression
| equality_expression EQ_OP relational_expression
| equality_expression NE_OP relational_expression
;

and_expression
: equality_expression
| and_expression '&' equality_expression
;

exclusive_or_expression
: and_expression
| exclusive_or_expression '^' and_expression
;

inclusive_or_expression
: exclusive_or_expression
| inclusive_or_expression '|' exclusive_or_expression
;

logical_and_expression
: inclusive_or_expression
| logical_and_expression AND_OP inclusive_or_expression
;

logical_or_expression
: logical_and_expression
| logical_or_expression OR_OP logical_and_expression
;

conditional_expression
: logical_or_expression
| logical_or_expression '?' expression ':' conditional_expression
;

assignment_expression
: conditional_expression
| unary_expression assignment_operator assignment_expression
;

assignment_operator
: '='
| MUL_ASSIGN
| DIV_ASSIGN
| MOD_ASSIGN
| ADD_ASSIGN
| SUB_ASSIGN
| LEFT_ASSIGN
| RIGHT_ASSIGN
| AND_ASSIGN
| XOR_ASSIGN
| OR_ASSIGN
;

expression
: assignment_expression
| expression ',' assignment_expression
;

constant_expression
: conditional_expression    /* with constraints */
;

declaration
: declaration_specifiers ';'    /* no rule need*/
| declaration_specifiers init_declarator_list ';' { printf("declaration_specifier:%s\nThe init_declarator_list:%s \nsemicolon:%s\n",$<a>1,$<a>2,$<a>3);

                                                }
| static_assert_declaration
;

declaration_specifiers
: storage_class_specifier declaration {printf("Storage_class_specifier:%s \ndeclaration_specifiers:%s \n",$<b>1,$<b>2);}
| storage_class_specifier
| type_specifier declaration_specifiers
| type_specifier
| type_qualifier declaration_specifiers
| type_qualifier
| function_specifier declaration_specifiers
| function_specifier
| alignment_specifier declaration_specifiers
| alignment_specifier
;

init_declarator_list
: init_declarator
| init_declarator_list ',' init_declarator
;

init_declarator
: declarator '=' initializer
| declarator
;

storage_class_specifier
: TYPEDEF   /* identifiers must be flagged as TYPEDEF_NAME */
| EXTERN
| STATIC
| THREAD_LOCAL
| AUTO
| REGISTER
;

type_specifier
: VOID
| CHAR
| SHORT
| INT
| LONG
| FLOAT
| DOUBLE
| SIGNED
| UNSIGNED
| BOOL
| COMPLEX
| IMAGINARY     /* non-mandated extension */
| atomic_type_specifier
| struct_or_union_specifier
| enum_specifier
| TYPEDEF_NAME      /* after it has been defined as such */
;



struct_or_union_specifier
: struct_or_union '{' struct_declaration_list '}'
| struct_or_union IDENTIFIER '{' struct_declaration_list '}'
| struct_or_union IDENTIFIER
;

struct_or_union
: STRUCT
| UNION
;

struct_declaration_list
: struct_declaration
| struct_declaration_list struct_declaration
;

struct_declaration
: specifier_qualifier_list ';'  /* for anonymous struct/union */
| specifier_qualifier_list struct_declarator_list ';'
| static_assert_declaration
;

specifier_qualifier_list
: type_specifier specifier_qualifier_list
| type_specifier
| type_qualifier specifier_qualifier_list
| type_qualifier
;

struct_declarator_list
: struct_declarator
| struct_declarator_list ',' struct_declarator
;

struct_declarator
: ':' constant_expression
| declarator ':' constant_expression
| declarator
;

enum_specifier
: ENUM '{' enumerator_list '}'
| ENUM '{' enumerator_list ',' '}'
| ENUM IDENTIFIER '{' enumerator_list '}'
| ENUM IDENTIFIER '{' enumerator_list ',' '}'
| ENUM IDENTIFIER
;

enumerator_list
: enumerator
| enumerator_list ',' enumerator
;

enumerator  /* identifiers must be flagged as ENUMERATION_CONSTANT */
: enumeration_constant '=' constant_expression
| enumeration_constant
;

atomic_type_specifier
: ATOMIC '(' type_name ')'
;

type_qualifier
: CONST
| RESTRICT
| VOLATILE
| ATOMIC
;

function_specifier
: INLINE
| NORETURN
;

alignment_specifier
: ALIGNAS '(' type_name ')'
| ALIGNAS '(' constant_expression ')'
;

declarator
: pointer direct_declarator
| direct_declarator
;

direct_declarator
: IDENTIFIER
| '(' declarator ')'
| direct_declarator '[' ']'
| direct_declarator '[' '*' ']'
| direct_declarator '[' STATIC type_qualifier_list assignment_expression ']'
| direct_declarator '[' STATIC assignment_expression ']'
| direct_declarator '[' type_qualifier_list '*' ']'
| direct_declarator '[' type_qualifier_list STATIC assignment_expression ']'
| direct_declarator '[' type_qualifier_list assignment_expression ']'
| direct_declarator '[' type_qualifier_list ']'
| direct_declarator '[' assignment_expression ']'
| direct_declarator '(' parameter_type_list ')'
| direct_declarator '(' ')'
| direct_declarator '(' identifier_list ')'
;

pointer
: '*' type_qualifier_list pointer
| '*' type_qualifier_list
| '*' pointer
| '*'
;

type_qualifier_list
: type_qualifier
| type_qualifier_list type_qualifier
;


parameter_type_list
: parameter_list ',' ELLIPSIS
| parameter_list
;

parameter_list
: parameter_declaration
| parameter_list ',' parameter_declaration
;

parameter_declaration
: declaration_specifiers declarator
| declaration_specifiers abstract_declarator
| declaration_specifiers
;

identifier_list
: IDENTIFIER
| identifier_list ',' IDENTIFIER
;

type_name
: specifier_qualifier_list abstract_declarator
| specifier_qualifier_list
;

abstract_declarator
: pointer direct_abstract_declarator
| pointer
| direct_abstract_declarator
;

direct_abstract_declarator
: '(' abstract_declarator ')'
| '[' ']'
| '[' '*' ']'
| '[' STATIC type_qualifier_list assignment_expression ']'
| '[' STATIC assignment_expression ']'
| '[' type_qualifier_list STATIC assignment_expression ']'
| '[' type_qualifier_list assignment_expression ']'
| '[' type_qualifier_list ']'
| '[' assignment_expression ']'
| direct_abstract_declarator '[' ']'
| direct_abstract_declarator '[' '*' ']'
| direct_abstract_declarator '[' STATIC type_qualifier_list assignment_expression ']'
| direct_abstract_declarator '[' STATIC assignment_expression ']'
| direct_abstract_declarator '[' type_qualifier_list assignment_expression ']'
| direct_abstract_declarator '[' type_qualifier_list STATIC assignment_expression ']'
| direct_abstract_declarator '[' type_qualifier_list ']'
| direct_abstract_declarator '[' assignment_expression ']'
| '(' ')'
| '(' parameter_type_list ')'
| direct_abstract_declarator '(' ')'
| direct_abstract_declarator '(' parameter_type_list ')'
;

initializer
: '{' initializer_list '}'
| '{' initializer_list ',' '}'
| assignment_expression
;

initializer_list
: designation initializer
| initializer
| initializer_list ',' designation initializer
| initializer_list ',' initializer
;

designation
: designator_list '='
;

designator_list
: designator
| designator_list designator
;

designator
: '[' constant_expression ']'
| '.' IDENTIFIER
;

static_assert_declaration
: STATIC_ASSERT '(' constant_expression ',' STRING_LITERAL ')' ';'
;

statement
: labeled_statement
| compound_statement
| expression_statement
| selection_statement
| iteration_statement
| jump_statement
;

labeled_statement
: IDENTIFIER ':' statement
| CASE constant_expression ':' statement
| DEFAULT ':' statement
;

compound_statement
: '{' '}'
| '{'  block_item_list '}'
;

block_item_list
: block_item
| block_item_list block_item
;

block_item
: declaration
| statement
;

expression_statement
: ';'
| expression ';'
;

selection_statement
: IF '(' expression ')' statement ELSE statement
| IF '(' expression ')' statement
| SWITCH '(' expression ')' statement
;

iteration_statement
: WHILE '(' expression ')' statement
| DO statement WHILE '(' expression ')' ';'
| FOR '(' expression_statement expression_statement ')' statement
| FOR '(' expression_statement expression_statement expression ')' statement
| FOR '(' declaration expression_statement ')' statement
| FOR '(' declaration expression_statement expression ')' statement
;

jump_statement
: GOTO IDENTIFIER ';'
| CONTINUE ';'
| BREAK ';'
| RETURN ';'
| RETURN expression ';'
;

translation_unit
: external_declaration
| translation_unit external_declaration
;

external_declaration
: function_definition
| declaration
;

function_definition
: declaration_specifiers declarator declaration_list compound_statement
| declaration_specifiers declarator compound_statement
;

declaration_list
: declaration
| declaration_list declaration
;

%%
#include <stdio.h>

void yyerror(const char *s)
{
    fflush(stdout);
    fprintf(stderr, "*** %s\n", s);
}
void parse(FILE* fileInput)
{
    yyin= fileInput;
    while(feof(yyin)==0)
    {
        yyparse();// To read file, while() and yyparse() is necessary because we need to read until the content is run out
    }
}
%e 1019
%第2807页
%n 371
%k 284
%1213年
%o 1117
O[0-7]
D[0-9]
新西兰[1-9]
L[a-zA-Zè]/***************************/
A[A-zA-Z_0-9]
H[a-fA-F0-9]
HP(0[xX])
E([Ee][+-]?{D}+)
P([Pp][+-]?{D}+)
FS(f | f | l | l)
是((u | u)(l | l | ll | ll)?)|((l | l | ll | ll)(u | u)?)
CP(u | u | L)
SP(u8 | u | u | L)
ES(\\(['“\?\\abfnrtv]|[0-7]{1,3}|x[a-fA-F0-9]+)
WS[\t\v\n\f]
%{
#包括
#包括“y.tab.h”
外部无效错误(常量字符*);
外部内部符号类型(常量字符*);
#定义符号类型(标识符)标识符
静态无效注释(void);
静态整数检查类型(无效);
%}
%%
{五十} {yylval.a=strdup(yytext);返回语句;}/*****************/
“/*”{comment();}
“//”*{/*消费//-注释*/}
include“{yylval.a=strdup(yytext);return(include);}
“void”{yylval.a=strdup(yytext);return(void);}
“int”{yylval.a=strdup(yytext);return(int);}
“long”{yylval.a=strdup(yytext);return(long);}
“char”{yylval.a=strdup(yytext);return(char);}
“short”{yylval.a=strdup(yytext);return(short);}
“signed”{yylval.a=strdup(yytext);return(signed);}
“double”{yylval.a=strdup(yytext);return(double);}
“unsigned”{yylval.a=strdup(yytext);return(unsigned);}
“float”{yylval.a=strdup(yytext);return(float);}
“auto”{yylval.a=strdup(yytext);return(auto);}
“extern”{yylval.a=strdup(yytext);return(extern);}
“寄存器”{yylval.a=strdup(yytext);return(register);}
“static”{yylval.a=strdup(yytext);return(static);}
“const”{yylval.a=strdup(yytext);return(const);}
“restrict”{yylval.a=strdup(yytext);return(restrict);}
“volatile”{yylval.a=strdup(yytext);return(volatile);}
“_原子”{yylval.a=strdup(yytext);返回原子;}
“break”{yylval.a=strdup(yytext);return(break);}
“case”{yylval.a=strdup(yytext);return(case);}
“continue”{yylval.a=strdup(yytext);return(continue);}
“default”{yylval.a=strdup(yytext);return(default);}
“do”{yylval.a=strdup(yytext);return(do);}
“else”{yylval.a=strdup(yytext);return(else);}
“enum”{yylval.a=strdup(yytext);return(enum);}
for“{yylval.a=strdup(yytext);return(for);}
“goto”{yylval.a=strdup(yytext);return(goto);}
“如果”{yylval.a=strdup(yytext);返回(if);}
“inline”{yylval.a=strdup(yytext);return(inline);}
“return”{yylval.a=strdup(yytext);return(return);}
“sizeof”{yylval.a=strdup(yytext);return(sizeof);}
“struct”{yylval.a=strdup(yytext);return(struct);}
“switch”{yylval.a=strdup(yytext);return(switch);}
“typedef”{yylval.a=strdup(yytext);return(typedef);}
“union”{yylval.a=strdup(yytext);return(union);}
while“{yylval.a=strdup(yytext);return(while);}
“_Alignas”{yylval.a=strdup(yytext);返回Alignas;}
“_Alignof”{yylval.a=strdup(yytext);返回Alignof;}
“_Bool”{yylval.a=strdup(yytext);返回Bool;}
“_复数”{yylval.a=strdup(yytext);返回复数;}
“_Generic”{yylval.a=strdup(yytext);返回Generic;}
“_virtual”{yylval.a=strdup(yytext);返回virtual;}
“_Noreturn”{yylval.a=strdup(yytext);返回Noreturn;}
“_Static_assert”{yylval.a=strdup(yytext);返回Static_assert;}
“_Thread_local”{yylval.a=strdup(yytext);返回Thread_local;}
“{yylval.a=strdup(yytext);返回函数名;}”
{五十} {A}*{return check_type();}
{HP}{H}+{IS}?{yylval.a=strdup(yytext);返回I_常量;}
{NZ}{D}*{IS}?{yylval.a=strdup(yytext);返回I_常量;}
“0”{O}*{IS}?{yylval.a=strdup(yytext);返回I_常量;}
{CP}?”“([^'\\\n]{ES})+”“{return I_常量;}”/**/
{D} +{E}{FS}{yylval.a=strdup(yytext);返回F_常量;}
{D} *“{D}+{E}?{FS}{yylval.a=strdup(yytext);返回F_常量;}”
{D} +“{E}?{FS}?{yylval.a=strdup(yytext);返回F_常量;}
{HP}{H}+{P}{FS}{yylval.a=strdup(yytext);返回F_常量;}
{HP}{H}*“{H}+{P}{FS}{yylval.a=strdup(yytext);返回F_常量;}”
{HP}{H}+“{P}{FS}{yylval.a=strdup(yytext);返回F_常量;}
({SP}?\”([^“\\\n]{ES})*\“{WS}*)+{return STRING\u LITERAL;}
“…”{yylval.a=strdup(yytext);返回省略号;}
“>>=”{yylval.a=strdup(yytext);返回RIGHT_ASSIGN;}
“{yylval.a=strdup(yytext);返回RIGHT_OP;}

“您会收到警告,因为非终结符
包含
不是解析树的一部分。一种可能的解决方案是将
包含
添加到
翻译单元
规则:

translation_unit: 
   include translation_unit 
 | external_declaration 
 | ...

您会收到警告,因为非终结符
include
不是解析树的一部分。一种可能的解决方案是将
include
添加到
translation\u单元
规则:

translation_unit: 
   include translation_unit 
 | external_declaration 
 | ...

也许是因为你从来没有在解析器中的任何地方使用过
include
规则?我不知道你从哪个古老的例子中挖掘出了最初的几个lex选项,但所有这些都被弃用了几十年,而且一点效果都没有。此外,你执行的每个
strdup
都需要