Pergunta

Eu tenho um arquivo Lex/Flex relativamente simples e o tenho executado com o sinalizador de depuração da Flex para garantir que ele esteja tokenizando corretamente. Infelizmente, estou sempre encontrando um dos dois problemas - ou o programa que o flex gera paradas apenas desiste silenciosamente após alguns fichas, ou a regra que estou usando para reconhecer personagens e strings não é chamada e a regra padrão é chamado em vez disso.

Alguém pode me apontar na direção certa? Anexei meu arquivo flex e amostra de entrada / saída.

EDIT: Descobri que o Lexer gerado para após uma regra específica: "CDR". Isso é mais detalhado, mas também muito mais confuso. Eu publiquei um arquivo Lex modificado em curto.

/* lex file*/
%option noyywrap
%option nodefault

%{
       enum tokens{
                CDR,
                CHARACTER,
                SET
        };
%}

%%

"cdr"                                               { return CDR; }
"set"                                               { return SET; }

[ \t\r\n]                                           /*Nothing*/
[a-zA-Z0-9\\!@#$%^&*()\-_+=~`:;"'?<>,\.]      { return CHARACTER; }

%%

Entrada de amostra:

set c cdra + cdr b + () ;

Saída completa da execução da entrada através do analisador gerado:

--(end of buffer or a NUL)
--accepting rule at line 16 ("set")
--accepting rule at line 18 (" ")
--accepting rule at line 19 ("c")
--accepting rule at line 18 (" ")
--accepting rule at line 15 ("cdr")

Alguma ideia? O programa gerado está desistindo após metade da entrada! (Para referência, estou fazendo informações redirecionando o conteúdo de um arquivo para o programa gerado).

Foi útil?

Solução

Ao gerar um Lexer que é independente (ou seja, não um com tokens definidos em Bison/Yacc, você normalmente escreve uma enumeração no topo do arquivo que define seus tokens. No entanto, o loop principal de um programa LEX, incluindo o principal Loop gerado por padrão, parece algo assim:

while( token = yylex() ){
    ...

Isso é bom, até que o seu Lexer corresponda à regra que aparece primeiro na enumeração - neste caso específico CDR. Como as enumes por padrão iniciam em zero, isso faz com que o loop do tempo termine. Renumerar sua enumeração - resolverá o problema.

enum tokens{
            CDR = 1,
            CHARACTER,
            SET
    };

Versão curta: Ao definir tokens manualmente para um Lexer, comece com 1 não 0.

Outras dicas

Esta regra

[-+]?([0-9*\.?[0-9]+|[0-9]+\.)([Ee][-+]?[0-9]+)? 
          |

Parece estar perdendo um suporte de fechamento logo após o primeiro 0-9, adicionei um | Abaixo onde eu acho que deveria estar. Eu não conseguia começar a adivinhar como o Flex responderia a isso.

A regra que geralmente uso para nomes de símbolos é [a-zA-Z$_], isso é como suas seqüências de cordas não cotadas, exceto que eu geralmente permito números dentro de símbolos, desde que o símbolo não comece com um número.

[a-zA-Z$_]([a-zA-Z$_]|[0-9])*

Um personagem é apenas um símbolo curto. Eu não acho que precisa ter sua própria regra, mas, se isso acontecer, você precisa garantir que a regra da string requer pelo menos 2 caracteres.

[a-zA-Z$_]([a-zA-Z$_]|[0-9])+
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top