C 如何组合两个flex(.l)文件并在一个Bison文件(.y)中使用它们?
我对Bison/Flex很陌生。我创建了一个程序来读取c文件并识别定义的函数。成功了。我想知道,我如何使用来自另一个开源的预定义lex文件,并将其令牌用于我的lex文件并生成输出 简单地说,是否可以组合两个或多个lex文件并作为输入(Bison(.y)文件从中读取令牌) 请推荐我。 谢谢 为了清楚起见,这里有一个样本 c.l(来源-->)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
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;
}