1

这是与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,但它的细微差别确实会给你带来麻烦。

4

1 回答 1

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(@""); }
    ;

请注意,我正在使用!丢弃指令丢弃所有文字标记。这些文字是纯语法,不需要在您的操作中进行进一步处理。

另请注意,在表达式不存在INDEXED BYNOT INDEXED表达式的情况下,我将一个空字符串压入堆栈。这样可以统一处理qualifiedTableNameAction中的指定索引。在该操作中,您将始终在堆栈顶部有一个指定索引的字符串。如果是空字符串,则没有索引。

于 2014-03-27T19:16:54.283 回答