2017-01-18 3 views
3

実際に何もせずにマッチツリーに物を挿入できるかどうか不思議でした。私が解決しようとしている問題はありません。実際に何も照合せずに名前付きキャプチャをマッチツリーに挿入できますか?

この例では、その一致がハッシュのキーであることを確認するトークンmarketがあります。私はそのハッシュの値を何とかマッチツリーに挿入しようとしていました。私はlong_market_stringと常に一致するトークンを持つことができたと思って、どういうわけかmarketが何を探していたのかを見てください。

grammar OrderNumber::Grammar { 
    token TOP { 
     <channel> <product> <market> <long_market_string> '/' <revision> 
     } 

    token channel { <[ M F P ]> } 
    token product { <[ 0..9 A..Z ]> ** 4 } 

    token market  { 
     (<[ A..Z ]>** 1..2) <?{ %Market_Shortcode{$0}:exists }> 
     } 

    # this should figure out what market matched 
    # I don't particularly care how this happens as long as 
    # I can insert this into the match tree 
    token long_market_string { <?> } 

    token revision { <[ A..C ]> } 
    } 

それが作成されているようMatchツリーを台無しにはいくつか方法はありますか?

私は物事を反転何か行うことができます:

grammar AppleOrderNumber::Grammar { 
    token TOP { 
     <channel> <product> <long_market_string> '/' <revision> 
     } 

    token channel { <[ M F P ]> } 
    token product { <[ 0..9 A..Z ]> ** 4 } 

    token market  { 
     (<[ A..Z ]>** 1..2) <?{ %Market_Shortcode{$0}:exists }> 
     } 
    token long_market_string { <market> } 
    token revision { <[ A..C ]> } 
    } 

をしかし、そのような場合を処理しています。私は、任意の数のものを挿入することにもっと興味があります。

答えて

1

トークンは一種のメソッドなので、トークンが行うすべての設定作業を行ったメソッドを作成した場合は、ほとんど何でもできます。

これは推測されておらず、現時点では容易ではありません。
(私はそれを把握するために、ソースコードで見て開始する場所の漠然とした考えを持っている)


あなたが簡単に行うことができますどのような結果
.made/.astに追加され(.madeとそれも、文法の内である必要はありません

$/ = grammar { 
    token TOP { 
    .* 
    { 
     make 'World' 
    } 
    } 
}.parse('Hello'); 

say "$/ $/.made()"; # Hello World 

.ast)は同義語です

'asdf' ~~ /{make 42}/; 
say $/;  # 「」 
say $/.made # 42 

あなたが一致ツリーが実際に想定されていない何かをしてにマッチツリーを破壊したいようですね事

grammar example-grammar { 
    token TOP { 
    [ <number> | <word> ]+ % \s* 
    } 
    token word { 
    <.alpha>+ 
    } 
    token number { 
    \d+ 
    { make +$/ } 
    } 
} 

