加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Flex开发解析器示例(1)

发布时间:2020-12-15 04:56:18 所属栏目:百科 来源:网络整理
导读:? ? 通用单据处理支持主表修改 ,对于复杂数据类型,当仅主表数据的部分数据项改变时只同步这些已变化的字段,减少不必要的开销。 接口表记录变更的方式是记录每个变更字段的当前值。 每个字段的变更描述格式为:字段名 =[值长度,属性,值]。 多个字段之间用逗号

??

通用单据处理支持主表修改,对于复杂数据类型,当仅主表数据的部分数据项改变时只同步这些已变化的字段,减少不必要的开销。
接口表记录变更的方式是记录每个变更字段的当前值。
每个字段的变更描述格式为:字段名=[值长度,属性,值]。
多个字段之间用逗号(",")分隔。

此格式可以避免转义问题(如值内容中出现"],"的情况).
属性目前用于区分是否是base64编码,这可用于binary类型字段的支持,可扩展。

字段类型在同步到目标库时根据数据库的结构信息决定,不需要在此指定。

?

以下为用Flex开发的解析变更字段表达式的解析器代码。

?

/* name: fld_list.y */


%option noyywrap
%x S_FIELDNAME
%x S_EQUEL
%x S_DATA_LEN
%x S_DATA_LEN2
%x S_DATA_PROP
%x S_DATA_PROP2
%x S_FIELDVAL
%x S_END

%{
#include <string.h>
#include <stdlib.h>
char *fld_name; /*字段名称
*/
unsigned int data_len = 0; /* 字段值长度
*/
int data_prop = 0; /*字段属性
*/
char *data_buffer; /* 字段值 */

#define MAX_FIELD_NAME_LEN? 64

struct stFieldInfo {
?char *name;
?unsigned int len;
?int prop;
?char *buffer;
?
?struct stFieldInfo *next;
};

struct stFieldInfo? *field_list = 0;
struct stFieldInfo? *last_field = 0;
int add_field(struct stFieldInfo *fld);
%}


%%
[A-Za-z_]+([A-Za-z_]|[0-9])* {
?fld_name = strdup(yytext);
?BEGIN S_FIELDNAME;
}

<S_FIELDNAME>([" "t])*"="([" "t])*[([" "t])* {
?BEGIN S_EQUEL;
}

<S_EQUEL>[0-9]* {
?data_len = atoi(yytext);
?BEGIN S_DATA_LEN;
}
<S_DATA_LEN>([" "t])*","([" "t])* {
?BEGIN S_DATA_LEN2;?
}

<S_DATA_LEN2>[0-9]* {
?data_prop = atoi(yytext);
?BEGIN S_DATA_PROP;
}

<S_DATA_PROP>([" "t])*","([" "t])* {
?BEGIN S_DATA_PROP2;?
}

<S_DATA_PROP2>. {
?int c;
?int len = 0;
?char *p;
?data_buffer = malloc(data_len+1);
?data_buffer[0] = yytext[0];
?p = data_buffer;
?p++;
?len++;
?while(len<data_len&&(c=input())&&c!=EOF) {
??*p = c;
??p++;
??len++;
?}
?if (c==EOF||len<data_len)
??yyterminate();
?data_buffer[len] = '';

?BEGIN S_FIELDVAL;
}

<S_FIELDVAL>([" "t])*]([" "t])*[,]? {
?struct stFieldInfo *fld = malloc(sizeof(struct stFieldInfo));
?fld->name = fld_name;
?fld->len = data_len;
?fld->prop = data_prop;
?fld->buffer = data_buffer;
?fld->next = 0;
?add_field(fld);
?
?BEGIN INITIAL;
}
. { ECHO; }

%%

int add_field(struct stFieldInfo *fld) {
??if (field_list==0) {
???field_list = fld;
???last_field = fld;
???return 0;
??}
??last_field->next = fld;
??last_field = fld;

??return 0;??
}

int print_fld_list() {
?int fld_num = 0;
?struct stFieldInfo *fld = field_list;
?while(fld!=0) {
??printf("name:%s,len=%d,prop=%d,data=%s.n",fld->name,fld->len,fld->prop,fld->buffer);
??fld_num++;

??fld = fld->next;
?}
?printf("field_num:%d.n",fld_num);

?return 0;
}

int main()
{
?char *str_input = "f123=[3,3,abc],f23=[5,1,xxxxx]";

?field_list = 0;
?last_field = 0;
?yy_scan_string(str_input);

?yylex();

?print_fld_list();

?getch();

?return 0;
}

?

?

?

此示例的输出为:

name:f123,len=3,prop=3,data=abc.
name:f23,len=5,prop=1,data=xxxxx.
field_num:2.

?

上述代码是不可重入的。

?

修改代码以支持多线程环境使用。修改后的代码如下(FLEX 2.5.35版本):

/* name: fld_list.y */

?

%option reentrant

%option noyywrap

%option extra-type="struct stWorkData*"

?

%x S_FIELDNAME

%x S_EQUEL

%x S_DATA_LEN

%x S_DATA_LEN2

%x S_DATA_PROP

