【问题标题】:How to scan tokens only within context using Flex?如何使用 Flex 仅在上下文中扫描令牌?
【发布时间】:2011-09-29 06:35:22
【问题描述】:

我想使用 Flex & Bison 创建一个模板引擎解析器。问题是我只想解析 {{..}} 和 ${..} 中的表达式。

模板可以是任何带有嵌入标记的任意文本,代码如下:

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

【问题讨论】:

    标签: bison lex flex-lexer


    【解决方案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; }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-22
      相关资源
      最近更新 更多