Verilog の一部を解析しようとしています。主に、モジュールの定義とインスタンス化を抽出することに関心があります。
Verilog では、モジュールは次のように定義されます。
module foo ( ... ) endmodule;
モジュールは、次の 2 つの異なる方法のいずれかでインスタンス化されます。
foo fooinst ( ... );
foo #( ...list of params... ) fooinst ( .... );
この時点では、定義済みまたはインスタンス化されたモジュールの名前を見つけることにのみ関心があります。上記の両方の場合で「foo」。
このメンヒル文法 (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 };
menhir インタープリターでこれを試してみると、モジュール インスタンスをうまく抽出できます。
MODULE IDENT LPAREN
ACCEPT
[expr2:
[list(expr1):
[expr1:
[list(junk):]
[mod_expr: MODULE IDENT LPAREN]
[list(junk):]
]
[list(expr1):]
]
EOF
]
単一モジュールのインスタンス化では問題なく機能します。
IDENT IDENT LPAREN
ACCEPT
[expr2:
[list(expr1):
[expr1:
[list(junk):]
[mod_expr: IDENT IDENT LPAREN]
[list(junk):]
]
[list(expr1):]
]
EOF
]
しかしもちろん、これらのいずれかの前に現れる IDENT がある場合、拒否されます。
IDENT MODULE IDENT LPAREN IDENT IDENT LPAREN
REJECT
...そしてもちろん、これらの定義の前に実際の Verilog ファイルに識別子があります。
Verilog 文法を完全に指定する必要はないようにしています。代わりに、文法をゆっくりと段階的に構築して、最終的にはより多くの言語を解析したいと考えています。
IDENT をジャンク ルールに追加すると、上記の問題は修正されますが、ジャンク ルールが IDENT をキャプチャしているため、モジュールのインスタンス化ルールは機能しません。
一致させたくないものをバイパスする非常に寛容なルールを作成することは可能ですか、それとも実際にこのようなことを行うには完全な文法を作成する必要がありますか?
一致させるルールを作成することは可能ですか:
MODULE IDENT LPAREN stuff* RPAREN ENDMODULE
「stuff*」は、最初は RPAREN 以外のすべてに一致しますか?
何かのようなもの :
stuff:
| !RPAREN { } ;
私は過去に、そのような構造を可能にする PEG パーサーを使用しました。