2017-01-24 15 views
0

Я пытаюсь прочитать известное число (во время выполнения) символов в Flex lexer. Я знаю, что он начинается с CRLF, поэтому я сопоставляю это, а затем читаю символы literal_length, используя yyinput.Как я могу запретить Flex отбрасывать yyinput символы?

<EXPECT_LITERAL>"\r\n"  { 
    for(int i=0;i<literal_length;i++){ 
     int c= yyinput(yyg); 
     if(c == EOF) break; 
    } 
    *yylval = val_new_s(yytext); 
    return(LITERAL); 
} 

Но yyinput не добавляет новые символы, вместо этого он содержит:

*yy_c_buf_p = '\0'; /* preserve yytext */ 
yy_hold_char = *++yy_c_buf_p; 

, что означает, что yytext не получает дополнительных символов literal_length. Я бы предпочел не создавать новый буфер для их хранения, если я могу его избежать, потому что я знаю, что последовательность символов уже находится в памяти.

Помимо полного переопределения yyinput(), есть ли способ сохранить дополнительные символы в yytext?

ответ

0

Вы соглашаетесь с CRLF, так что yytext содержит CRLF.

Если вы хотите, чтобы соответствовать цифрам следующих CRLF, то вам нужно, чтобы соответствовать цифрам:

%x EXPECT_DIGITS 

<EXPECT_LITERAL>\r\n BEGIN(EXPECT_DIGITS); /* ignore otherwise */ 
<EXPECT_DIGITS>[0-9]* BEGIN(INITIAL);  /* parse yytext here */ return LITERAL; 

То, что символы могут быть считаны уже является деталью реализации вы не можете полагаться.

Возможно, вы упростите совпадение немного больше, чтобы уйти без специального состояния (например, вы можете сопоставить \r\n[0-9]*, тогда цифры уже являются частью yytext).

+0

Спасибо за информацию Simon. Но я не могу создать соответствие для точного количества символов, которые неизвестны до выполнения. Я знаю, что символы читаются, потому что вызов yyinput() заставляет их читать. Мы можем определить, произойдет ли EOF до ожидаемого количества символов, и YYINPUT можно заставить ждать, если они еще не готовы. Так что известно, что персонажи есть. Я мог бы переписать yyinput(), чтобы НЕ уничтожить входящие символы, но поскольку это исключено вопросом, я приму ваш ответ как «нет». – Roderick

+0

@ Roderick, вот что делает звездочка. '[0-9]' соответствует любой цифре ASCII, звездочка повторяет это совпадение. 'yyleng' затем сообщает вам, сколько символов совпало. –

+0

Звездочка получает все символы, которые она может. Вопрос состоял в том, чтобы получить символы «literal_length», и только многие. – Roderick

0

Вы можете соответствовать цифрам в отдельном государстве, и прекратить состояние, когда у вас есть все из них:

%{ 
    uint64_t accumulator; 
    unsigned int remaining_digits; 
%} 

%x EXPECT_DIGITS 

<EXPECT_LITERAL>\r\n BEGIN(EXPECT_DIGITS); remaining_digits = literal_length; accumulator = 0; 
<EXPECT_DIGITS>[0-9] accumulator = accumulator * 10 + *yytext - '0'; if(!--remaining_digits) { BEGIN(INITIAL); *yylval = accumulator; return LITERAL; } 
<EXPECT_DIGITS>.  /* handle non-digits */ 

Это требует немного больше обработок ошибок, очевидно.

 Смежные вопросы

  • Нет связанных вопросов^_^