In order to build an if-else statement using JAPE grammar, it is not always required using Java in RHS.
When writing the rules, it can often be convenient to divide processing in multiple stages: each stage produces some results, which can then be passed to the next stages. So, based on what you just described, the data processing could be divided in the following three phases.
- RecordFinder, which returns the records within the document, ie
Record
annotations.
- TagFinder, which returns tags
a
and b
within the document.
- Intersection: it searches for tags
a
and b
within the records.
File Main.jape
MultiPhase: Main
Phases:
RecordFinder
TagFinder
Intersection
File RecordFinder.jape
This phase is able to annotate the records in your document. The only rule of this JAPE file reads tokens (ie Token
annotations returned by the tokeniser) as input and finds the records (ie tags record
) within the document, and finally it returns Record
annotations.
Note that, in the Options, the control is set as first, because the aim is to find the first occurrence of a sequence containing a token <record>
, followed by one or more other tokens, followed by a token </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" }
File TagFinder.jape
This phase reads tokens as input and finds tags a
and b
within the text, and finally it returns a
and b
annotations.
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" }
File Intersection.jape
This phase reads the annotations Record
, a
and b
as input and searches for tags a
or b
within Record
. Read this as reference about contains and within operators (I used one of these operators in the following rules).
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" }