Pergunta

Atualmente, estou aprendendo como o Lexers e os analisadores funcionam, e tenho as seguintes perguntas sobre a Máquina do Estado. Por exemplo, preciso colorizar o texto seguindo a regra: para esta regra, a tabela de transição de estado simples ficará assim:

current event next  action
IDLE    $     COLOR -
COLOR   any   -     OnColor()
COLOR   \n    IDLE  -

Isso chamará de ação oncolor () para todos os caracteres entre '$' e final de linha para que eu possa colori -la. É claro que o mesmo pode ser gerado automaticamente a partir do REGEXP, mas eu realmente quero saber como funciona antes do uso de mágica pesada :). O próximo problema é o problema: se eu tiver uma regra: (quero colorir qualquer linha de texto que termine com dólar, a tabela de transição do estado não é muito clara:

current      event next             action
IDLE         any   -                -
IDLE         $     DOUND_DOLLAR     -
FOUND_DOLLAR \n    IDLE             OnDollar()
FOUND_DOLLAR any   IDLE             -

Eu posso ensinar minha máquina de estado a ligar para odollar () se ele fundar um sinal de '$' no final da linha, mas o que posso fazer para colorir o texto que foi antes do encontro do sinal do dólar? Quais são os padrões comuns para resolver esses problemas? É claro que será 1 linha com o REGEXP, mas estou realmente interessado em saber como esse analisador pode ser implementado por meio da máquina de estado e é possível.

Foi útil?

Solução 3

Ao ler "Purple Dragon Book" (sic), parece que os compiladores e intérpretes modernos usando ativamente o buffer "Look Forward" e acumulam texto recente, para que possam verificar facilmente alguns próximos símbolos e poucos símbolos anteriores para obter o tipo exato de lexem.

Portanto, no meu exemplo de exemplo () precisa olhar para os símbolos próximos e anteriores para decidir o tipo de lexem que pode ser acumulado.

Outras dicas

Se você é restrito a colorir um personagem de cada vez (ou seja, você não tem capacidade de buffer, lookahead, recoling ou marcação), é impossível.

Caso contrário, se você tiver esses recursos, isso poderá ser feito; A técnica depende do que está disponível.

  • Recoloração - tenha uma ação que possa recolorar os caracteres de volta. Obviamente, esta é uma solução trivial.

  • Buffering / Marking - tenha uma ação que coloca o personagem na extremidade de um buffer / define uma marca nomeada na fonte, em vez de deixar o personagem passar. Então, quando você descobrir mais tarde o que fazer, tenha uma ação que comprometa o buffer de uma maneira ou de outra, ou libera uma marca nomeada. Recolocar mais de 1 personagem com isso fica um pouco complicado.

  • Lookahead - tem transições especulativas, ou seja, use um NFA em vez de um DFA.

A maioria dos colorizadores sempre trabalha em um bloco maior, digamos uma linha inteira (o que é suficiente na maioria dos casos), mais uma bandeira de "vazamento" para, digamos, comentários de várias linhas. Veja o QT Sintaxe Highlighter High Exemplo para tal API.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top