问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

在visual studio 2010环境下使用flex和bison开发C编译器后,怎样对txt文本中的C源程序经行编译?

发布网友 发布时间:2022-04-14 16:48

我来回答

3个回答

懂视网 时间:2022-04-14 21:10

由于老师要求,最近在做oceanbase存储过程的实现,在oceanbase 0.4以前是不支持存储过程的。实现的主要步骤主要包括 1、语法解析 2、词法解析 3、具体执行语法树的步骤 现在先来说说语法解析吧,在这一块主要是使用的flex( 词法分析器生成工具) 和bison(语

由于老师要求,最近在做oceanbase存储过程的实现,在oceanbase 0.4以前是不支持存储过程的。实现的主要步骤主要包括

1、语法解析

2、词法解析

3、具体执行语法树的步骤

现在先来说说语法解析吧,在这一块主要是使用的flex( 词法分析器生成工具) 和bison(语法分析器生成器) 这两个是对用户输入的存储过程语句进行解析的

来具体说说该怎么实现对sql语句的分析吧

1、首先建立一个lex的文件

%option noyywrap nodefault yylineno case-insensitive

%{

#include "prosql.tab.hpp"
#include 
#include 
#include 
#include 
#include 
//YYSTYPE yylval;
int oldstate;
extern "C" int yylex();
//extern "C" int yyparse();
extern "C" void yyerror(const char *s, ...);
extern char globalInputText[10000];
extern int readInputForLexer( char *buffer, int *numBytesRead, int maxBytesToRead );
#undef YY_INPUT
#define YY_INPUT(b,r,s) readInputForLexer(b,&r,s)
%}

%x COMMENT

%%

CREATE		{ return CREATE; }
PROCEDURE	{ return PROCEDURE; }
SQL		{ return SQL; }

DECLARE		{ return DECLARE; }
SET		{ return SET; }
BEGIN		{ return BEGINT; }
END		{ return END; }

INT		{ return INT; }
VARCHAR		{ return VARCHAR; }
DATE		{ return DATE; }
TIME		{ return TIME; }
DOUBLE		{ return DOUBLE; }

IF		{ return IF; }
THEN		{ return THEN; }
ELSE		{ return ELSE; }
ENDIF		{ return ENDIF; }
FOR		{ return FOR; }
WHEN		{ return WHEN; }
WHILE		{ return WHILE; }


[0-9]+	{ yylval.strval = strdup(yytext);/*printf("number=%s
",yylval.strval);*/ return INTNUM; }/*number*/

[0-9]+"."[0-9]* |
"."[0-9]+	|
[0-9]+E[-+]?[0-9]+	|
[0-9]+"."[0-9]*E[-+]?[0-9]+ |
"."[0-9]*E[-+]?[0-9]+	{ yylval.strval = strdup(yytext);/*printf("float=%s
",yylval.strval);*/ return APPROXNUM; }/*double*/

TRUE	{ yylval.strval = "1";/*printf("bool=%s
",yylval.strval);*/ return BOOL; }/*bool*/

FALSE	{ yylval.strval = "0";/*printf("bool=%s
",yylval.strval);*/ return BOOL; }/*bool*/

'(\.|''|[^'
])*'	|
"(\.|""|[^"
])*" {
				char *temp = strdup(yytext); 
				yylval.strval = strdup(yytext);

				//GetCorrectString(yylval.strval, temp);
				
				/*printf("string=%s
",yylval.strval);*/
				return STRING;
			}/*string*/
'(\.|[^'
])*$		{ yyerror("Unterminated string %s", yytext); }
"(\.|[^"
])*$		{ yyerror("Unterminated string %s", yytext); }


X'[0-9A-F]+' | 
0X[0-9A-F]+ 	{ yylval.strval = strdup(yytext); return STRING; }


0B[01]+ |
B'[01]+' { yylval.strval = strdup(yytext); return STRING; }


