Pergunta

Como um projeto animal de estimação, eu gostaria de tentar implementar uma linguagem básica de meu próprio projeto que pode ser usado como uma linguagem de web-scripting. É trivial para executar um programa C ++ como um Apache CGI, então as mentiras reais de trabalho em como analisar um arquivo de entrada contendo não-código (HTML / CSS marcação) e código do lado do servidor.

No meu curso compilador graduação, usamos Flex e Bison para gerar um scanner e um analisador para uma linguagem simples. Foi-nos dada uma cópia da gramática e escreveu um analisador que traduziu a linguagem simples para uma simples reunião para uma máquina virtual. O scanner de flex tokenizes a entrada, e passa os sinais para o analisador Vega.

A diferença entre este eo que eu gostaria de fazer é que, como PHP, esta linguagem pode ter marcação HTML simples e a linguagem de script intercaladas como o seguinte:

<p>Hello,
<? echo "World ?>
</p>

Am I incorreta em assumir que seria eficiente para analisar o arquivo de entrada da seguinte forma:

  1. entrada de digitalização até que uma tag script de inicialização é encontrada ('
  2. segundo scanner tokenizes seção script do lado do servidor do arquivo de entrada (a partir da tag aberta: '') e passa o token para o analisador, que não tem necessidade de saber sobre a marcação no arquivo.
  3. O controle é retornado para o primeiro scanner que continua este padrão geral.

Basicamente, o primeiro aparelho apenas se diferencia entre Markup (que é retornada directamente para o navegador não modificada) e de código, que é passado para o segundo scanner, que por sua vez tokenizes o código e passa os sinais para o analisador.

Se isto é não um padrão de design sólido, como é que linguagens como PHP entrada alça de varredura e análise de código de forma eficiente?

Foi útil?

Solução

Você quer olhar para as condições iniciais. Por exemplo:

"<?"            { BEGIN (PHP); }
<PHP>[a-zA-Z]*  { return PHP_TOKEN; }
<PHP>">?"       { BEGIN (0); }
[a-zA-Z]*       { return HTML_TOKEN; }

Você começa no estado 0, use a BEGIN macro para os estados de mudança. Para corresponder a um RE somente enquanto em um estado particular, prefixo do RE com o nome do estado cercado por ângulo de menor e maior.

No exemplo acima, "PHP" é o estado. "PHP_TOKEN" e "HTML_TOKEN" são _% token_s definida por seu arquivo yacc.

Outras dicas

PHP não diferencia entre a digitalização ea Markup. É simplesmente sai para o tampão, quando no modo de marcação, e em seguida muda para análise quando no modo de código. Você não precisa de um scanner de duas passagens, e você pode fazer isso com apenas um único lexer flex.

Se você está interessado em saber como o PHP em si funciona, baixar o código fonte (experimente a fonte PHP4 é muito mais fácil de entender). O que você quer olhar é no Diretório Zend, zend_language_scanner.l.

Depois de ter escrito algo semelhante a mim mesmo, eu realmente recomendo repensar indo a rota Flex e Bison, e ir com algo moderno como Antlr . É muito mais fácil, mais fácil de entender (as macros empregadas em uma lex gramática ficar muito confuso e difícil de ler) e ele foi construído em um depurador ( AntlrWorks ) para que você não tem que passar horas olhando para 3 arquivos de depuração Meg. Ele também suporta muitas linguagens (Java, C #, C, Python, Actionscript) e tem um excelente livro e um site muito bom que deve ser capaz de chegar até você e funcionando em nenhum momento.

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