Máquina de estado para coloração de sintaxe
-
22-07-2019 - |
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.
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.