J'essaie d'analyser certains éléments de Verilog - je suis principalement intéressé par l'extraction de définitions de modules et d'instanciations.Est-il possible de créer une grammaire très permissive en utilisant Menhir?
en Verilog un module est défini comme:
module foo (...) endmodule;
Et un module est instancié dans l'une des deux façons différentes:
foo fooinst (...);
foo #(...list of params...) fooinst (....);
A ce stade, je ne suis intéressé à la nom du module défini ou instancié; 'foo' dans les deux cas ci-dessus.
Compte tenu de cette grammaire menhir (verParser.mly):
%{
type expr = Module of expr
| ModInst of expr
| Ident of string
| Int of int
| Lparen
| Rparen
| Junk
| ExprList of expr list
%}
%token <string> INT
%token <string> IDENT
%token LPAREN RPAREN MODULE TICK OTHER HASH EOF
%start expr2
%type <expr> mod_expr
%type <expr> expr1
%type <expr list> expr2
%%
mod_expr:
| MODULE IDENT LPAREN { Module (Ident $2) }
| IDENT IDENT LPAREN { ModInst (Ident $1) }
| IDENT HASH LPAREN { ModInst (Ident $1) };
junk:
| LPAREN { }
| RPAREN { }
| HASH { }
| INT { };
expr1:
| junk* mod_expr junk* { $2 } ;
expr2:
| expr1* EOF { $1 };
Lorsque je tente ce dans le menhir interpretter il fonctionne très bien extraire le module instantion:
MODULE IDENT LPAREN
ACCEPT
[expr2:
[list(expr1):
[expr1:
[list(junk):]
[mod_expr: MODULE IDENT LPAREN]
[list(junk):]
]
[list(expr1):]
]
EOF
]
Il fonctionne très bien pour le instanciation d'un seul module:
IDENT IDENT LPAREN
ACCEPT
[expr2:
[list(expr1):
[expr1:
[list(junk):]
[mod_expr: IDENT IDENT LPAREN]
[list(junk):]
]
[list(expr1):]
]
EOF
]
Mais bien sûr, s'il y a un IDENT t apparaît avant tout d'eux, il rejettera:
IDENT MODULE IDENT LPAREN IDENT IDENT LPAREN
REJECT
... et bien sûr il y aura des identifiants dans un fichier Verilog réel avant ces defs. J'essaie de ne pas avoir à spécifier complètement une grammaire Verilog, mais je veux construire la grammaire lentement et progressivement pour finir par analyser de plus en plus le langage.
Si j'ajoute IDENT à la règle de courrier indésirable, cela résout le problème ci-dessus, mais la règle d'instanciation de module ne fonctionne pas car la règle de courrier indésirable capture maintenant l'IDENT.
Est-il possible de créer une règle très permissive qui contournera les éléments que je ne veux pas faire correspondre, ou est-il généralement nécessaire de créer une grammaire complète pour faire quelque chose comme ça?
Est-il possible de créer une règle qui me permettrait de correspondre:
MODULE IDENT LPAREN stuff* RPAREN ENDMODULE
où "choses *" correspond à tout d'abord, mais RPAREN?
Quelque chose comme:
stuff:
| !RPAREN { } ;
Je l'ai utilisé parseurs PEG dans le passé qui permettrait des constructions de ce genre.
Juste curieux, y at-il une raison pour laquelle Verilog-Perl ou une grammaire Verilog ANTLR ne convient pas? –
@ Adam12: ANTLR implique Java. Verilog-Perl peut fonctionner, mais je pense que nous aurons besoin de quelque chose d'un peu plus rapide que Perl (plusieurs milliers de fichiers Verilog à traiter). Peut finir par aller avec C++ et Boost :: spirit puisque les parseurs PEG peuvent être configurés pour analyser plus facilement une grammaire incomplète. – aneccodeal
Si vous pensez que le PEG est mieux adapté au travail (je n'ai aucune expérience de l'utilisation des grammaires LR pour l'analyse partielle/floue), vous pouvez être intéressé par [Aurochs] (https://github.com/berke/aurochs), un Générateur d'analyseur de PEG dans la terre d'OCaml. – gasche