开发者

How to scan tokens only within context using Flex?

开发者 https://www.devze.com 2023-04-08 08:55 出处:网络
I want to create a parser of template engine using Flex & Bison. The thing is that I would like to parse only expressions within {{..}} and ${..}.

I want to create a parser of template engine using Flex & Bison. The thing is that I would like to parse only expressions within {{..}} and ${..}.

The template can be any arbitrary text with embedded tokens with code like this:

        </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>
        """)}开发者_如何学JAVA}
        <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>


I have found the solution myself. Flex has a feature called Start Conditions.

Below is the lexer.l code which returns tokens only from {{ }}. Other text is returned as 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; }
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号