2017-01-18 53 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.ast是同義詞)

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

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

它甚至沒有成爲一個語法內

'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

這不是接近我問的,真的。所有這一切都很簡單。我想將其他東西插入沒有令牌的匹配樹中。你不能「做幾乎任何事情」,因爲匹配對象有不可變的位。 –

+0

@briandfoy一個Int也是一個不可變的對象。當我說一個標記是一種方法時,我的意思是它繼承了Method,並添加了一堆東西。如果你用一種常規的方法自己完成這些事情,那麼你可以做一切令牌可以做的事情。我不打算花一週或更長時間看源代碼來做幾乎沒有人需要做的事情。在你提出問題之前,我曾多次嘗試過這樣做,並且認爲花費數小時後它不值得。 –

+0

好的,但我已經知道,並沒有辯論這一點。你說過你試過同樣的事情(我想暗示你不能完成它),但這聽起來像是你試圖說服我自己做這件事很簡單。那裏有混合信息。 –

0

這聽起來像你想顛覆匹配樹成做一些匹配樹是不是真的應該去做。匹配樹會跟蹤輸入字符串中匹配哪些子字符串,而不是解析器生成的任意數據。如果你想跟蹤任意數據,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將只是字符串「TOP是:foobar的」,而匹配樹具有與被用來構建頂級AST組件的子節點。如果再回到你的例子,我們可以把它:

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,並且只需在%Market_Shortcode(或者同時包含短名稱和長名稱的市場對象,如果您想同時跟蹤兩者)中設置token market的AST即可。

這種事情的一個不那麼簡單的例子就像Python的語法。由於Python的塊級結構是基於行的,因此您的語法(因此匹配樹)需要以某種方式反映這一點。但是你也可以通過用分號分隔幾條簡單的陳述在一條線上。現在,您可能希望塊的AST成爲語句列表,而單行的AST本身可能是多個語句的列表。因此,您可以通過(例如)flatmap將線條列表(或沿着這些線條的東西,取決於您如何表示塊狀語句(如ifwhile))來構建塊的AST。

現在,如果你真的,真的,真的想要對比賽樹做令人討厭的事情,我敢肯定它可以做到,當然。你必須自己用method long_market_name來實現解析代碼,這個API是沒有記錄和內部的,並且可能至少會涉及到nqp :: ops。指向here的內容可能會有用。其他相關文件是Rakudo回購中的src/core/{Match,Cursor}.pm。還要注意,Matches的字符串化是通過從輸入字符串中提取匹配的子字符串來計算的,所以如果你希望它有用地進行字符串化,就必須繼承Match的子類。

+0

AST樹是我試圖顛覆。但是,真的不是AST。有一個匹配對象樹有一個名爲「ast」的鍵,它們不直接連接。 AST被迫與Match樹具有相同的結構。 –

+0

「AST被迫與Match樹具有相同的結構」吧? –

+0

AST存在於匹配對象中。 –

相關問題