这是第二个与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的,但它的细微差别真的会给你带来麻烦。
在这里创建PEGKit。
动作在前面的令牌匹配之后立即执行。
假设输入如下:
mydb.mytable INDEXED BY 'foo'
您的示例规则没有包含任何Actions,所以我将添加一些。如果你把你的规则分解成更小的子规则,添加动作真的会容易得多:
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(@""); }
;
注意,我使用!
discard指令丢弃了所有的文字标记。这些字面量是纯语法,在Actions中不需要进行进一步处理。
还要注意,在不存在INDEXED BY
表达式或NOT INDEXED
表达式的情况下,我将一个空字符串压入堆栈。这样您就可以统一地处理qualifiedTableName
Action中的指定索引。在这个Action中,堆栈顶部总是有一个字符串,它指定了索引。如果是空字符串,则没有索引。