PEGKit 0.4.2

PEGKit 0.4.2

测试已测试
语言语言 Obj-CObjective C
许可 MIT
发布最新发布2014年12月

未命名 维护。



PEGKit 0.4.2

  • Todd Ditchendorf

PEGKit 是由 Todd Ditchendorf 在 Objective-C 中实现并受 Packrat parsing expression grammar 启发的开源工具包,适用于 iOS 和 OS X。它遵循 MIT 开源许可协议发布。

始终使用 Xcode 工作空间 PEGKit.xcworkspace,而不是 Xcode 项目。

此项目将 TDTemplateEngine 作为 Git 子模块包含。因此,正确克隆此项目需要添加 -r 参数。

git clone --recursive [email protected]:itod/pegkit.git

PEGKit 受 Terence Parr 的 ANTLR 和 Steven John Metsker 的 《Building Parsers with Java》的极大影响。

PEGKit 框架提供 2 个对 Cocoa 开发者来说有一般意义的基本服务

  1. 通过 Objective-C 的 PKTokenizerPKToken 类实现字符串分词
  2. 使用语法生成 Objective-C 解析器 - 从简单的、直观的且功能强大的 BNF 样式语法(类似于 yacc 或 ANTLR)生成 Objective-C 解析器类的源代码。在解析时,生成的解析器将向您的 Objective-C 代理提供回调。

PEGKit 源代码可在 GitHub 上找到

关于如何在 iOS 应用中使用 PEGKit 的教程可在 GitHub 上找到

历史

PEGKit 是同一作者早期框架的重写版,称为 ParseKit。ParseKit 通常被认为是过时的,并且应该使用 PEGKit 进行所有未来的开发。

  • ParseKit 在运行时生成 动态非确定性的解析器。ParseKit 生成的解析器表现出差的(指数级的)性能特征——尽管在罕见情况下它们具有一些有趣属性。

  • PEGKit 在设计时生成用于 确定性PEG)存储记忆的解析器的 静态 ObjC 源代码,您可以将其编译到您的项目中。PEGKit 生成的解析器表现出好的(线性的)性能特征。

文档

TODO

丢弃指令

后缀 ! 运算符可用于丢弃不用于计算结果的标记。

示例

addExpr = atom ('+'! atom)*;
atom = Number;

+ 标记对于计算匹配加法表达式的结果不是必要的,因此我们可以将其丢弃。

行为

动作是直接嵌入PEGKit语法规则中的小段Objective-C源代码。动作被大括号包围,并放在任何规则引用之后。

在任何一个动作中,都可用一个类型为PKAssemblyself.assembly对象作为一个栈(通过PUSH()POP()便利宏)。汇编的栈包含最近解析的标记(PKToken实例),并且也可用作计算结果时存储工作的位置。

动作在其前面的规则引用匹配后立即执行。因此,最近匹配的标记就在汇编栈的顶部。

示例 1

// matches addition expressions like `1 + 3 + 4`
addExpr  = atom plusAtom*;

plusAtom = '+'! atom
{
    PUSH_DOUBLE(POP_DOUBLE() + POP_DOUBLE());
};

atom     = Number
{
    // pop the double value of token on the top of the stack
    // and push it back as a double value 
    PUSH_DOUBLE(POP_DOUBLE()); 
};

示例 2

// matches or expressions like `foo or bar` or `foo || bar || baz`
orExpr = item (or item {
    id rhs = POP();
    id lhs = POP();
    MyOrNode *orNode = [MyOrNode nodeWithChildren:lhs, rhs];
    PUSH(orNode);
})*;
or    =  'or'! | '||'!;
item  = Word;

规则动作

  • @before - 此处放置设置代码。在开始解析此规则之前执行。
  • @after - 此处放置清理代码。在解析此规则结束后执行。

规则动作放在规则内部——在规则名称之后,但在=符号之前。

示例

// matches things like `-1` or `---1` or `--------1`

@extension { // this is a "Grammar Action". See below.
    @property (nonatomic) BOOL negative;
}

unaryExpr 
@before { _negative = NO; }
@after  {
    double d = POP_DOUBLE();
    d = (_negative) ? -d : d;
    PUSH_DOUBLE(d);
}
    = ('-'! { _negative = !_negative; })+ num;
num = Number;

语法动作

PEGKit有一个受ANTLR启发的功能,称为“语法动作”。语法动作是执行您想要的操作的一种方法:在各种位置插入您的解析器的.h和.m文件中的任意代码。它们必须放置在您的语法中规则列出之前的最顶部。

以下是所有当前可用的语法动作,以及它们在生成的解析器源代码中的插入位置的描述:

在.h文件中:

  • @h - .h文件顶部
  • @interface - 在头文件的@interface部分中

在.m文件中:

  • @m - .m文件顶部
  • @extension - 在.m文件中的私有类扩展@interface MyParser ()内部
  • @ivars - 在.m文件中@implementation MyParser {}内的私有实例变量
  • @implementation - 在您的解析器的@implementation部分内部。定义方法的地方。
  • @init - 在您的解析器的方法内部
  • @dealloc - 如果未启用ARC,则在您的解析器的dealloc方法内部
  • @before - 此处放置设置代码。在开始解析之前执行。
  • @after - 此处放置清理代码。在解析结束后执行。

(注意,这里列出的@before@after语法动作与可能也放置在每个单独规则中的@before@after是不同的。)