Pergunta

Perdoe-me, eu sou completamente novo para analisar e lex / yacc, e eu sou provavelmente na maneira sobre a minha cabeça, mas mesmo assim:

Eu estou escrevendo uma calculadora bastante básico com PLY, mas de entrada pode não ser sempre uma equação, e eu preciso para determinar se ele é ou não durante a análise. Os extremos da entrada seria algo que avalia perfeitamente à uma equação, que ele analisa bem e calcula, ou algo que não é nada como uma equação, que falha a análise e também está bem.

A área cinza é uma entrada que tem equação semelhante partes, das quais o analisador vai agarrar e trabalhar fora. Este não é o que eu quero -. Eu preciso ser capaz de dizer se partes da cadeia não se pego e indexado para que eu possa jogar para trás um erro, mas não tenho idéia de como fazer isso

Alguém sabe como posso definir, basicamente, uma 'captura tudo o que é esquerda' símbolo? Ou há uma maneira melhor que eu posso lidar com isso?

Foi útil?

Solução

Há um built-in error token no yacc. Você normalmente fazer algo como:

line: goodline | badline ;

badline : error '\n' /* Error-handling action, if needed */

goodline : equation '\n' ;

Qualquer linha que não corresponde equation serão tratadas por badline.

Você pode querer usar yyerrok no erro de manipulação de ação para garantir o processamento de erro é reposto para a próxima linha.

Outras dicas

Definir um símbolo (final da entrada), e fazer a sua saída lexer-lo no final da entrada.

Portanto, antes, se você tivesse esses tokens:

'1' 'PLUS' '1'

Você agora tem:

'1' 'PLUS' '1' 'END_OF_INPUT'

Agora, você pode definir sua regra de nível superior no seu analisador. Em vez de (por exemplo):

Equation ::= EXPRESSION

Você terá

Equation ::= EXPRESSION END_OF_INPUT

Obviamente você vai ter que reescrever estes em sintaxe PLY, mas isso deve levá-lo a maior parte do caminho.

Eu normalmente uso um 'leitor de comando' separado para obter um comando completo - provavelmente uma linha no seu caso - em uma seqüência variável de host, em seguida, mandar para o analisador léxico para analisar a cadeia, incluindo a dizer-me quando ele didn' t chegar ao fim. Isso é difícil de configurar, mas fazer algumas classes de relatórios de erros mais fácil. Um dos lugares que eu usei esta técnica rotineiramente tem comandos multi-linha com 3 convenções comentário, dois conjuntos de cadeias entre aspas, e alguns outros males para definir meus dentes na borda (sensível ao contexto tokenization - eca).

Caso contrário, o conselho de Don com o Yacc 'error' token é bom.

Parece que você já encontrou uma solução, mas vou acrescentar outra sugestão no caso de você ou outros estão interessados ??em uma abordagem alternativa.

Você diz que você está usando PLY mas é que porque você quer que o compilador para ser executado em um ambiente Python? Se assim for, você pode considerar outras ferramentas também. Para esses empregos Costumo usar ANTLR ( http://www.antlr.org ), que tem um gerador de código Python . ANTLR tem muitos truques para fazer as coisas como comer um monte de entrada no nível léxico para que o analisador de nunca vê-lo (por exemplo, comentários), capacidade de chamar uma sub-regra (por exemplo equação) dentro de uma gramática maior (que deve terminar uma vez que o regra foi acompanhado sem processar mais de entrada ... soa um pouco como o que você quer fazer) e um algoritmo muito agradável esquerda factoring.

ANTLRs ao analisar a capacidade combinada com o uso do StringTemplate ( http://www.stringtemplate.org ) motor faz uma boa combinação e tanto apoio Python (entre muitos outros).

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