class example-actions { 
    method TOP ($/) { make $/.pairs.map:{ .key => .value».made} } 
    method number ($/) { #`(already done in grammar, so this could be removed) } 
    method word ($/) { make ~$/ } 
} 

.say for example-grammar.parse(
    'Hello 123 World', 
    :actions(example-actions) 
).made».perl 

# :number([123]) 
# :word(["Hello", "World"]) 
+0

これは実際に私が求めているものに近いものではありません。そのすべては簡単です。私はトークンを持たないマッチツリーに他のものを挿入したい。 Matchオブジェクトには不変のビットがあるため、「ほとんど何もしない」ことはできません。 –

+0

@briandfoy Intは不変オブジェクトです。トークンがメソッドの一種だと言ったとき、メソッドから継承され、たくさんのものが追加されます。あなたが定期的な方法であなた自身の束を自分で行う場合、あなたはトークンが行うことができるすべてを絶対に行うことができます。私は、ほとんど一人で行う必要のないことを行うために、ソースコードを一週間以上見ようとは考えていません。私はあなたが尋ねる前にこれを同じことを何度もやろうとしましたが、時間を費やして時間の価値があるとは思っていませんでした。 –

+0

さて、私はすでにそれを知っていて、それについて議論していませんでした。あなたは同じことを試みたと言いました(私はあなたがそれをやり遂げることができなかったと推測していると思います)。しかし、あなた自身がやることは自明なことを私に信じさせているようにも聞こえます。そこにメッセージが混在しています。 –

0

このタイプのアクションクラスを使用するほとんどの時間をする。マッチツリーは、パーサによって生成された任意のデータではなく、入力文字列のどこにマッチした部分文字列を追跡します。任意のデータを追跡したい場合は、ASTツリーの何が問題になりますか?

確かに、マッチメソッドが正常に完了するとボトムアップ方式で構築されるため、ASTツリーは解析ツリーをミラーリングする必要があります。しかし、AST自体は、「任意のノードに接続されたオブジェクト」という意味では、それほど制限されていません。例えば考えてみましょう:マッチツリーはトップレベルのASTを構築するために使用した部品との子ノードを有している:ここでは

grammar G { 
    token TOP { <foo> <bar> {make "TOP is: " ~ $<foo> ~ $<bar>} } 
    token foo { foo {make "foo"} } 
    token bar { bar {make "bar"} } 
} 
G.parse("foobar"); 

$/.madeは単に「foobarのTOPがある」という文字列になります。その後、あなたの例に戻ると、我々はそれを行うことができます。

grammar G { 
    my %Market_Shortcode = :AA('Double A'); 
    token TOP { 
     <channel> <product> <market> 
     {} # Force the computation of the $/ object. Note that this will also terminate LTM here. 
     <long_market_string(~$<market>)> '/' <revision> 
     } 

    token channel { <[ M F P ]> } 
    token product { <[ 0..9 A..Z ]> ** 4 } 

    token market  { 
     (<[ A..Z ]>** 1..2) <?{ %Market_Shortcode{$0}:exists }> 
     } 

    token long_market_string($shortcode) { <?> { say 'c='~$shortcode; make %Market_Shortcode{$shortcode} } } 

    token revision { <[ A..C ]> } 
    } 

G.parse('M0000AA/A'); 

$<long_market_string>.astは今「ダブルA」になります。もちろん、私はtoken long_market_nameを省略し、ちょうどtoken marketのいずれかが%Market_Shortcode(または両方を一度に追跡したい場合は、短い名前と長い名前のMarketオブジェクト)にします。

この種のものの例は、Pythonの文法のようなものではありません。 Pythonのブロックレベルの構造は行ベースなので、文法(したがってマッチツリー)はこれを何らかの形で反映する必要があります。しかし、セミコロンで区切っていくつかの簡単なステートメントを1行にまとめることもできます。さて、おそらくブロックのASTをステートメントのリストにしたいのですが、1行のASTはそれ自体がいくつかのステートメントのリストになることがあります。したがって、ブロックのASTは、ブロックの文(例えば、ifwhileなど)をどのように表現するかに応じて、線のリスト(またはその行に沿ったもの)を一緒に(例えば)flatmapで作成します。

実際に、本当にはマッチツリーに厄介なことをしたいと思っています。 method long_market_nameで解析コードを実装する必要があります。そのAPIは文書化されておらず、内部的なものであり、nqp :: opsに落とされるものもあります。 hereに指されているものは、おそらく有用であろう。他の関連ファイルはRakudoレポのsrc/core/{Match,Cursor}.pmです。 Matchesの文字列化は、入力文字列から一致する部分文字列を抽出することによって計算されるので、文字列化を有効にするには、Matchをサブクラス化する必要があります。

+0

ASTツリーは、私が破壊しようとしているものです。しかし、本当にASTはありません。直接接続されていない「ast」というキーを持つ一致オブジェクトのツリーがあります。 ASTはマッチツリーと同じ構造を持つように強制されます。 –

+0

"ASTはマッチツリーと同じ構造になっています" –

+0

ASTはMatchオブジェクトに存在します。 –

関連する問題