Multiple flex / analisadores bisonte
-
06-07-2019 - |
Pergunta
O que é a melhor maneira de lidar com vários analisadores Flex / Bison dentro de um projeto?
Eu escrevi um analisador e agora eu preciso de um segundo no mesmo projeto. Até agora, na terceira seção do parser1.y
I inserido o método main(..)
e chamou yyparse
de lá.
O que eu quero obter é ter dois analisadores diferentes (parser1.y
e parser2.y
) e ser capaz de usá-los a partir de uma função externa (vamos supor main
em main.cpp
).
Que precauções devo usar para funções de exportação yyparse
arquivos .y
fora e como eu deveria lidar com dois analisadores?
PS. Estou usando g ++ para compilar mas não o C ++ versões Flex e Bison e eu gostaria de mantê-lo dessa forma (evitando assim encapsular o analisador dentro de um objeto).
Solução
Note que Bison fornece a '-p zz' opção de símbolos de prefixo com 'zz' em vez de 'aa'.
Da mesma forma, Flex fornece o '-P zz' opção de símbolos de prefixo com 'zz' em vez de 'aa'. Ele usa '-p' para relatórios de desempenho. É uma pena que eles não são consistentes entre si.
Outras dicas
Além de resposta de Leffler, eu gostaria de oferecer uma outra abordagem aqui:
No arquivo .lex
você poderia usar %option prefix="PREFIX"
, e no arquivo .y
você poderia usar %define api.prefix PREFIX
, que faz a mesma coisa que passar -p PREFIX
a Bison e -P PREFIX
para Flex.
Observe após a substituir do yy
prefixo padrão, você pode acessar nomes internos via AMBOS o yy*
original e seu PREFIX*
substituído, enquanto que, obviamente, para nomes externos você deve usar seu PREFIX*
para acessá-los.
Se você usar Bison 3.0 ou melhor, em seguida, ter um olhar para %define api.prefix {foo_}
, que substitui todos os prefixos yy
e YY
com foo_
e FOO_
.
Veja a documentação sobre múltiplas Analisadores .
Entre Vega 2,6 e 3,0, não utilizado para haver cintas:. %define api.prefix foo_
A variável api.prefix não está funcionando mais para mim (é produzir um erro de compilação)
%define api.prefix {PREFIX}
Eu tive que usar a seguinte sintaxe
%name-prefix="PREFIX"
Além do que já foi dito, se você usar um 'api.prefix% definir {PREFIX}' que também irá renomear yytext && yyparse para PREFIXtext e PREFIXparse. Não se esqueça do {} em todo o prefixo!
O mesmo se aplica a opção '% prefix = "prefixo"' em lex, o lexer será renomeado para PREFIXlex.