C 如何组合两个flex(.l)文件并在一个Bison文件(.y)中使用它们?

C 如何组合两个flex(.l)文件并在一个Bison文件(.y)中使用它们?,c,bison,flex-lexer,C,Bison,Flex Lexer,我对Bison/Flex很陌生。我创建了一个程序来读取c文件并识别定义的函数。成功了。我想知道,我如何使用来自另一个开源的预定义lex文件,并将其令牌用于我的lex文件并生成输出 简单地说,是否可以组合两个或多个lex文件并作为输入(Bison(.y)文件从中读取令牌) 请推荐我。 谢谢 为了清楚起见,这里有一个样本 c.l(来源-->) D[0-9] L[a-zA-Z_2;] H[a-fA-F0-9] E[Ee][+-]?{D}+ FS(f | f | l | l) IS(u | u | l

我对Bison/Flex很陌生。我创建了一个程序来读取c文件并识别定义的函数。成功了。我想知道,我如何使用来自另一个开源的预定义lex文件,并将其令牌用于我的lex文件并生成输出

简单地说,是否可以组合两个或多个lex文件并作为输入(Bison(.y)文件从中读取令牌)

请推荐我。 谢谢

为了清楚起见,这里有一个样本

c.l(来源-->)

D[0-9]
L[a-zA-Z_2;]
H[a-fA-F0-9]
E[Ee][+-]?{D}+
FS(f | f | l | l)
IS(u | u | l | l)*
%{
/*此扫描仪来源于:http://www.lysator.liu.se/c/ANSI-C-grammar-l.html */
无效计数();
#包括
#包括
#定义YYSTYPE void*
%}
%%
“/*”{comment();}
“自动”{count();返回(自动);}
“break”{count();返回(break);}
“case”{count();返回(case);}
“char”{count();返回(char);}
“const”{count();返回(const);}
“continue”{count();return(continue);}
“默认值”{count();返回(默认值);}
“do”{count();返回(do);}
“double”{count();返回(double);}
“else”{count();return(else);}
“枚举”{count();返回(枚举);}
“extern”{count();返回(extern);}
“float”{count();返回(float);}
对于“{count();return(for);}”
“goto”{count();返回(goto);}
如果“{count();return(if);}”
“int”{count();返回(int);}
“long”{count();返回(long);}
“寄存器”{count();返回(寄存器);}
return“{count();return(return);}
“short”{count();返回(short);}
“已签名”{count();返回(已签名);}
“sizeof”{count();返回(sizeof);}
“static”{count();返回(static);}
“struct”{count();返回(struct);}
开关{count();返回(开关);}
“typedef”{count();返回(typedef);}
“联合”{count();返回(联合);}
“unsigned”{count();返回(unsigned);}
“void”{count();返回(void);}
“volatile”{count();返回(volatile);}
while“{count();return(while);}
{五十} ({L}{D})*{count();return(check_type());}
0[xX]{H}+{IS}?{count();返回(常量);}
0{D}+{IS}?{count();返回(常量);}
{D} +{IS}?{count();返回(常量);}
L?'(\\.\\\\\'])+'{count();返回(常量);}
{D} +{E}{FS}?{count();返回(常量);}
{D} *“{D}+({E})?{FS}?{count();返回(常量);}
{D} +“{D}*({E})?{FS}?{count();返回(常量);}
L?\“(\\.\\[^\\”])*\“{count();返回(字符串\文字);}”
“…”{count();返回(省略号);}
“>>=”{count();return(RIGHT_ASSIGN);}
“{count();return(RIGHT_OP);}
"
简单地说,是否可以组合两个或多个lex文件并作为输入(Bison(.y)文件从中读取令牌)

lex
(或
flex
)实用程序基于一个输入文件为扫描器函数生成C源代码。如果通过它运行两个独立的输入,那么将得到两个独立的函数。使用某些版本的
lex
和一些额外的工作,您可以使这些函数具有不同的名称,但是您无法成功地使它们扫描相同的输入流,因为它们维护自己的输入缓冲区和扫描状态信息,因此它们会相互干扰

您还不能将
lex
输入文件连接起来,将它们合并为一个文件,至少因为每个文件包含两个或三个部分,它们的相对顺序非常重要。连接两个
lex
输入文件不会产生有效的
lex
输入文件

您可以将两个
lex
输入文件逐节合并为一个文件,但如果涉及的文件非常复杂,则此练习最多也很困难。仅仅将每对相应部分的内容组合起来就可以生成一个有效的
lex
输入文件,但它不太可能完成您想要的工作

如果您有一个第三方
lex
输入,它描述了与您想要的类似的扫描规则,并且您希望以某种方式重用该代码,那么您最好的选择可能是接受该输入并修改它以适合您。这可能很棘手,因为您首先需要很好地理解现有输入,然后才能根据需要修改它。但无论如何,要合并两个
lex
输入,您都需要这些和更多

或者,您可以简单地将现有文件作为编写自己的文件的灵感。研究它,从中收集关于如何实现类似目标的想法,等等。。这是我推荐自己的选择。通过这种方式,您可能会学到更多,并且您可能会更好地理解生成的代码

简单地说,是否可以组合两个或多个lex文件并作为输入(Bison(.y)文件从中读取令牌)

lex
(或
flex
)实用程序基于一个输入文件为扫描器函数生成C源代码。如果通过它运行两个独立的输入,那么将得到两个独立的函数。使用某些版本的
lex
和一些额外的工作,您可以使这些函数具有不同的名称,但是您无法成功地使它们扫描相同的输入流,因为它们维护自己的输入缓冲区和扫描状态信息,因此它们会相互干扰

您还不能将
lex
输入文件连接起来,将它们合并为一个文件,至少因为每个文件包含两个或三个部分,它们的相对顺序非常重要。连接两个
lex
输入文件不会产生有效的

D           [0-9]
L           [a-zA-Z_]
H           [a-fA-F0-9]
E           [Ee][+-]?{D}+
FS          (f|F|l|L)
IS          (u|U|l|L)*


%{

/* this scanner sourced from: http://www.lysator.liu.se/c/ANSI-C-grammar-l.html */

void count();
#include <stdio.h>
#include <string.h>
#define YYSTYPE void *

%}


