9

背景: 冬休み中の短いプロジェクトとして、Python と PLY を使用して、Ax (グラフ電卓用に設計された) というプログラミング言語を実装しようとしています。簡単な注意: この言語はグローバル変数のみを許可し、ポインターを多用します。

この言語で goto を実装しようとしていますが、その方法がわかりません。

私の一般的な方法は、最初に PLY を使用してコードを ast に解析し、次にそれを実行しながら実行することです。

たとえば、ステートメント

If 3
    Disp 4
    Disp 6
End

...に変わるだろう...

['PROGRAM', 
  ['BLOCK', 
    ['IF', 
      ['CONDITION', 3], 
      ['BLOCK', 
        ['DISP', 4], 
        ['DISP', 6]
      ]
    ]
  ]
]

...これを再帰的に実行します (読みやすくするためにインデントを追加しました)。

ast はツリーであるため、異なるノード間をジャンプする方法がわかりません。おそらく、ツリーをフラットな配列に変換して、フラットな配列['IF', ['CONDITION', 3], ['DISP', 4], ['DISP', 6]]のインデックスを使用してコードの特定の行に移動できるようにすることを検討しましたが、これには特定の優雅さが欠けているようで、ほとんどステップのように感じます逆に(間違っているかもしれませんが)。

私はこれを見てきましたがそれがどのように機能するかを理解できませんでした。

ヘルプやヒントをいただければ幸いです。

4

3 に答える 3

9

「再帰的に実行する」はgoto. が機能するにはgoto、PC、「プログラムカウンター」が必要であり、プログラム内の各ステートメントには個別のアドレスが必要です。実行されると、各ステートメントのアドレスが PC に割り当てられます。がgoto検出されると、goto (その引数) のターゲット アドレスが PC に入れられ、そこから実行が再開されます。

これは、スタックベースの再帰的アプローチで達成することはほとんど不可能です。次の 2 つのオプションがあります。

  • AST をシーケンスにフラット化し、各ステートメントに個別のアドレスを割り当てることができます

  • インタープリターに「スキップ」モードを追加します。に遭遇すると、すべてのスタック フレームを抜けてルートに戻るgotoa をスローします。GotoExceptionターゲットアドレスに到達するまで、ステートメントを処理します (実行せずにスキップします)。

gotoのこの実装はあまりパフォーマンスが高くなく、おそらく実装が脆弱であることが想像できると思います。

于 2011-12-27T08:40:42.333 に答える
0

AST を有向グラフ (制御フロー グラフ) にフラット化することもできます。networkxインタープリターがトラバースできるグラフを生成するためにこれを行う方法の例は、Python パッケージにありますpromela。そのためには、いくつかの AST クラスを作成する必要があることに注意してください。

于 2015-03-27T09:47:41.720 に答える