Pergunta
Estou usando o Lex no meu programa e tenho um problema com o qual preciso de ajuda.
Meu programa aceita sua entrada na forma de [algo "algo]. Isso está funcionando corretamente.
No entanto, também preciso aceitar o formulário [algo "algo].
Existe uma maneira de eu ter algum tipo de primeiro caso em Lex em que todas as entradas são executadas (como o pré -processamento) e, em seguida, a mesma entrada modificada continua através do restante do meu programa?
Aqui está o que estou falando:
%%
.* {
do preprocessing
}
something{
return SOMETHING;
}
\" {
return QUOTE;
}
%%
Solução
Bem, você pode realmente escrever um pré -processador em Lex e colocá -lo em seu sistema de construção, mas isso é provavelmente exagero!
Você pode usar as condições de início, alternando entre elas com o início e analisar primeiro a entrada e depois usar o Unput para empurrar os personagens de volta para o fluxo; em seguida, uma condição de partida diferente pode analisar o resultado (veja o manual flexível).
Recentemente, escrevi um analisador para uma linguagem de configuração do tipo Python que fez exatamente isso. O analisador tinha dois modos (condições de partida), uma para contar as guias no início de uma linha para determinar o escopo e depois outra para fazer a análise real.
Esses métodos são bons, mas geralmente há uma maneira melhor de fazê -lo, especialmente se o seu esquema de entrada não for extremamente complexo.
Existe uma diferença gramática entre [algo "algo] e [algo" algo] para o seu programa? Uma regra de comer em branco faria o truque?
Poderia descrever seu idioma e gramática um pouco mais ....?
Depois do comentário:
OK, então, basicamente, você tem dois fichas, algo e citação. Se seus tokens forem separados pelo espaço branco, você poderá fazer o seguinte:
%%
\" {
//this will match a single quote
return QUOTE;
}
[^" \t\n\r]+ {
//this will match a run of anything thats not a quote, space, tab or line ending
return SOMETHING;
}
[ \t\n\r] {
//do nothing: i.e. ignore whitespace
}
%%
Para o seu token, você também pode combinar com algo como [A-Za-z_][A-Za-z0-9_]*
que corresponderá a uma carta ou um sublinhado seguido por 0 ou mais letras, sublinhamentos e números.
Isso ajuda?