2

ユーザーがある種のスクリプトを作成できるようにするプログラムを作成しています。私は彼のスクリプトを実行時にコンパイルしてから実行しました。私は次のようなことをしています: https://stackoverflow.com/a/4181855/637142

とにかく、長い話を短くするために、基本的に $ で始まるすべての変数を置き換える必要があります。スクリプトをコンパイルする何かのために。ユーザーに次の行がある場合:

var x = ($MyArray[ 4 ].Size) + 3;

どの正規表現を選択できるようになります$MyArray[ 4 ].Sizeか?

ユーザーがどこに書き込む場合:

var x = $SomeVar;

その場合、簡単に見つけることができますSomeVar。$ で始まる変数が見つからない

編集

私は解決策を見つけることに近づいていると思います。現在、$ を次の単語に置き換えていFoo.ます。つまり、行を置き換えました。

var x = ($MyArray[ 4 ].Size) + 3;

為に

dynamic Foo; // then
var x = (Foo.MyArray[ 4 ].Size) + 3;

これでコンパイルできますが、まだ見つける必要がありますFoo.MyArray[ 4 ].Size

編集 2

私はコンパイラを作成しようとしているのではなく、いくつかの変数 ($ で始まる変数) を置き換える必要があるだけです;)

4

3 に答える 3

2

正規表現を使用してスクリプト言語を別の言語に変換しようとしているようです。これを正しく行うには、正規表現で管理できる以上のことが必要になります。

既存の構文解析システムを使用してスクリプトを管理することを強くお勧めします。これらの種類の外部性の多くを考慮し、動作する成熟した言語を作成するためです。たとえば、Lua は一般的な選択肢です。

あるいは、元のソース コードをツリーに変換して処理する適切なパーサーを作成し、それをたどって結果のコードを生成することもできます。

于 2013-08-14T20:09:10.133 に答える
1

質問を完全に理解しているかどうかわかりません。

コンパイラを作ろうとしていますか?友よ、それはそう簡単ではない。コンパイラは通常、次の 5 つの段階を経ます。

  • 字句解析
  • 解析中
  • セマンティック分析
  • 最適化
  • コード生成

字句解析段階を達成しようとしているように見えます。もしそうなら、このタスクを達成するために使用できる多くのプログラムがあります。これらのツールの 1 つは、C# LEX と呼ばれます。これは、コードを分析してトークンを吐き出すプログラムを生成するための優れたツールです。

以下は、LEX スクリプトの例です。

    %%

    ALPHABET = [a-zA-Z]*

    %%

    <YYINITIAL>{ALPHABET} { return ("STRING"); }

C# LEX は、この .lex ファイルを取得して解析します。次に、レクサーで指定された言語に適合するスクリプトを分析できる C# プログラムを生成します。

ありがとう、

于 2013-08-14T20:11:58.680 に答える
0

多くの時間を費やした後、なんとか正規表現を行うことができました。

したがって、コードがある場合:

if (0 == $Foo.Arr1[7 + Arr2_5[3-1] ].More[8].Yes-9) {
  // do something
} 

その場合、私は一致したいと思います$Foo.Arr1[7 + Arr2_5[3-1] ].More[8].Yes

次の正規表現はそれに一致します。

(?xi)
(?>
      (?<Q> "      )    # quote
    | (?<C> //     )    # comment
    | (?<N> [^"\$] )    # nothing
    | (?<D> \$     )    # dollar sign
)
(?(Q) .+? (\r|\n|$|") ) # if a quote is match continue selecting until you find next quote
(?(C) .+? (\r|\n|$)   ) # if a comment // or /* is match continue selecting until end of line
(?(N) (?=(?!))        )
(?(D)                   # if dollar sign is matched then:
  (

    (?(B)(?<-B>)){15}  # make sure group has a count of 0

    (?<V> [a-z|_]     ) # variable must start with letter of under score
    (?>
            (?<B>   \[        )                   # match [
       |    (       [^\s\)\(+\-@\#$%\^&\*=`~,\\\|\[\]] )  # or anything that is not a space, +, @ etc..
    )*
    (?(B)                                         # if you match a bracket then:
        (
           (?>
                    [^\[\]]
                 |    \[ (?<numberP>)                # balance match until opening ( = closing )
                 |    \] (?<-numberP>)
            )*
            \]
            (?(numberP)(?!))
            \.? 
        )
    )  # basically if you match a bracket keep selecting until you find even number of closing ]
  )
  +   # repeat this as many times as you can
)
(?(Q)(?!))   # Make regex fail if any of the following cases
(?(C)(?!))
(?(N)(?!))
于 2013-08-14T20:53:11.520 に答える