[-+&~|^/%*(),.;!] { return yytext[0]; }

"&&"	{ return ANDOP; }
"||"	{ return OR; }

"<"	{ yylval.subtok = 1; return COMPARISON; }
">"	{ yylval.subtok = 2; return COMPARISON; }
"!="	|
"<>"	{ yylval.subtok = 3; return COMPARISON; }
"="	{ yylval.subtok = 4; return COMPARISON; }
"<="	{ yylval.subtok = 5; return COMPARISON; }
">="	{ yylval.subtok = 6; return COMPARISON; }
"<=>"	{ yylval.subtok = 12; return COMPARISON; }

"<<"	{ yylval.subtok = 1; return SHIFT; }
">>"	{ yylval.subtok = 2; return SHIFT; }


[A-Za-z][A-Za-z0-9_]*	{ yylval.strval = strdup(yytext);
			 /*printf("name 1=%s
",yylval.strval);*/
    return NAME; }
`[^`/\.
]+`  { yylval.strval = strdup(yytext+1);
			 /*printf("name 2=%s
",yylval.strval);*/
    yylval.strval[yyleng-2] = 0;
    return NAME; }

`[^`
]*$  { yyerror("unterminated quoted name %s", yytext); }


@[0-9a-z_.$]+ |
@"[^"
]+" |
@`[^`
]+` |
@'[^'
]+' { yylval.strval = strdup(yytext+1); return USERVAR; }

@"[^"
]*$ { yyerror("unterminated quoted user variable %s", yytext); }
@`[^`
]*$ { yyerror("unterminated quoted user variable %s", yytext); }
@'[^'
]*$ { yyerror("unterminated quoted user variable %s", yytext); }

":=" { return ASSIGN; }

#.*		;
"--"[ 	].*	;

"/*"  { oldstate = YY_START; BEGIN COMMENT; }
"*/" { BEGIN oldstate; }
.|
 ;
<> { yyerror("unclosed comment"); }


[ 	
]  /* white space */
.  { yyerror("mystery character '%c'", *yytext); }

%%

这一部分呢就是对 每个我们自定义的满足正则的识别 

接下来是对词的语法识别

%{
#include 
#include 
#include 
#include 
#include 
char * parsetreeroot=NULL;
extern "C" int yylex();
extern "C" int yyparse();
extern "C" void yyerror(const char *s, ...);
char globalInputText[10000];
int globalReadOffset;
int readInputForLexer( char *buffer, int *numBytesRead, int maxBytesToRead );
char * mystrcat(char *s1,char *s2)
{
	char *p1=(char *)malloc(strlen(s1)+strlen(s2)+1);
	strcpy(p1,s1);
	strcat(p1,s2);
	return p1;
}
%}
%locations
%union {
	int intval;		
	double floatval;	
	char *strval;
	int subtok;
}
%token  NAME
%token  STRING
%token  INTNUM
%token  BOOL
%token  APPROXNUM
%token  USERVAR

%type  stmt_root create_stmt para_list definition data_type pro_block pro_parameters declare_list set_list 
%type  assign_var pro_body pro_stmt_list sql_stmt expr



%right ASSIGN
%left OR
%left XOR
%left ANDOP

%left NOT '!'
%left BETWEEN
%left  COMPARISON /* = <> < > <= >= <=> */
%left '|'
%left '&'
%left  SHIFT /* << >> */
%left '+' '-'
%left '*' '/' '%' MOD
%left '^'

%token CREATE
%token PROCEDURE
%token PRONAME
%token DECLARE
%token SET
%token BEGINT
%token END
%token SQL

%token INT
%token VARCHAR
%token DATE
%token TIME
%token DOUBLE

%token IF
%token NOT
%token EXISTS
%token THEN
%token ELSE
%token ENDIF
%token FOR
%token WHEN
%token WHILE
%start stmt_root
%%