%%
"/*"            { comment(); }

"auto"          { count(); return(AUTO); }
"break"         { count(); return(BREAK); }
"case"          { count(); return(CASE); }
"char"          { count(); return(CHAR); }
"const"         { count(); return(CONST); }
"continue"      { count(); return(CONTINUE); }
"default"       { count(); return(DEFAULT); }
"do"            { count(); return(DO); }
"double"        { count(); return(DOUBLE); }
"else"          { count(); return(ELSE); }
"enum"          { count(); return(ENUM); }
"extern"        { count(); return(EXTERN); }
"float"         { count(); return(FLOAT); }
"for"           { count(); return(FOR); }
"goto"          { count(); return(GOTO); }
"if"            { count(); return(IF); }
"int"           { count(); return(INT); }
"long"          { count(); return(LONG); }
"register"      { count(); return(REGISTER); }
"return"        { count(); return(RETURN); }
"short"         { count(); return(SHORT); }
"signed"        { count(); return(SIGNED); }
"sizeof"        { count(); return(SIZEOF); }
"static"        { count(); return(STATIC); }
"struct"        { count(); return(STRUCT); }
"switch"        { count(); return(SWITCH); }
"typedef"       { count(); return(TYPEDEF); }
"union"         { count(); return(UNION); }
"unsigned"      { count(); return(UNSIGNED); }
"void"          { count(); return(VOID); }
"volatile"      { count(); return(VOLATILE); }
"while"         { count(); return(WHILE); }

{L}({L}|{D})*       { count(); return(check_type()); }

0[xX]{H}+{IS}?      { count(); return(CONSTANT); }
0{D}+{IS}?      { count(); return(CONSTANT); }
{D}+{IS}?       { count(); return(CONSTANT); }
L?'(\\.|[^\\'])+'   { count(); return(CONSTANT); }

{D}+{E}{FS}?        { count(); return(CONSTANT); }
{D}*"."{D}+({E})?{FS}?  { count(); return(CONSTANT); }
{D}+"."{D}*({E})?{FS}?  { count(); return(CONSTANT); }

L?\"(\\.|[^\\"])*\" { count(); return(STRING_LITERAL); }

"..."           { count(); return(ELLIPSIS); }
">>="           { count(); return(RIGHT_ASSIGN); }
"<<="           { count(); return(LEFT_ASSIGN); }
"+="            { count(); return(ADD_ASSIGN); }
"-="            { count(); return(SUB_ASSIGN); }
"*="            { count(); return(MUL_ASSIGN); }
"/="            { count(); return(DIV_ASSIGN); }
"%="            { count(); return(MOD_ASSIGN); }
"&="            { count(); return(AND_ASSIGN); }
"^="            { count(); return(XOR_ASSIGN); }
"|="            { count(); return(OR_ASSIGN); }
">>"            { count(); return(RIGHT_OP); }
"<<"            { count(); return(LEFT_OP); }
"++"            { count(); return(INC_OP); }
"--"            { count(); return(DEC_OP); }
"->"            { count(); return(PTR_OP); }
"&&"            { count(); return(BOOL_AND_OP); }
"||"            { count(); return(BOOL_OR_OP); }
"<="            { count(); return(LE_OP); }
">="            { count(); return(GE_OP); }
"=="            { count(); return(EQ_OP); }
"!="            { count(); return(NE_OP); }
";"         { count(); return(SEMICOLON); }
("{"|"<%")      { count(); return(OCB); }
("}"|"%>")      { count(); return(CCB); }
","         { count(); return(COMMA); }
":"         { count(); return(COLON); }
"="         { count(); return(EQU); }
"("         { count(); return(OP); }
")"         { count(); return(CP); }
("["|"<:")      { count(); return(LBRACKET); }
("]"|":>")      { count(); return(RBRACKET); }
"."         { count(); return(PERIOD); }
"&"         { count(); return(AND_OP); }
"!"         { count(); return(BANG); }
"~"         { count(); return(TILDE); }
"-"         { count(); return(MINUS); }
"+"         { count(); return(ADD); }
"*"         { count(); return(STAR); }
"/"         { count(); return(SLASH); }
"%"         { count(); return(PERCENT); }
"<"         { count(); return(LT_OP); }
">"         { count(); return(GT_OP); }
"^"         { count(); return(CIRCUMFLEX); }
"|"         { count(); return(OR_OP); }
"?"         { count(); return(QUESTIONMARK); }

