3

私は自己変更ルールを調べており、セマンティクスとは正確には何なのか、そしてそれらがどのように機能するのか疑問に思っています。これはかなり幅広い質問ですが、具体的な「これを行うにはどうすればよいか」という質問を使用して、より焦点を絞った質問にします。 (^(64) は小文字の「d」の 16 進 ASCII であるため、検出されません)

rule: ["a" "b" (insert find rule "^(64)" "c" probe rule) "d" "e"]
parse "abcde" rule

それを実行すると、次のようになります (Rebol と Red の両方で):

["a" "b" (insert find rule "d" "c" probe rule) "c" "d" "e"]
== false

ルールは更新されたようで、かなり「安全に見える方法」で更新されました (安全と思われるものがある場合)。より邪悪なバージョンがあります:

rule: ["a" "b" (clear rule probe rule) "d" "e"]
parse "abcde" rule

Rebol と Red の両方で:

[]
== false

どのようにクラッシュしないのか、私はちょっと混乱しています。しかし、それが何らかの形で防弾されていると仮定すると、最初の例を機能させる方法はありますか?

4

3 に答える 3

2

これは機能します

>> rule: ["a" "b"  (insert first find rule block! "c" probe rule ) [] "d" "e"]
== ["a" "b" (insert first find rule block! "c" probe rule) [] "d" "e"]
>> parse "abcde" rule
["a" "b" (insert first find rule block! "c" probe rule) ["c"] "d" "e"]
== true

変更されていない最初のレベルのルール要素の数とルール カーソルの位置があるためです。2 番目のレベルは、入力時に読み込まれるようです。

これも効く

>> rule: ["a" "b"   (insert first find rule "d" "c" probe rule )  "d" "e"]
== ["a" "b" (insert first find rule "d" "c" probe rule) "d" "e"]
>> parse "abcde" rule
["a" "b" (insert first find rule "d" "c" probe rule) "cd" "e"]
== true

自己修正ルールの一般的な形式では、次のように変更または置換できるバリアントの下位レベル ルールを使用します。

sub_rule: []
rule: ["a" "b" (sub_rule: "c" probe rule) sub_rule "d" "e"]

parse "abcde" rule
["a" "b" (sub_rule: "c" probe rule) sub_rule "d" "e"]
 == true
于 2015-04-03T08:16:18.673 に答える
0

しかし、それが何らかの形で防弾されていると仮定すると...

R3-Alpha ではそうではなく、運が悪いと (系列展開を引き起こした場合など)、これを行うとクラッシュする可能性があります。#2214を参照してください:「実行中のPARSEルールを変更すると、ルールTAILを超えて実行され、クラッシュする可能性があります」

そのため、現在 PARSE によって処理されているルールを変更しないでください。ただし、ルールがその時点で実行されていない場合は、ルール内のネストされたルールを変更できます。

 subrule: ["c"]
 rule: ["a" (insert subrule "b") subrule]
 parse "abc" rule

これは、Ren-C ビルドでは、パーサーがルールをトラバースしている間、変更されないようにルールをロックすることによって形式化されています。パーサーの別のアプローチは、ルール内の各フェッチで長さをテストし、長さを超えている場合は中止することです。これによりクラッシュは回避できますが、複雑で危険な動作が発生し、料金を支払うことでパフォーマンスが低下します。

(同様の理由で、Ren-C では、現在実行中のブロックを DO で変更することもできません。ただし、実行されていないネストされた括弧グループを変更することで、上記の PARSE と同じ回避策を達成できます。)

rule: ["a" "b" (clear rule probe rule) "d" "e"]
parse "abcde" rule

どのようにクラッシュしないのか、私はちょっと混乱しています。

Rebol の R3-Alpha では、拡張して新しい割り当てが必要でない限り、シリーズのメモリを再利用しないため、この特定のケースはクラッシュしたり文句を言ったりしません。系列の先頭位置にターミネータを書き込み(「a」を上書き)、キャッシュ長を調整するだけです。PARSE は長さを無視し、END マーカーのみを探します。そのため、古くなったエンド マーカーが見つかるまで処理を続けました。

それを確認するには、次のことも試してみてください。

>> rule: ["a" "b" (clear rule) "c" "d" "e"]
== ["a" "b" (clear rule) "c" "d" "e"]

>> parse "abcde" rule
== true

基本的に、ガベージメモリにある値を使用しています。

于 2016-10-03T18:01:55.470 に答える