Os idiomas modernos ainda usam geradores de analisador?

38

Eu estava pesquisando sobre o conjunto de compiladores gcc na wikipedia aqui , quando isso surgiu:

O GCC começou usando os analisadores LALR gerados com o Bison, mas passou gradualmente para os analisadores escritos à mão; para C ++ em 2004 e para C e Objective-C em 2006. Atualmente, todos os front-ends usam analisadores de descida recursiva escritos à mão

Portanto, com a última frase (e pelo que confio na wikipedia), posso dizer definitivamente que "C (gcc), C ++ (g ++), Objective-C, Objective-C ++, Fortran (gfortran), Java (gcj), Ada (GNAT), Go (gccgo), Pascal (gpc), ... Mercúrio, Modula-2, Modula-3, PL / I, D (gdc) e VHDL (ghdl) "são todos front-ends que não use mais um gerador de analisador. Ou seja, todos eles usam analisadores escritos à mão.

Minha pergunta então é: essa prática é onipresente? Especificamente, estou procurando respostas exatas para "a implementação padrão / oficial de x possui um analisador escrito à mão" para x em [Python, Swift, Ruby, Java, Scala, ML, Haskell]? (Na verdade, informações em outros idiomas também são bem-vindas aqui.) Tenho certeza de que posso encontrar isso sozinho depois de muita pesquisa. Mas também tenho certeza de que isso é facilmente respondido pela comunidade. Obrigado!

eatonphil
fonte
3
Ponto de dados: O CPython possui um gerador de analisador LALR de fermentação doméstica (pgen). Não sei o resto.
8
Ponto de dados: Ghc (haskell) usa um gerador de analisador LALR (feliz), assim como o OCaml.
Twan van Laarhoven 17/07/2014
1
Deve ser "Faça modernos compiladores de alto desempenho ..." ou semelhante, porque o idioma é a especificação e não a implementação, enquanto é o compilador que usa ou não um analisador gerado por máquina.
dmckee
@ DMCkee, sim, você está correto. No entanto, a nomeação começa a ficar longa e menos direta. Sinta-se livre para editá-lo, se você é mais criativo do que eu!
eatonphil
Em relação ao ML: O MLton usa um gerador de analisador específico para o ML, tenho 90% de certeza de que o SML / NJ também o faz, embora eu esteja menos familiarizado com ele. Você pode ou não querer considerar isso "escrito à mão".
Patrick Collins

Respostas:

34

O AFAIK, GCC usa analisadores escritos à mão, em particular, para melhorar o diagnóstico de erros sintáticos (ou seja, fornecer mensagens significativas humanas sobre erros de sintaxe).

A teoria de análise (e os geradores de análise descendentes dela) é principalmente sobre o reconhecimento e análise de uma frase de entrada correta . Mas esperamos dos compiladores que eles forneçam uma mensagem de erro significativa (e que sejam capazes de analisar significativamente o restante da entrada após o erro sintático), para alguma entrada incorreta.

Além disso, linguagens legadas antigas, como C11 ou C ++ 11- (que são conceitualmente antigas, mesmo que sua última revisão tenha apenas três anos) não são totalmente livres de contexto. Lidar com a sensibilidade desse contexto nas gramáticas para geradores de analisadores (ou seja, bisontes ou até menires ) é tediosamente difícil.

Basile Starynkevitch
fonte
2
Concorrer. Recuperar bem os erros de análise (quando você não deseja parar de analisar o primeiro erro, como o antigo Borland Pascal) e criar mensagens de erro de boa qualidade (incluindo dicas e sugestões de resolução, como os humanos querem) são inerentemente contextuais tarefas heurísticas sensíveis. Eles podem ser feitos no alto da saída do gerador de analisador de estoque, um pouco, mas é um trabalho árduo.
27616 Jonathan Eunice
2
Dealing with that context sensitiveness in grammars for parser generators is boringly difficult. Também é mais ou menos impossível, pois essas ferramentas geram analisadores sem contexto. O local correto para verificar se todas as restrições sensíveis ao contexto estão presentes é após a geração da árvore de análise, se você estiver usando ferramentas como esta.
DTECH
7

Os geradores e motores de analisador de analisadores são bastante gerais. A vantagem da generalidade é que é fácil construir um analisador preciso rapidamente e torná-lo funcional, no esquema geral das coisas.

O próprio mecanismo do analisador sofre na frente do desempenho devido à sua generalidade. Qualquer código escrito à mão sempre será significativamente mais rápido que os mecanismos do analisador acionado por tabela.

A segunda área em que os geradores / mecanismos de análise têm dificuldade é que todas as linguagens de programação reais são sensíveis ao contexto, geralmente de maneiras bastante sutis. As linguagens LR são livres de contexto, o que significa que existem muitas sutilezas sobre posicionamento e ambiente que são impossíveis de transmitir adequadamente na sintaxe. As gramáticas atribuídas tentam abordar regras básicas de linguagem, como "declarar antes do uso", etc. A conexão dessa sensibilidade ao contexto no código escrito à mão é simples.

BobDalgleish
fonte
15
Citação para a reivindicação de desempenho, por favor? Ser orientado por tabelas pode ser uma otimização de desempenho significativa e os geradores têm acesso a algoritmos muito eficientes, mas praticamente nunca implementados manualmente (justamente porque são uma confusão impenetrável de tabelas e números mágicos).
2
E sobre a segunda área: muitas das principais linguagens de programação reais não são sensíveis ao contexto em nenhum sentido que se aplique (você teria que se referir ao conjunto de todos os programas válidos após a verificação de tipo e assim por diante , o que nunca é escrito à mão ou analisador gerado tenta analisar). É verdade que os analisadores escritos à mão são mais flexíveis, e isso é útil para alguns idiomas, mas principalmente no domínio da recuperação de erros e relatórios, incrementalidade etc. - os geradores de analisadores raramente são evitados por causa do poder de reconhecimento (se você quer escrever tal gramática é uma história diferente). -1
Se você usar as informações da tabela de símbolos durante a análise, poderá chamá-lo de sensível ao contexto. As gramáticas atribuídas definitivamente não são livres de contexto, embora eu não ache que sejam totalmente sensíveis ao contexto. Seus outros pontos sobre recuperação de erros e relatórios são bem aceitos.
BobDalgleish
1
C e C ++ precisam de informações da tabela de símbolos durante a análise (ou aceite uma árvore de análise muito menos específica em que não seja feita distinção entre, por exemplo, instruções de expressão e declarações de variáveis). Mas eu não estava pensando nisso. Idiomas como Java, Lisps, JavaScript, Ruby, Python, Go, Rust, Scala, Swift, Haskell (e provavelmente vários mais, talvez C # e ML também?) Não precisam dessas informações para criar o tipo de AST que você quer assim mesmo. Muitos deles realmente possuem gramáticas LL (1), ou mesmo gramáticas LALR.
1
citação para todas as línguas reais são sensíveis ao contexto, por favor?
Psr