Pergunta

Eu tenho uma gramática YACC (Bison), um tokenizer Lex (Flex) e um programa C entre os quais preciso compartilhar um struct (ou realmente qualquer variável).Atualmente, declaro o objeto real no arquivo de gramática e extern sempre que eu precisar (ou seja, meu arquivo de origem C), geralmente usando um ponteiro para manipulá-lo.Eu tenho um arquivo de cabeçalho (e implementação) compartilhado entre o arquivo C e o arquivo de gramática com funções úteis para manipular minha estrutura de dados.Isso funciona, mas é um pouco desconfortável.Existe uma maneira melhor de compartilhar memória entre a gramática e o programa?

Foi útil?

Solução

Um arquivo de cabeçalho para compartilhar a declaração externa entre os arquivos de origem que precisam dele é o melhor caminho a percorrer, geralmente. A principal alternativa é fornecer 'acesso funcional' a ele - ou seja, algum tipo de função 'Get Value' e 'Set Value' (ou um conjunto de funções). Isso geralmente é um exagero. Certifique -se de incluir o cabeçalho na gramática (onde você define a variável), bem como no Lexer e no outro código, para que as inconsistências sejam vistas o mais rápido possível.

Outras dicas

Se você quiser seguir o lex/yacc padrão (POSIX), sua única opção é optar por variáveis/funções globais.Se você estiver satisfeito com o uso de extensões Bison e Flex, existem algumas maneiras de transmitir variáveis, que envolvem principalmente a adição de parâmetros extras a yyparse() e yylex().

No Bison, isso é feito por meio de% lex-param e% parse-param.

%parse-param { struct somestruct *mystruct }
%lex-param { struct somestruct *mystruct }

No Flex, existem dois mecanismos diferentes, dependendo se você deseja um lexer reentrante ou não.Supondo que você escolha a opção padrão (não reentrante), você desejará redefinir YY_DECL:

%{
#define YY_DECL int yylex(struct somestruct *mystruct)
%}

Em um lexer Flex reentrante, argumentos extras podem ser adicionados por meio da estrutura do scanner que o Flex carrega para manter seu estado.Você deseja definir YY_EXTRA_TYPE;os dados extras podem ser acessados ​​através de yyget/set_extra().

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