CPPマクロ定義解析処理【python】
3195 ワード
問題の説明
c++マクロ定義ファイルのキーワードには、#define,#undef#ifndef,#else,#endif,処理コメント,//,/*,*,*/,解析ファイルがあり、マクロ定義を出力する
構想を分析する.
テキスト解析の基礎は文字列処理であり、マクロ定義ファイルの処理には出会ったキーワードに対して特殊な処理を実行する必要がある.
ファイル定義の中間データ構造はネストされたリストで、マクロ定義は主に順序構造と分岐構造であり、順序構造は理解しやすく、1つのマクロ定義は辞書として、辞書はリストの要素としてである.ブランチ構造の場合、サブリストで表されます.このサブリストの構造は次のとおりです.
[
{{'id':1},{'parent':0},{'pos':0},#idは現在のサブリスト番号,parentはサブリストの親リスト番号,posは現在の処理ブランチの左右ブランチ,trueは左,タグは1である.falseは右で、2とマークされています.
{'macro_key': ''}, #macro_keyは現在の分岐構造の条件である
[],#は左サブリスト
[],#は右サブリスト
]
このように表すと、現在のブランチサブリストbranch(pythonの参照フィーチャーを使用)を定義し、現在のリスト番号node_id,親リスト番号parent_id,左右分岐位置pos,ネストリストの遍歴を補助する.
マクロ定義を格納するフォーマットは、マクロ定義辞書、キーはマクロ名、値はマクロ定義値です.定義済みマクロ名を記録する補助データ構造もあります.
次に、異なるキーワードについて異なる分析を行います.
1.コメントの処理
注記には、//,/*,*/、ここで/*と*/がペアで現れ、スタックで順序関係を表す3種類があります.文字ごとにスキャンする方法を採用し、各文字に対して//であれば、後の内容は省略する./*の場合、スタックが空または/*の場合、スタックに入ります.*/の場合、スタックの上部が/*の場合、スタックが弾け、カーソルが後ろに進みます.それ以外の場合は、スタックトップが/*でない場合は、有効な文字であることを示します.そうでない場合は無視します.
2.キーワードの統一処理
マクロの定義は一般的に2つの語、あるいは3つの語で、中間のスペースは隔てて、よくある構想はsplitで、ここに小さな穴があって、もし定義が文字列であれば、文字列の中間にスペースがあって、このようにsplitは第3の語を割ることができます.ここでsplitにパラメータを追加します.maxsplit=2は、前の2回に出会ったスペースだけを区切って、後ろのものを全体として意味します.
2.1遭遇#ifndef:
サブリストの挿入
node_posは2で、右ブランチを表し、branchブランチはワードリストの3番目の要素(空のサブリスト)を指し、他のフィールド定義は上記の説明を参照してください.
2.2遭遇#ifdef:
サブリストの挿入
node_posは1であり、左ブランチを表し、branchブランチはワードリストの2番目の要素(空のサブリストでもある)を指し、他のフィールド定義は上記の説明を参照してください.
2.3遭遇#else:
分岐を切り替える必要があり、pos値を修正するだけで、1は2になり、2は1に変化します.また、現在のbranchはリストの要素であり、親リストを見つける必要があります.ネストされたリスト全体で親リストのidを検索し、このリストを見つけ、posに基づいて別のブランチに調整する必要があります.指定したidのリストを検索するにはどうすればいいですか?これは単独で関数を設定し,後で詳しく述べる.
2.4遭遇#define:
これはマクロの定義であり、現在のbranchにappendの辞書を1つだけ使用すればよいが、マクロ名のみがある場合は、値ドメインは空にしておく.
2.5遭遇#endif:
これはブランチが終了するタグで、現在のbranchを親リストに変換する必要があります.左右のブランチは親リストに対応する左右のブランチに復元する必要があります.同様に、ここではツリー全体の検索に用いられ、elseとは異なる場所で、endifは左右の分岐位置を指定しない.
2.6遭遇#undef:
undefはマクロの設定をキャンセルすることを示し、
{'MC2': '', 'reverse': 1}
マクロ辞書の後ろにフィールドを追加します.reverseはマクロの設定をキャンセルしたことを示します.
これで、すべてのキーワードの処理が完了します.
ネストされたリストの検索については、再帰的にアルゴリズムの考え方は以下の通りです.
パラメータを3つ入力し、検索するブランチbranch、検索するサブリスト番号node_id,左右サブリストタイプ(-1はpos検索基準,1は左ワードリスト,2は右サブリストを表す)
出力結果2個、検索結果0失敗、1成功;[現在のリスト番号、現在の親リスト番号、現在の左右のブランチ位置、現在のブランチbranch]
現在のブランチが空の場合、出力0、[0,0,0,[]]
現在のbranchの辞書タイプ要素のシーケンスを取得し、idキーワードを含む辞書を見つけ、idの値がnode_であるかどうかを比較します.id,もしそうであれば成功裏に見つけることができ,要求されるノードタイプが1,2の場合,ブランチはbranchのサブリスト[1を左,2を右]を取り,現在の結果を出力する.要求されるノードタイプが-1の場合、idキーワード辞書のposを取り、branchのサブリストを分岐する[pos対応サブリスト]
左サブツリーが空でない場合(サブツリー長>=1)、左サブツリーを検索し、検索結果フィールドが0でない場合、左サブツリーの出力結果が最終的な結果になります.
右のサブ数が空でない場合(サブツリー長=2)、右のサブツリーを検索し、検索結果フィールドが0でない場合、右のサブツリーの出力結果が最終的な結果になります.
以上の出力条件が満たされていません.出力0,[0,0[]]
その他
全体の過程はやはり非常に挑戦して、最後の効果はまだ良くて、複雑な情況の処理はやはり火加減が足りなくて、多くの情況の処理はもっと良いことができます.頑張りましょう.
c++マクロ定義ファイルのキーワードには、#define,#undef#ifndef,#else,#endif,処理コメント,//,/*,*,*/,解析ファイルがあり、マクロ定義を出力する
構想を分析する.
テキスト解析の基礎は文字列処理であり、マクロ定義ファイルの処理には出会ったキーワードに対して特殊な処理を実行する必要がある.
ファイル定義の中間データ構造はネストされたリストで、マクロ定義は主に順序構造と分岐構造であり、順序構造は理解しやすく、1つのマクロ定義は辞書として、辞書はリストの要素としてである.ブランチ構造の場合、サブリストで表されます.このサブリストの構造は次のとおりです.
[
{{'id':1},{'parent':0},{'pos':0},#idは現在のサブリスト番号,parentはサブリストの親リスト番号,posは現在の処理ブランチの左右ブランチ,trueは左,タグは1である.falseは右で、2とマークされています.
{'macro_key': ''}, #macro_keyは現在の分岐構造の条件である
[],#は左サブリスト
[],#は右サブリスト
]
このように表すと、現在のブランチサブリストbranch(pythonの参照フィーチャーを使用)を定義し、現在のリスト番号node_id,親リスト番号parent_id,左右分岐位置pos,ネストリストの遍歴を補助する.
マクロ定義を格納するフォーマットは、マクロ定義辞書、キーはマクロ名、値はマクロ定義値です.定義済みマクロ名を記録する補助データ構造もあります.
次に、異なるキーワードについて異なる分析を行います.
1.コメントの処理
注記には、//,/*,*/、ここで/*と*/がペアで現れ、スタックで順序関係を表す3種類があります.文字ごとにスキャンする方法を採用し、各文字に対して//であれば、後の内容は省略する./*の場合、スタックが空または/*の場合、スタックに入ります.*/の場合、スタックの上部が/*の場合、スタックが弾け、カーソルが後ろに進みます.それ以外の場合は、スタックトップが/*でない場合は、有効な文字であることを示します.そうでない場合は無視します.
2.キーワードの統一処理
マクロの定義は一般的に2つの語、あるいは3つの語で、中間のスペースは隔てて、よくある構想はsplitで、ここに小さな穴があって、もし定義が文字列であれば、文字列の中間にスペースがあって、このようにsplitは第3の語を割ることができます.ここでsplitにパラメータを追加します.maxsplit=2は、前の2回に出会ったスペースだけを区切って、後ろのものを全体として意味します.
2.1遭遇#ifndef:
サブリストの挿入
[{'id': node_id, 'parent': parent_id, 'pos': node_pos}, {key_name: ''}, [], []]
node_posは2で、右ブランチを表し、branchブランチはワードリストの3番目の要素(空のサブリスト)を指し、他のフィールド定義は上記の説明を参照してください.
2.2遭遇#ifdef:
サブリストの挿入
[{'id': node_id, 'parent': parent_id, 'pos': node_pos}, {key_name: ''}, [], []]
node_posは1であり、左ブランチを表し、branchブランチはワードリストの2番目の要素(空のサブリストでもある)を指し、他のフィールド定義は上記の説明を参照してください.
2.3遭遇#else:
分岐を切り替える必要があり、pos値を修正するだけで、1は2になり、2は1に変化します.また、現在のbranchはリストの要素であり、親リストを見つける必要があります.ネストされたリスト全体で親リストのidを検索し、このリストを見つけ、posに基づいて別のブランチに調整する必要があります.指定したidのリストを検索するにはどうすればいいですか?これは単独で関数を設定し,後で詳しく述べる.
2.4遭遇#define:
これはマクロの定義であり、現在のbranchにappendの辞書を1つだけ使用すればよいが、マクロ名のみがある場合は、値ドメインは空にしておく.
2.5遭遇#endif:
これはブランチが終了するタグで、現在のbranchを親リストに変換する必要があります.左右のブランチは親リストに対応する左右のブランチに復元する必要があります.同様に、ここではツリー全体の検索に用いられ、elseとは異なる場所で、endifは左右の分岐位置を指定しない.
2.6遭遇#undef:
undefはマクロの設定をキャンセルすることを示し、
{'MC2': '', 'reverse': 1}
マクロ辞書の後ろにフィールドを追加します.reverseはマクロの設定をキャンセルしたことを示します.
これで、すべてのキーワードの処理が完了します.
ネストされたリストの検索については、再帰的にアルゴリズムの考え方は以下の通りです.
パラメータを3つ入力し、検索するブランチbranch、検索するサブリスト番号node_id,左右サブリストタイプ(-1はpos検索基準,1は左ワードリスト,2は右サブリストを表す)
出力結果2個、検索結果0失敗、1成功;[現在のリスト番号、現在の親リスト番号、現在の左右のブランチ位置、現在のブランチbranch]
現在のブランチが空の場合、出力0、[0,0,0,[]]
現在のbranchの辞書タイプ要素のシーケンスを取得し、idキーワードを含む辞書を見つけ、idの値がnode_であるかどうかを比較します.id,もしそうであれば成功裏に見つけることができ,要求されるノードタイプが1,2の場合,ブランチはbranchのサブリスト[1を左,2を右]を取り,現在の結果を出力する.要求されるノードタイプが-1の場合、idキーワード辞書のposを取り、branchのサブリストを分岐する[pos対応サブリスト]
左サブツリーが空でない場合(サブツリー長>=1)、左サブツリーを検索し、検索結果フィールドが0でない場合、左サブツリーの出力結果が最終的な結果になります.
右のサブ数が空でない場合(サブツリー長=2)、右のサブツリーを検索し、検索結果フィールドが0でない場合、右のサブツリーの出力結果が最終的な結果になります.
以上の出力条件が満たされていません.出力0,[0,0[]]
その他
全体の過程はやはり非常に挑戦して、最後の効果はまだ良くて、複雑な情況の処理はやはり火加減が足りなくて、多くの情況の処理はもっと良いことができます.頑張りましょう.