我想使用Flex& amp;创建一个模板引擎解析器。野牛。问题是我只想解析{{..}}和$ {..}中的表达式。
模板可以是带有嵌入标记的任意文本,代码如下:
</table:table-row>
{{$(/report/row.xml).embed()}}
{{$(//Accreditation/AccreditationDocument/Report).each(fragment(row) """
<table:row>
<table:table-cell office:value-type="string" office:string-value="${row["name"]}" />
</table:row>
""")}}
<table:table-row table:number-rows-repeated="1048574" table:style-name="ro1">
<table:table-cell table:number-columns-repeated="16384"/>
</table:table-row>
</table:table>
答案 0 :(得分:1)
我自己找到了解决方案。 Flex有一个名为Start Conditions的功能。
以下是lexer.l
代码,仅从{{}}返回令牌。其他文本以GENERAL_BODY返回。
%{
#include "bisondef.h"
%}
%option reentrant noyywrap never-interactive nounistd
%option bison-bridge
WS [ \t\n]+
ID [A-z_][[:alnum:]]*
%x stmt
%%
int stmt_level = 0;
"{{" { stmt_level = 0; BEGIN(stmt); }
<stmt>{
"{{" { stmt_level++; printf("stmt {{\n"); }
"}}" {
if (0 == stmt_level) BEGIN(INITIAL);
else stmt_level--;
}
{WS} {}
[0-9]+ { yylval->num = atoi(yytext); return NUM; }
"+"|"-"|"*"|"/"|"("|")" { return *yytext; }
";" { return SEMICOLON; }
{ID} { yylval->str = strdup(yytext); return ID; }
}
. {
yylval->str = strdup(yytext);
return GENERAL_BODY;
}
%%
int yyerror(const char *msg) { fprintf(stderr,"Error: %s\n",msg); return 0; }