为了使用 JAPE 语法构建 if-else 语句,并不总是需要在 RHS 中使用 Java。
在编写规则时,通常可以方便地将处理划分为多个阶段:每个阶段产生一些结果,然后可以将其传递给下一个阶段。所以,根据你刚才的描述,数据处理可以分为以下三个阶段。
-
RecordFinder,返回文档内的记录,即
Record注解。
-
TagFinder,在文档中返回标签
a 和b。
-
交集:在记录中搜索标签
a和b。
文件 Main.jape
MultiPhase: Main
Phases:
RecordFinder
TagFinder
Intersection
文件 RecordFinder.jape
此阶段能够对文档中的记录进行注释。这个JAPE文件的唯一规则是读取tokens(即tokeniser返回的Token注解)作为输入,并在文档中查找记录(即标签record),最后返回@987654330 @注解。
注意,在Options中,control被设置为first,因为目的是找到序列的第一个出现包含一个令牌<record>,后跟一个或多个其他令牌,然后是一个令牌</record>。
Phase: RecordFinder
Input: Token
Options: control = first debug = true
// The following rule is able to find the sentence within a record
Rule: RuleToFindRecord
(
({Token.string == "<"} {Token.string == "record"} ({Token})* {Token.string == ">"})
({Token})*
({Token.string == "<"} {Token.string == "/"} {Token.string == "record"} {Token.string == ">"})
):match
-->
:match.Record = { rule = "RuleToFindRecord" }
文件 TagFinder.jape
这个阶段读取tokens作为输入,在文本中找到标签a和b,最后返回a和b注解。
Phase: TagFinder
Input: Token
Options: control = first debug = true
// The following rule is able to find the tag "a" within the document.
Rule: RuleToFindTag_a
(
(
({Token.string == "<"} {Token.string == "a"} {Token.string == ">"})
({Token})*
({Token.string == "<"} {Token.string == "/"} {Token.string == "a"} {Token.string == ">"})
)
|
({Token.string == "<"} {Token.string == "a"} {Token.string == "/"} {Token.string == ">"})
):match
-->
:match.a = { rule = "RuleToFindTag_a" }
// The following rule is able to find the tag "b" within the document.
Rule: RuleToFindTag_b
(
(
({Token.string == "<"} {Token.string == "b"} {Token.string == ">"})
({Token})*
({Token.string == "<"} {Token.string == "/"} {Token.string == "b"} {Token.string == ">"})
)
|
({Token.string == "<"} {Token.string == "b"} {Token.string == "/"} {Token.string == ">"})
):match
-->
:match.b = { rule = "RuleToFindTag_b" }
文件Intersection.jape
此阶段读取注释Record、a 和b 作为输入,并在Record 中搜索标签a 或b。阅读 this 作为关于 contains 和 within 运算符的参考(我在以下规则中使用了这些运算符之一)。
Phase: Intersection
Input: Record a b
Options: control = first debug = true
// A record matches with this rule if it contains both tag a and tag b.
Rule: Rule_1
(
{Record contains a, Record contains b}
):match
-->
:match.Record_with_both_tags = { rule = "Rule_1" }
// A record matches with this rule if it contains tag a.
Rule: Rule_2
(
{Record contains a}
):match
-->
:match.Record_with_tag_a = { rule = "Rule_2" }