2014-03-27 28 views
1

語法期間分析器,堆棧管理這是關係到Custom objects in ParseKit Actions用行動

如果我有一個語法規則,如第二個問題:

qualifiedTableName = (databaseName '.')? tableName (('INDEXED' 'BY' indexName) | ('NOT' 'INDEXED'))?; 

它是正確的假設,該行動將不會被調用直到規則匹配?所以在這種情況下,當動作被稱爲堆棧可能看起來像:

possibly: 
|'INDEXED' 
|'NOT' 
or: 
|indexName (A custom object possibly) 
|'BY' 
|'INDEXED 

|tableName (for sure will be here) 

and possibly these 
|'.'   (if this is here I know the database name must be here) if not push last one on? 
|databaseName 
--------------(perhaps more things from other rules) 

這些正確的評估?是否有任何其他文件的行動?我知道它主要基於Antlr,但它的細微差別可能會讓你陷入困境。

回答

1

PEGKit的創建者。

在前面的令牌匹配後立即執行動作

假設此輸入:

mydb.mytable INDEXED BY 'foo' 

你們的榜樣規則不包含任何操作,所以我會增加一些。這真的很容易,如果你您的規則分解成更小的子規則添加操作:

qualifiedTableName = name indexOpt 
{ 
    // now stack contains 3 `NSString`s. 
    // ["mydb", "mytable", "foo"] 
    NSString *indexName = POP(); 
    NSString *tableName = POP(); 
    NSString *dbName = POP(); 
    // do stuff here 
}; 

databaseName = Word; 
tableName = Word; 
indexName = QuotedString; 

name = (databaseName '.'!)? tableName 
{ 
    // now stack contains 2 `PKToken`s of type Word 
    // [<Word «mydb»>, <Word «mytable»>] 
    // pop their string values 
    NSString *tableName = POP_STR(); 
    NSString *dbName = POP_STR(); 
    PUSH(dbName); 
    PUSH(tableName); 
}; 

indexOpt 
    = index 
    | Empty { PUSH(@""); } 
    ; 

index 
    = ('INDEXED'! 'BY'! indexName) 
    { 
     // now top of stack will be a Quoted String `PKToken` 
     // […, <Quoted String «"foo"»>] 
     // pop its string value 
     NSString *indexName = POP_STR(); 
     // trim quotes 
     indexName = [indexName substringWithRange:NSMakeRange(1, [indexName length]-2)]; 
     // leave it on the stack for later 
     PUSH(indexName); 
    } 
    | ('NOT'! 'INDEXED'!) { PUSH(@""); } 
    ; 

請注意,我放棄所有使用!丟棄指令字面的令牌。這些文字是純粹的語法,在您的動作中不需要進一步處理。

另請注意,對於不存在的表達式或NOT INDEXED表達式,我將一個空字符串推入堆棧。這樣可以統一處理qualifiedTableName操作中的指定索引。在該Action中,您將始終在指定索引的堆棧頂部有一個字符串。如果它是一個空字符串,那麼就沒有索引。

+0

爲了我自己的理解,更改'name'規則以遵循相同的更細粒度的方法來提取'(databaseName'。')?'因爲您可能會彈出空對象。或者那可以嗎?例如解析您的示例而不使用「mydb」。會匹配正確,但數據庫名稱將是零謝謝! – utahwithak

+0

是的,你絕對正確。我肯定會打破這一點,以更容易地處理特定於數據庫的名稱的存在或不存在。 –