2011-09-29 24 views
2

我想使用Flex & Bison創建模板引擎的解析器。問題是我只想解析{{..}}和$ {..}中的表達式。如何使用Flex僅在上下文中掃描令牌?

模板可以用代碼嵌入令牌這樣的任意文本:我已經找到了解決自己

 </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> 

回答

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; }