** (Advanced) ** Models a PEG Rule.** ** Rules are commonly created by using methods from the `Rules` mixin, but may be parsed from string patterns.** ** `Rule` *may* sub-classed to create your own custom rules. @Jsabstractclass Rule {** Creates a rule by parsing the given pattern:** ** syntax: fantom ** Rule.fromPattern("[abc] / [xyz]")** ** See `Peg.parseRule`staticnew parseRule(Str pattern){ PegGrammar().parseRule(pattern)}** The name of this rule. Only rules with names appear in debug output.** Should be legal Fantom identifier (think variable names!).virtual Str? name { set {if(!it.chars.first.isAlpha || it.chars.any { !it.isAlphaNum && it != '_' && it != '-'})throw ArgErr("Name must be a valid Fantom identifier: $it") &name = it}}** A label for this rule.virtual Str? label { set {if(!it.chars.first.isAlpha || it.chars.any { !it.isAlphaNum && it != '_' && it != '-'})throw ArgErr("Label must be a valid Fantom identifier: $it") &label = it}}** Disable debugging of this rule if it gets too noisy.virtual Bool debug := true** Not all rules are useful in the parsed AST. virtual Bool useInResult := true** Override to implement Rule logic. @NoDocabstract Bool doProcess(RuleCtx ctx)** Returns the PEG expression for this rule. Example:** ** [a-zA-Z0-9]abstract Str expression()** Returns the PEG definition for this rule. Example:** ** alphaNum <- [a-zA-Z0-9] Str definition(){if(name == null)return expression ex := nameif(!useInResult) ex = "-" + exif(!debug) ex = ex + "-"return"${ex} <- ${expression}"}** A helpful builder method for setting the name. This withName(Str name){this.name = namereturnthis}** A helpful builder method for setting the label. This withLabel(Str label){this.label = labelreturnthis}** A helpful builder method for turning debug off. This debugOff(){this.debug = falsereturnthis}** A helpful builder method for removing this rule from tree results. This excludeFromResults(){this.useInResult = falsereturnthis}** Matches this rule against the given string.** ** See `Peg.match` Match? match(Str str){ Peg(str, this).match} @NoDocvirtual Str typeName(){// if converting doProcess() to processFn then THIS method will need to be converted to another field name := typeof.name.decapitalizereturn name.endsWith("Rule") ? name[0..<-4] : name} @Operator @NoDocvirtual This add(Rule rule){throw Err("${typeof.qname} does not support add()")} @NoDocinternal Str _dis(Bool inner := false){ dis := inner && name == null && (thisis SequenceRule || thisis FirstOfRule) ? "(" + expression + ")" : (name ?: expression)return label != null ? "${label}:${dis}" : dis} @NoDocoverride Str toStr(){ _dis }}