3

私はクライアントが非常に基本的なコードを作成できるようにするソリューションを構築しています。今ではいくつかの基本的な構文検証を行っていますが、変数の検証で立ち往生しています。

JSLintがJavascriptを使用してこれを行うことは知っていますが、これを行うための良い方法を誰かが知っているかどうか疑問に思っていました。

たとえば、ユーザーがコードを書いたとしましょう

moose = "barry"
base = 0
if(moose == "barry"){base += 100}

次に、「if」式が正しい構文にあることを明確にする方法を見つけようとしています。変数mooseが初期化されている場合などですが、文字ごとにスキャンせずにこれを実行したい場合、コードはミニ言語です。このアプリケーション専用に構築されているため、非常に基本的であり、メモリなどを管理する必要はありません。

最初にキャリッジリターンで分割し、次にスペースで分割することを考えていましたが、ユーザーが次のようなものを記述しない、moose="barry"またはif(moose=="barry") 条件の結果をインラインに保持しないと言うことは何もありません。

明らかに、コンパイラーとインタープリターはこれをはるかに大規模に実行しますが、文字ごとに実行するのか、どのように最適化するのかはわかりません。

(他のオプションは、それをPHPに返送して処理し、ブラウザーの責任を放棄することです)

助言がありますか?

ありがとう

ユースケースは限られており、この場合、構文は拡張されません。言語は、クライアントがユーザー入力に基づいて一意のコストを作成できるようにするための単純なスクリプト言語であり、計算を確実にするかどうかに関係なく、最終結果はPHPによって処理されます。エンドユーザーが調整したり、一貫性を確保したりすることはできません。

たとえば、基本コストが1.00ポンドで、フォームに「追加コスト」というフィールドがある場合、言語を使用すると、「追加コスト」フィールドに関連する基本コストを操作できます。

それで

base = 1;
if(additional > 100 && additional < 150){base += 50}
elseif(additional == 150){base *= 150}
else{base += additional;}

これは、言語がどのように使用されるかの基本的な例です。


すべての回答に感謝します。パーサーを調査しました。パーサーの作成は、数千行のコードでいくつかのテストを実行する場合よりもはるかに複雑であり、文字ごとに処理するのに数秒しかかからないことがわかりました。 512MBのメモリを備えたシングルコアP4(これは顧客が使用するよりはるかに少ない)

私は、JavaScriptの代わりにこれを使用して、情報をチェックし、変数などをチェックしながら(後で再コンパイルせずに呼び出す準備ができるように)有効なPHPコードに変換するPHPベースの構文チェッカーを構築することにしました。これはより適切なようです検証プロセスを妨げることなく、より複雑なコードを生成できるようになります

1時間しかかからず、ifステートメントの有効性をチェックでき、ネストされたif、スペース、または奇数の式と混同されないコードがあります。パーサーと本格的なスクリプト言語に対して、チェックする必要のあるものはほとんどありません。もっと長くかかったでしょう

あなたは私に考えることをたくさん与えてくれました、そして私は関連する答えを評価しましたありがとう

4

3 に答える 3

4

本当にこれを実行したい場合、つまり、ソフトウェアを適切かつ予測どおりに動作させたい場合は、「これを実行しない」という奇妙な特殊なケースをたくさん行わずに、実際のソフトウェアを作成する必要があります。あなたの言語のパーサー。それができたら、自分の言語の任意のプログラムをデータ構造に変換できます。このデータ構造を使用すると、少なくとも以前はuse-definitionおよびdefinition-use chain分析と呼ばれていた手順を含め、コードのあらゆる種類の分析を実行できます。

アプリケーションでスクリプトを作成できる「プログラミング言語」を作成すると、それがどんなに些細なことだと思っても、誰かがそれを使って驚くほど大きなプログラムを作成することになります。

JavaScriptパーサーを生成するすぐに利用できるパーサージェネレーターを知りません。再帰下降パーサーは書くのがそれほど難しくありませんが、維持するのが醜くなり、構文を拡張するのが少し難しくなります(特に、元のバージョンの作成にあまり経験がない場合)。

于 2010-12-27T16:59:50.057 に答える
2

Javascriptで、文法用のパーサーを生成するパーサージェネレーターであるJS/CCを確認することをお勧めします。BNFとEBNFを使用して言語を記述する方法を理解する必要があります。また、JS / CCには、文法を指定するための独自の構文(実際のBNF / EBNFにいくらか近い)があります。文法が与えられると、JS/CCはその文法のパーサーを生成します。

Pointyが言ったように、他のオプションは、独自のレクサーと再帰下降パーサーを最初から作成することです。BNF / EBNFがあれば、それほど難しくはありません。私は最近、JavaScriptでEBNFからパーサーを作成しました(文法は非常に単純だったので、1つのYMMVを作成するのはそれほど難しくありませんでした)。

それが「クライアント固有」であるというあなたのコメントに対処するため。ここに私自身の経験も追加します。スクリプト言語とスクリプト環境を提供している場合、実際のパーサーよりも優れたルートはありません。

大量のif-elsesを介して特殊なケースを処理することは、ひどく苦痛であり、メンテナンスの悪夢になります。大学1年生の時、自分の言語を書こうとしました。これは、再帰下降パーサー、または一般的なパーサーについて私が何かを知る前のことでした。私は、コードをトークンに分解できることを自分で理解しました。そこから、一連のif-elsesを使用し、トークンをスペースやその他の文字(正確に説明したもの)で分割して、非常に扱いにくいパーサーを作成しました。最終結果はひどいものでした。

再帰下降パーサーについて読んだら、自分の言語の文法を書き、元のパーサーを書くのにかかった時間の10分の1で簡単にパーサーを作成しました。真剣に、あなたがあなた自身に多くの苦痛を救いたいならば、実際のパーサーを書いてください。現在のルートをたどると、問題は永久に修正されます。人々がスペースを間違った場所に置いた場合、またはおそらくスペースが多すぎる(または少なすぎる)場合に対処する必要があります。他の唯一の選択肢は、非常に堅固な構造を提供することです(つまり、このステートメントの後に正確にx個のスペースが必要です)。これにより、スクリプト環境が非常に魅力的でなくなります。実際のパーサーは、これらすべての問題を自動的に修正します。

于 2010-12-27T18:10:58.723 に答える
1

Javascriptには関数'eval'があります。

var code = 'alert(1);';
eval(code);

アラートが表示されます。'eval'を使用して基本的なコードを実行できます。

于 2010-12-27T16:42:26.133 に答える