Objective c ParseKit操作中的自定义对象

Objective c ParseKit操作中的自定义对象,objective-c,parsekit,pegkit,Objective C,Parsekit,Pegkit,我对在ParseKit语法中添加操作的能力非常感兴趣。令人惊讶的是,关于这些行动的可用文档很少。假设我有两条规则,比如: databaseName = Word; createTableStmt ='CREATE' ('TEMP'| 'TEMPORARY')? 'TABLE' 'IF NOT EXISTS'? databaseName; 这显然不是一个完整的语法,但将作为一个例子。解析时,我希望“返回”一个具有特定属性的CreateTableStmt对象。如果我正确理解该

我对在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
}
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)
然后,当所有内容都被解析后,我就可以从堆栈中获取根对象,它是语法的完全实例化的自定义表示。如果我没记错的话,有点像构建AST。然后,我可以使用该表示比使用传入的字符串更容易地进行操作

我的问题是如何查看它是否匹配
('TEMP'|'TEMPORARY')
,以便设置值。那些代币在堆栈上吗?有没有比跳回“CREATE”并查看我们是否通过它更好的方法。我是否应该在每一场比赛中都回到最底层

如果我的规则是

qualifiedTableName  = (databaseName '.')? tableName (('INDEXED' 'BY' indexName) | ('NOT' 'INDEXED'))?;
假设在匹配规则之前不会调用操作是否正确?因此,在这种情况下,调用堆栈的操作可能如下所示:

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
}
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的,但它的细微差别确实会让你陷入麻烦。

这里的创建者。一些项目:

ParseKit弃用: 就在本周,我将ParseKit分给了一个更干净/更小/更快的库,名为。ParseKit应该被认为是不推荐使用的,PEGKit应该用于所有新的开发。请移到佩吉

PEGKit与ParseKit的语法和代码生成功能几乎相同,您的ParseKit语法可以与PEGKit一起使用,只需做一些小改动。事实上,您的问题中的所有示例都是可用的,PEGKit中没有任何更改

还有这个

语法中的语法错误: 我在上面的语法示例中发现了3个语法错误(这同样适用于ParseKit和PEGKit)

  • 这一行:

    createTableStmt ='CREATE' ('TEMP'| 'TEMPORARY')? 'TABLE' 'IF NOT EXISTS'? databaseName;
    • 注意所有重要的
      丢弃指令,用于丢弃不需要的文字标记

    • 还请注意,我已将最后两条规则更改为使用
      | Empty
      ,而不是
      。这样,我就可以将操作添加到空的备选方案中(稍后您就会看到)

    然后,您可以向语法中添加操作,或者使用ObjC解析器委托回调,如果您喜欢在纯代码中工作的话

    如果您在语法中使用动作,以下类似操作将起作用:

    createTableStmt = 'CREATE'! tempOpt 'TABLE'! existsOpt databaseName ';'!
    {
        NSString *dbName = POP();
        BOOL ifNotExists = POP_BOOL();
        BOOL isTemp = POP_BOOL();
        NSLog(@"create table: %@, %d, %d", dbName, ifNotExists, isTemp);
        // go to town
        // myCreateTable(dbName, ifNotExists, isTemp);
    };
    
    databaseName = QuotedString
    {
        // pop the string value of the `PKToken` on the top of the stack
        NSString *dbName = POP_STR();
        // trim quotes
        dbName = [dbName substringWithRange:NSMakeRange(1, [dbName length]-2)];
        // leave it on the stack for later
        PUSH(dbName);
    };
    
    tempOpt 
        = ('TEMP'! | 'TEMPORARY'!) { PUSH(@YES); }
        | Empty { PUSH(@NO); }
        ;
    
    existsOpt 
        = ('IF'! 'NOT'! 'EXISTS'!) { PUSH(@YES); }
        | Empty { PUSH(@NO); }
        ;
    
    我有

    至于你的第二个问题,请把它作为一个新的SO问题,把它标记为
    ParseKit
    PEGKit
    ,我会尽快找到它。

    这里的创建者。一些项目:

    ParseKit弃用: 就在本周,我将ParseKit分给了一个更干净/更小/更快的库,名为。ParseKit应该被认为是不推荐使用的,PEGKit应该用于所有新的开发。请移到佩吉

    PEGKit与ParseKit的语法和代码生成功能几乎相同,您的ParseKit语法可以与PEGKit一起使用,只需做一些小改动。事实上,您的问题中的所有示例都是可用的,PEGKit中没有任何更改

    还有这个

    语法中的语法错误: 我在上面的语法示例中发现了3个语法错误(这同样适用于ParseKit和PEGKit)

  • 这一行:

    createTableStmt ='CREATE' ('TEMP'| 'TEMPORARY')? 'TABLE' 'IF NOT EXISTS'? databaseName;
    • 注意所有重要的
      丢弃指令,用于丢弃不需要的文字标记

    • 还请注意,我已将最后两条规则更改为使用
      | Empty
      ,而不是
      。这样,我就可以将操作添加到空的备选方案中(稍后您就会看到)

    然后,您可以向语法中添加操作,或者使用ObjC解析器委托回调,如果您喜欢在纯代码中工作的话

    如果您在语法中使用动作,以下类似操作将起作用:

    createTableStmt = 'CREATE'! tempOpt 'TABLE'! existsOpt databaseName ';'!
    {
        NSString *dbName = POP();
        BOOL ifNotExists = POP_BOOL();
        BOOL isTemp = POP_BOOL();
        NSLog(@"create table: %@, %d, %d", dbName, ifNotExists, isTemp);
        // go to town
        // myCreateTable(dbName, ifNotExists, isTemp);
    };
    
    databaseName = QuotedString
    {
        // pop the string value of the `PKToken` on the top of the stack
        NSString *dbName = POP_STR();
        // trim quotes
        dbName = [dbName substringWithRange:NSMakeRange(1, [dbName length]-2)];
        // leave it on the stack for later
        PUSH(dbName);
    };
    
    tempOpt 
        = ('TEMP'! | 'TEMPORARY'!) { PUSH(@YES); }
        | Empty { PUSH(@NO); }
        ;
    
    existsOpt 
        = ('IF'! 'NOT'! 'EXISTS'!) { PUSH(@YES); }
        | Empty { PUSH(@NO); }
        ;
    
    我有


    至于你的第二个问题,请把它作为一个新的SO问题,把它标记为
    ParseKit
    PEGKit
    ,我会尽快找到它。

    哇,这简直让我的解析思维崩溃了。刚开始看一个精通语法创作的人真的很酷。谢谢你详尽、清晰的回答。很棒的工具。选择了一个完美的时间开始更新。您是否有机会移植到演示应用程序或创建类似ANTLR的语法编辑器?谢谢!是的,是的。:)哇,这让我大吃一惊。刚开始看一个精通语法创作的人真的很酷。谢谢你详尽、清晰的回答。很棒的工具。选择了一个完美的时间开始更新。您是否有机会移植到演示应用程序或创建类似ANTLR的语法编辑器?谢谢!是的,是的。:)