Parsing 语法操作期间的解析器堆栈管理

Parsing 语法操作期间的解析器堆栈管理,parsing,parsekit,pegkit,Parsing,Parsekit,Pegkit,这是与此有关的第二个问题 如果我有语法规则,例如: qualifiedTableName = (databaseName '.')? tableName (('INDEXED' 'BY' indexName) | ('NOT' 'INDEXED'))?; 假设在匹配规则之前不会调用操作是否正确?因此,在这种情况下,调用堆栈的操作可能如下所示: possibly: |'INDEXED' |'NOT' or: |indexName (A custom object possibly) |'BY'

这是与此有关的第二个问题

如果我有语法规则,例如:

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

这里的创建者

在前面的令牌匹配后立即执行操作

假设此输入:

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(@""); }
    ;
qualifiedTableName=name indexOpt
{
//现在堆栈包含3个`NSString`s。
//[“mydb”、“mytable”、“foo”]
NSString*indexName=POP();
NSString*tableName=POP();
NSString*dbName=POP();
//在这里做事
};
databaseName=Word;
tableName=Word;
indexName=QuotedString;
名称=(数据库名称“.”!)?表名
{
//现在堆栈包含2个Word类型的'PKToken'
// [, ]
//弹出它们的字符串值
NSString*tableName=POP_STR();
NSString*dbName=POP_STR();
PUSH(dbName);
PUSH(表名);
};
索引的
=索引
|空{PUSH(@“”);}
;
指数
=('index'!'BY'!indexName)
{ 
//现在,堆栈顶部将是一个带引号的字符串`PKToken`
// […, ]
//弹出它的字符串值
NSString*indexName=POP_STR();
//删减引号
indexName=[indexName substringWithRange:NSMakeRange(1[indexName长度]-2)];
//把它放在书堆上待会儿用
PUSH(indexName);
}
|('NOT'!'index'!{PUSH(@');}
;
请注意,我正在使用
丢弃所有文字标记放弃指令。这些文字是纯语法的,在您的操作中不需要进行进一步的处理


还请注意,对于不存在的由
表达式索引的表达式或未索引的表达式,我将把一个空字符串推到堆栈上。这样,您就可以在
qualifiedTableName
操作中统一处理指定的索引。在该操作中,堆栈顶部将始终有一个字符串,用于指定索引。如果它是一个空字符串,那么就没有索引。

就我个人的理解而言,更改
名称
规则以遵循相同的更精细的方法来提取
(databaseName.')?
,因为可能会弹出一个空对象。或者这样可以吗?例如,不使用“mydb.”解析示例将正确匹配,但dbname将为零,谢谢!是的,你完全正确。为了更容易地处理db特定名称的存在或不存在,我肯定会将其打破。