Pergunta

Eu estou escrevendo um analisador C usando PLY, e recentemente tive um problema. Este código:

typedef int my_type;
my_type x;

é o código C correta, porque my_type é definido como um tipo anteriormente sendo usado como tal. Eu lidar com isso, preenchendo uma tabela tipo de símbolo na analisador que é usado pelo lexer para diferenciar entre tipos e identificadores simples.

No entanto, enquanto o tipo de extremidades regra declaração com SEMI (os ';' token), PLY desloca a my_type token da segunda linha antes de decidir que é feito com o primeiro. Devido a isso, eu não tenho chance de passar a atualização na tabela de tipo de símbolo para o lexer e vê my_type como um identificador e não um tipo.

Todas as idéias para uma correção?

O código completo está em: http: / /code.google.com/p/pycparser/source/browse/trunk/src/c_parser.py Não sei como eu posso criar um pequeno exemplo disto.

Editar:

Problema resolvido. Ver a minha solução abaixo.

Foi útil?

Solução 2

Com alguma ajuda de Dave Beazley (criador de PLY), o meu problema foi resolvido.

A idéia é usar sub-regras especiais e fazer as ações em si. No meu caso, eu dividir a regra declaration a:

def p_decl_body(self, p):
    """ decl_body : declaration_specifiers init_declarator_list_opt
    """
    # <<Handle the declaration here>>        

def p_declaration(self, p):
    """ declaration : decl_body SEMI 
    """
    p[0] = p[1]

decl_body é sempre reduzido antes de o token após SEMI é deslocado dentro, assim que minha ação é executado no tempo correto.

Outras dicas

Não sei por que você está fazendo esse nível de análise em seu lexer.

Análise lexical deve provavelmente ser utilizada para separar o fluxo de entrada em símbolos lexicais (número, linha de mudança, de palavra-chave e assim por diante). É a fase de análise que deveria estar fazendo esse nível de análise, incluindo pesquisas de tabela para typedefs e tal.

Essa é a maneira que eu sempre separou as funções entre lexx e yacc, minhas ferramentas de escolha.

Eu acho que você precisa para mover a seleção para se um ID é um typeid de c_lexer.py para c_parser.py.

Como você disse, uma vez que o analisador está olhando para frente 1 token, você não pode tomar essa decisão no lexer.

Em vez disso, alterar o seu analisador de verificar ID do para ver se eles são typeid está em declarações, e, se eles não estão, gerar um erro.

Como Pax Diablo disse em sua resposta excelente, o trabalho do lexer / de tokenizer não é fazer esses tipos de decisões sobre tokens. Esse é o trabalho do analisador.

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