%x S_DATA_PROP2

%x S_FIELDVAL

%x S_END

?

%{

?

#define YY_NO_UNISTD_H

#include <string.h>

#include <stdlib.h>

?

?

#define MAX_FIELD_NAME_LEN? 64

?

struct stFieldInfo {

?????? char *name;

?????? unsigned int len;

?????? int prop;

?????? char *buffer;

??????

?????? struct stFieldInfo *next;

};

?

struct stWorkData {

?????? char *fld_name; /*字段名称 */

?????? unsigned int data_len; /* 字段值长度*/

?????? int data_prop; /*字段属性*/

?????? char *data_buffer; /* 字段值 */

?????? struct stFieldInfo? *field_list;

?????? struct stFieldInfo? *last_field;

};

?

int add_field(struct stWorkData *wkdata,struct stFieldInfo *fld);

%}

?

FLDNAME [A-Za-z_]+([A-Za-z_]|[0-9])*

DELIM ([" "t])*

NUMBERS [0-9]*

%%

{FLDNAME} {

?????? yyextra->fld_name = strdup(yyget_text(yyscanner));

?????? BEGIN S_FIELDNAME;

}

?

<S_FIELDNAME>{DELIM}"="{DELIM}[{DELIM} {

?????? BEGIN S_EQUEL;

}

?

<S_EQUEL>{NUMBERS} {

?????? yyextra->data_len = atoi(yyget_text(yyscanner));

?????? BEGIN S_DATA_LEN;

}

<S_DATA_LEN>{DELIM}","{DELIM} {

?????? BEGIN S_DATA_LEN2;??????

}

?

<S_DATA_LEN2>{NUMBERS}? {

?????? yyextra->data_prop = atoi(yyget_text(yyscanner));

?????? BEGIN S_DATA_PROP;

}

?

<S_DATA_PROP>{DELIM}","{DELIM} {

?????? BEGIN S_DATA_PROP2;????

}

?

<S_DATA_PROP2>. {

?????? int c;

?????? unsigned int len = 0;

?????? char *p;

?????? yyextra->data_buffer = malloc(yyextra->data_len+1);

?????? yyextra->data_buffer[0] = yyget_text(yyscanner)[0];

?????? p = yyextra->data_buffer;

?????? p++;

?????? len++;

?????? while(len<yyextra->data_len&&(c=input(yyscanner))&&c!=EOF) {

????????????? *p = c;

????????????? p++;

????????????? len++;

?????? }

?????? if (c==EOF||len<yyextra->data_len)

????????????? yyterminate();

?????? yyextra->data_buffer[len] = '';

?

?????? BEGIN S_FIELDVAL;

}

?

<S_FIELDVAL>{DELIM}]{DELIM}[,]? {

?????? struct stFieldInfo *fld = malloc(sizeof(struct stFieldInfo));

?????? fld->name = yyextra->fld_name;

?????? fld->len = yyextra->data_len;

?????? fld->prop = yyextra->data_prop;

?????? fld->buffer = yyextra->data_buffer;

?????? fld->next = 0;

?????? add_field(yyextra,fld);

??????

?????? BEGIN INITIAL;

}

. { ECHO; }

?

%%

?

int add_field(struct stWorkData *wkdata,struct stFieldInfo *fld) {

????????????? if (wkdata->field_list==0) {

???????????????????? wkdata->field_list = fld;

???????????????????? wkdata->last_field = fld;

???????????????????? return 0;

????????????? }

????????????? wkdata->last_field->next = fld;

????????????? wkdata->last_field = fld;

?

????????????? return 0;?????????????

}

?

int print_fld_list(struct stWorkData *wkdata) {

?????? int fld_num = 0;

?????? struct stFieldInfo *fld = wkdata->field_list;

?????? while(fld!=0) {

????????????? printf("name:%s,fld->buffer);

????????????? fld_num++;

?

????????????? fld = fld->next;

?????? }

?????? printf("field_num:%d.n",fld_num);

?

?????? return 0;

}

?

int main()

{

??? yyscan_t scanner;

?????? struct stWorkData wkdata;

?

?????? char *str_input = "f123=[3,xxxxx]";

?

?????? wkdata.data_len = 0;

?????? wkdata.data_prop = 0;

?????? wkdata.field_list = 0;

?????? wkdata.last_field = 0;

?

??? yylex_init ( &scanner );

?????? yylex_init_extra( &wkdata,&scanner );

?????? yy_scan_string(str_input,scanner);

?

??? yylex ( scanner );

??? yylex_destroy ( scanner );

?

?????? print_fld_list(&wkdata);

?

?????? getch();

?

?????? return 0;

}

?

???

  • ? FLEX&Bison参考资料:

Lexical Analysis With Flex

http://flex.sourceforge.net/manual/

?

Bison Quick Tutorial

http://gps.nju.edu.cn:88/mediawiki/index.php/Bison_Quick_Tutorial

?

?

Flex 2.5.35 and Win32 / Visual C++

http://www.thebinaryidiot.com/archives/2011/01/29/flex-2-5-35-and-win32-visual-studio-cpp/

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读