web-dev-qa-db-ja.com

トークンとルールの本当の違いは何ですか?

文法が組み込まれているために私はRakuに惹かれ、私はそれをいじって簡単なメールアドレスパーサーを作成すると思いましたが、問題が1つありました。

実際に機能するものに着陸する前に無数の反復を試みましたが、その理由を理解するのに苦労しています。

それが煮詰められたすべては、tokenruleに変更することでした。

これが私のサンプルコードです:

grammar Email {
  token TOP { <name> '@' [<subdomain> '.']* <domain> '.' <tld> }  
  token name { \w+ ['.' \w+]* }
  token domain { \w+ }
  token subdomain { \w+ }
  token tld { \w+ }
}
say Email.parse('[email protected]');

動作しません。単にNilを出力しますが、

grammar Email {
  rule TOP { <name> '@' [<subdomain> '.']* <domain> '.' <tld> }  
  token name { \w+ ['.' \w+]* }
  token domain { \w+ }
  token subdomain { \w+ }
  token tld { \w+ }
}
say Email.parse('[email protected]');

does機能し、正しく印刷されます

[email protected]」
 name => 「foo.bar」
 subdomain => 「baz」
 domain => 「example」
 tld => 「com」

変更したのは、token TOPからrule TOPだけです。

ドキュメントから収集できることから、これら2つのキーワードの唯一の違いは、空白はruleでは重要ですが、tokenでは重要ではないということです。それが本当なら、パターンの個々の部分の間の空白を無視したいので、最初の例はうまくいくはずです。

ピース間のスペースを削除する

rule TOP { <name>'@'[<subdomain>'.']*<domain>'.'<tld> }

動作を印刷Nilに戻します。

ここで何が起こっているのかを私に手がけることができる人は誰ですか?

[〜#〜] edit [〜#〜]:代わりにTOPルールをregexに変更すると、バックトラックが可能になり、機能します。

質問はまだ残っています。rule { }regex {:ratchet :sigspace }と同じ)が一致しないのに、なぜtoken { }regex {:ratchet }と同じ)が一致するのですか?

メールアドレスにはスペースが含まれていないため、すべての意図と目的のために、すぐに失敗するはずです

15
Electric Coffee

Raku docs に従って:

  • トークンメソッドは正規表現メソッドよりも高速で、空白を無視します。トークンメソッドはバックトラックしません。彼らは最初の可能な試合の後にあきらめます。
  • ルールメソッドは、空白が無視されないことを除いて、トークンメソッドと同じです。

無視されないということは、文字どおりに一致するのではなく、構文として扱われることを意味します。彼らは実際に<.ws>。詳細は sigspace を参照してください。

3
nvisser