2015-10-07 5 views
0

У меня есть следующий файл конфигурации, который я пытаюсь проанализировать.Регулярное выражение для строки, исключающей литеральные кавычки

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

В ЛЕКС файле (test.l), указанной ниже, регулярное выражение для STR является \"[^\"]*\" так, что он признает все, что в quotes.When я получить доступ к значению "username" or "applicationname" внутри файла анализатора, используя переменную $ N, она содержит буквальная строка. Мне просто нужны username и applicationname т.е. без строковых кавычек.

Есть ли стандартный способ добиться этого.

У меня есть следующий ЛЕКС файл (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

Вы возвращаете 'yytext' непосредственно в' yylval.str', что неверно - буфер токена изменится для следующего чтения токена, в результате чего ваши символы кажутся случайным образом запутаны. Вам нужно сделать копию '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; 
} 
Смежные вопросы