2015-10-07 131 views
0

我有下面的配置文件,我试图解析。不含文字引号的字符串的正则表达式

[ main ] 
e_type=0x1B 
username="username" 
appname="applicationname" 

在下面指定的文件法(test.l),用于STR正则表达式是\"[^\"]*\"使其能够识别内quotes.When我访问使用$ N变量解析器文件内的"username" or "applicationname"值一切,它包含了字符串。我只想要 usernameapplicationname即没有字符串引号。

有没有一个标准的方法来实现这一目标。

我有以下的lex文件(test.l

%option noyywrap 
%option yylineno 
%{ 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include "y.tab.h" 

int yylinenu = 1; 
int yycolno=1; 

/** 
* Forward declerations 
**/ 
void Number(); 
void HexaNumber(); 
unsigned char getHexaLex (char c); 
unsigned int strtol16 (char * str); 


%} 

%option nounput 
%option noinput 
%option case-insensitive 

/*----------------------------------------------------------------- 
    Some macros (standard regular expressions) 
------------------------------------------------------------------*/ 

DIGIT  [0-9] 
HEXALETTER [a-fA-F] 
HEXANUMBER [0][x](({DIGIT}|{HEXALETTER})+) 
NUM   {DIGIT}+ 
HEXA  ({DIGIT}|{HEXALETTER}|[*]) 
STR   \"[^\"]*\" 
WSPACE  [ \t]* 
NEWLINE  [\n\r]   

/*---------------------------------------------------------------- 
    The lexer rules 
------------------------------------------------------------------*/ 
%% 

e_type     { yylval.str = yytext; return T_E_TYPE; } 
main      { yylval.str = yytext; return T_MAIN_SECTION;} 
{HEXANUMBER}    { yylval.n = atoi(yytext); HexaNumber(); return T_NUMBER; } 
=      { return T_EQUAL; } 
"["      { return T_OPEN_BRACKET; } 
"]"      { return T_CLOSE_BRACKET;} 
appname     { Custom_tag(); return T_APPNAME; } 
username     { Custom_tag(); return T_APPNAME; } 

[^\t\n\r]    { } 
{WSPACE}     { } /* whitespace: (do nothing) */ 
{NEWLINE}    { 
          yylinenu++; 
          return T_EOL; 
         } 
{STR}     { Generic_string(); return T_STRING;}      

%% 

void Number() { 
    yylval.n = atol(yytext); 
} 

void Generic_string() { 
    yylval.str = malloc(strlen(yytext)+1); 
    strcpy (yylval.str, yytext); 
} 
+0

您直接在'yylval.str'中返回'yytext',这是错误的 - 令牌缓冲区将在下一个令牌读取时发生变化,从而导致您的符号看起来随机获取消失。你需要复制'yytext'并返回一个指向它的指针。 –

回答

1

你有一个指针匹配的令牌(yytext)和长度(yyleng),所以这是很简单的删除引号:

void Generic_string() { 
    yylval.str = malloc(yyleng - 1); // length - 2 (quotes) + 1 (NUL) 
    memcpy (yylval.str, yytext + 1, yyleng - 2); // copy all but quotes 
    yylval.str[yyleng - 2] = 0;     // NUL-terminate 
} 

就个人而言,我建议避免使用全局变量Generic_string,这两者都是为了简化可重入扫描器的未来实现,并使该过程更加灵活:

{STR} { yylval.str = duplicate_segment(yytext + 1, yyleng - 2); 
      return T_STRING; 
     } 

    /* ... */ 

char* duplicate_segment(const char* token, int token_length) { 
    char* dup = malloc(token_length + 1); 
    if (!dup) { /* handle memory allocation error */ } 
    memcpy(dup, token, token_length); 
    dup[token_length] = 0; 
    return dup; 
} 
相关问题