我对向 ParseKit 语法添加动作的能力非常感兴趣。令人惊讶的是,关于这些操作中可用的内容的文档很少。假设我有两个规则,例如:
databaseName = Word;
createTableStmt ='CREATE' ('TEMP'| 'TEMPORARY')? 'TABLE' 'IF NOT EXISTS'? databaseName;
这显然不是一个完整的语法,但将作为一个例子。解析时,我想“返回”CreateTableStmt
具有某些属性的对象。如果我正确理解该工具,我会在规则中添加一个操作,然后将其推送到组件上,该组件将携带它以供下一个规则处理或使用。
例如,它看起来像:
createTableStmt ='CREATE' ('TEMP'| 'TEMPORARY')? 'TABLE' 'IF NOT EXISTS'? databaseName;
{
AnotherObj* dbName = Pop(); //gives me the top most object
CreateTableStmt* createTable = [[CreateTableStmt alloc] initWith:dbName];
//set if it was temporary
// set 'IF NOT EXISTS'
PUSH(createTable);//push back on stack for next rule to use
}
然后,当所有内容都被解析时,我可以将根对象从堆栈中取出,它是语法的完全实例化的自定义表示。如果我没记错的话,有点像构建 AST。然后,我可以使用该表示进行操作,而不是使用传入的字符串。
我的问题是如何查看它是否匹配('TEMP' | 'TEMPORARY')
,以便设置值。这些令牌在堆栈上吗?有没有比弹回“CREATE”并查看我们是否通过它更好的方法。我是否应该在每场比赛中弹回堆栈底部?
另外,如果我的规则是
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,但它的细微差别确实会给你带来麻烦。