[ \t\v\n\f]     { count(); }
.           { /* ignore bad characters */ }

%%


comment()
{
    char c, c1;

loop:
    while ((c = input()) != '*' && c != 0)
      /*putchar(c)*/;

    if ((c1 = input()) != '/' && c != 0)
    {
        unput(c1);
        goto loop;
    }

    if (c != 0)
      /*putchar(c1)*/;
}


int column = 0;

void count()
{
    int i;

    for (i = 0; yytext[i] != '\0'; i++)
        if (yytext[i] == '\n')
            column = 0;
        else if (yytext[i] == '\t')
            column += 8 - (column % 8);
        else
            column++;

    /*ECHO*/;
}


int check_type()
{
/*
* pseudo code --- this is what it should check
*
*   if (yytext == type_name)
*       return(TYPE_NAME);
*
*   return(IDENTIFIER);
*/

/*
*   it actually will only return IDENTIFIER
*/

    return(IDENTIFIER);
}

%{

#include "c.l"
#include <stdio.h>
#include "parser_test.tab.h"

%}


%%


"{"                     { yylval.str = strdup(yytext); return OCB; }
"}"                     { yylval.str = strdup(yytext); return CCB; }

/* MANY MORE TOKENS TO ADD */

%%

%{

#include    <stdio.h>
#include "lex.yy.c"
int yyerror ();
int yylineno;
char* a;
char* b;

%}

%union {
    char *str;
}

%define parse.error verbose

%type <str> INT CONST CONSTANT RETURN IDENTIFIER ADD EQU PTR SEMICOLON OP CP OCB CCB COMMA

%token INT CONST CONSTANT RETURN IDENTIFIER ADD EQU PTR SEMICOLON NUMBER OP CP OCB CCB COMMA

%start Program

%%

Program:                outStatements
                        functions
                        ;

functions:              function
                        | functions function
                        ;

function:               INT IDENTIFIER OP parametersList CP OCB statementList CCB  { a=$2; printf("\nFunction Defined : %s\n", $2); }
                        ;

parametersList:         /*empty*/
                        | parameters
                        ;

parameters:             parameter
                        | parameters COMMA parameter
                        ;

parameter:              INT IDENTIFIER       { printf("\nPARAMETER NAME: %s\nPARAMETER INT :%s\n", $2, $1); }
                        ;

statementList:          /*empty*/
                        | statements 
                        ;

statements:             statement
                        | statements statement
                        ;

statement:              RETURN IDENTIFIER ADD IDENTIFIER SEMICOLON
                        | INT IDENTIFIER COMMA IDENTIFIER EQU CONSTANT COMMA IDENTIFIER EQU CONSTANT SEMICOLON
                        | IDENTIFIER EQU IDENTIFIER OP IDENTIFIER COMMA IDENTIFIER CP SEMICOLON     { b = $3; }
                        ;

outStatements:          outStatement
                        | outStatements outStatement
                        ;

outStatement:           INT PTR IDENTIFIER SEMICOLON
                        | CONST INT IDENTIFIER EQU CONSTANT SEMICOLON
                        ;

%%

int main (int argc, char * argv[]) 
{
    yyin = fopen(argv[1], "r");
    int err_code = yyparse();
    if (err_code == 0) 
    {   
        printf("\nFunction called : '%s' from '%s'\n", b, a);
        printf("\nParsing Done !!!\n");
    } 
    else 
    {
        printf("\nUNSUCCESSFUL ....\n");
    }
    fclose(yyin);
    return 0;
}

int yyerror (char* s) 
{
    fprintf(stderr, "\nError on Line: %d :: %s\n" , yylineno, s);
}

int yywrap()
{
    return 1;
}