あなたの質問はASTノードの構築について語っていますが、説明の本文は明らかにシンボルテーブルについて語っています。これらのアイデアは同じではありません!AST はプログラムの構造を表します。シンボル テーブルは、どのような名前がどこに表示され、どのような型を持つかについての推論を表します。
シンボルテーブルのフォーカスに従って、ブロックに「入る」ときに現在のスコープをプッシュし、「出る」ときにポップするという概念は、ブロックごとの新しいスコープを抽象的に実現するため、概念的に正しいです。
文法規則の任意の時点でセマンティック アクションを付加できるかどうかわからないので、YACC にあなたが言ったことを実行させることはできないと思います。ルール全体にのみアクションを追加できると思います。そのアクションは、ルールが認識された(「縮小」された)場合にのみ実行されます。したがって、本当にこれを行いたい場合は、文法を曲げて、セマンティック アクションを挿入する機会を作成する必要があります。ルールを書き直すことでこれを行うことができます (あなたのスタイルに従うと、これは実際には有効な YACC 構文ではないと思います):
compound_statement : block_start statement_list block_end ;
block_start = '{' pushScope() ;
block_end = '}' popScope();
開始と終了を対称的にブロックするアクションを追加しましたが、もう少し節約できます (にやにや笑い):
compound_statement : block_start statement_list '}' popScope() ;
block_start = '{' pushScope() ;
ここでの本当の秘密は、元のルールにサブルールを追加することによって、ブロックに入った後に削減/セマンティック アクションの実行機会を作成することでした。私はしばしば空のルールを使用してこれを行いました:
compound_statement : '{' compound_statement_sub_rule block_start statement_list '}' popScope() ;
compound_statement_sub_rule = pushScope() ;
これを行う方法を示したので、これを行う必要はまったくないと思います。あなたがしていることは、セマンティクスを解析プロセスと絡ませることです。この道をたどると、識別子の作成/検索のための複雑なアクションで文法の残りの部分を装飾していることに気付くでしょう。一般に、セマンティック アクションを使用して単純に構文ツリーを構築し、構文解析が完了したら、構文ツリーをたどってシンボル テーブルの構築/識別子ルックアップを実装することをお勧めします。
私はオフィスアワーに行って、あなたがばかげていると思うかどうかにかかわらず、あなたが考えることができる限り多くの質問をします. それは見事に報われます。