如何使用Flex在上下文中扫描令牌?

时间:2011-09-29 06:35:22

标签: bison lex flex-lexer

我想使用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>

1 个答案:

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