stmt_root: create_stmt pro_block { $$=mystrcat($1,$2); parsetreeroot=$$;}
;
create_stmt: CREATE PROCEDURE NAME '(' para_list ')' 
		{
			char *temp=mystrcat("create procedure ",$3);
			temp=mystrcat(temp,"(");
			temp=mystrcat(temp,$5);
			$$=mystrcat(temp,")(create)
");
		}
;
/*
opt_if_not_exists:	 { $$ = 0; } 
 | IF NOT EXISTS  { $$ = 1; } 
 ;
*/
para_list: definition { $$=$1; }
|definition ',' para_list 
		{	
			
			char *temp=mystrcat($1,",");
			$$=mystrcat(temp,$3); 
		}
;
definition: USERVAR data_type 
		{	
			
			char *temp=mystrcat($1," ");
			$$=mystrcat(temp,$2);
			
		}
;

data_type:
 DATE 					{$$="date"; }
 | TIME					{$$="time"; }
 | VARCHAR '(' INTNUM ')' 			{$$="varchar"; }
 | INT 					{$$="int"; }
 | DOUBLE 					{$$="double"; }	
 ;

pro_block: BEGINT pro_parameters pro_body END 
		{ 
			char *temp=mystrcat("begin
",$2);
			temp=mystrcat(temp,"");
			temp=mystrcat(temp,$3);
			$$=mystrcat(temp,"end");
			//printf("pro_body %s
",$3);
		}
;

pro_parameters: declare_list ';' { $$=mystrcat($1,";(declare)
");}
|pro_parameters declare_list ';' 
		{ 
			char *temp=mystrcat($1,$2);
			$$=mystrcat(temp,";(declare)
");
		}
|pro_parameters set_list ';' 
		{
	 		char *temp=mystrcat($1,$2);
			$$=mystrcat(temp,";(set)
");
		}
;

declare_list:
|DECLARE definition 
		{
			$$=mystrcat("declare ",$2);
		}
|declare_list ',' definition 
		{ 
			char *temp=mystrcat($1,",");
			$$=mystrcat(temp,$3); 
		}
;

set_list:
|SET assign_var 
		{
			$$=mystrcat("set ",$2); 
		}
| set_list ',' assign_var 
		{	
			char *temp=mystrcat($1,",");
			$$=mystrcat(temp,$3); 
		}
;

assign_var : USERVAR COMPARISON expr
		{ 	
			char *temp=mystrcat($1,"=");
			$$=mystrcat(temp,$3); 
		}
;

expr: NAME  { $$=$1;}
 | STRING { $$=$1;}
 | INTNUM { $$=$1;}
 | APPROXNUM 	 { $$=$1;}	
 | BOOL  { $$=$1;}
 ;

pro_body : pro_stmt_list { $$=$1; }
;
pro_stmt_list: sql_stmt {$$=$1; }
|pro_stmt_list sql_stmt 
		{
			$$=mystrcat($1,$2);
		}
;
sql_stmt: 
|SQL NAME ';' { $$=mystrcat($2,";(sql)
");}
;
%%
/*
int main(int argc, char* argv[])
{
	yyparse();
}*/
int readInputForLexer( char *buffer, int *numBytesRead, int maxBytesToRead ) {
	int numBytesToRead = maxBytesToRead;
	int bytesRemaining = strlen(globalInputText)-globalReadOffset;
	int i;
	if ( numBytesToRead > bytesRemaining ) { numBytesToRead = bytesRemaining; }
	for ( i = 0; i < numBytesToRead; i++ ) {
		buffer[i] = globalInputText[globalReadOffset+i];
	}
	*numBytesRead = numBytesToRead;
	globalReadOffset += numBytesToRead;
	return 0;
}
void yyerror(const char *s, ...)
{
 fprintf(stderr, "error: %s
", s);
}
void zzerror(const char *s, ...)
{
	extern int yylineno;

	va_list ap;
	va_start(ap, s);

	fprintf(stderr, "%d: error: ", yylineno);
	vfprintf(stderr, s, ap);
	fprintf(stderr, "
");
}

int yywrap(void)
{
 return 1;
}
char* getsql()
{	
	return parsetreeroot;
}

这部分就是对上一个识别出来的词 进行顺序上的确定,构成一个完整的语法

这些需要在linux环境下进行调试

bison -d 文件名

flex 文件名

热心网友 时间:2022-04-14 18:18

作为移植版的 flex & bison for windows 似乎有问题,和正统的Flex/Bison工具输出有差异。运行的话,如果你有用main(int argc, char **argv)进行指定的话就按照你的格式进行调用,否则就用重定向工具:compiler.exe < code.txt

热心网友 时间:2022-04-14 19:36

www.baidu.com
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
请问我的网络一天了找个部门到现在没有解决请问我上哪投诉? 计算机具备哪几种功能? 计算机有哪些功能是什么 歌词中有丑姑娘的歌曲 驾照不年审会怎样 没开过车驾照年审会通过吗 本来白色的背心放入洗衣机清洗后就变成有黑色斑点 其他一起洗的衣物... ...衣服颜色保持鲜艳(主要是白色衣服洗几次感觉就有点颜色不亮丽了... 为什么登陆lol会叫你解绑 小姨子告诉我说,炒菜时记住这4个小技巧,就是比别人做的好吃 能治好强直性脊柱炎吗或控制病情发展【强直性脊柱炎】 乳房里面有一个大硬块是怎么回事 乳房内有硬块,硬块有大小怎么办? 乳房里面有个大硬块怎么办? 乳房有硬块,该怎么调理 为什么胖的女人的裤子在热天,裤子下面会湿掉? 1米7 54公斤为什么从最胖瘦到这个体重,裤子都垂下来了,跑步的时候裤子不停往下掉 穿裤子容易往下掉是因为太胖了吗? 四川学IT哪里好? 四川成都IT学校有哪些 塞下秋来风景异,衡阳雁去无留意此句以离开衡阳的大雁径去不留,反衬出遍地的荒凉.这句话对吗 sr3200能代换sr320吗? 道不尽这一世遍地的荒凉,夜未央看见地久天长是什么歌? 你有历劫俏佳人? HBR3100二极管和B310二极管可以互用吗? HBR3200与sR3200通用吗? 魔幻背景下的废土应该是什么样子呢? hbr3150二极管参数代换 ()()荒芜 下一站,人生 作文 形容荒原的词语 裤子上有粘胶怎么去掉 请问有谁知道怎样进行网上购物?听说好像要先开通网银,能具体解释下吗?还有支付宝和淘宝账号是什么? 淘宝帐户和网银帐户一样吗? 刚开通网银买衣服要淘宝账号是什么 衣服有瑕疵客服要怎么处理 开淘宝帐户的号码是不是要跟开网银留的号码一样啊 卖衣服时顾客说衣服有质量问题,比如说勾丝呀什么的,该怎么办呀,会要我赔吗? 在淘宝上买东西用的网银账号是13位还是 在淘宝买的衣服有瑕疵 想让卖家退一半的钱给我 衣服我留着 能实现吗? 衣服卖出去两个月了有质量问题咋处理? 网银和网购的问题 我在闲鱼卖二手衣服,别人收到了说我衣服有小瑕疵要退货,我不想退。别人如果找淘宝维权我会怎么样 新买的衣服发现有瑕疵,但不影响美观,有必要换吗 新衣服买回有瑕疵正常吗 我在淘宝买了两件衣服,卖家说都有瑕疵让我退款并且不发货,我该怎么办? 衣服有质量问题商家怎么赔偿 淘宝买到衣服瑕疵品但是过水才发现问题怎么维权? 健身教练老是说你长的漂亮?是敷衍的夸你还是对你有意思?我比他小,还说,我知道你年纪小,叫我小姑娘 健身教练赠言 蟑螂怕什么?怎么消灭它啊!!