TPL Grammar
This section describes the rules of TPL grammar.
Basic lexical rules
<id> ::= \$?[a-zA-Z_][a-zA-Z_0-9]*
<ids> ::= <id> ('.' <id>)*
<number> ::= 0x[0-9a-fA-F]+
| [0-9]+
<string> ::= ( '"' anything except newline or unescaped double quote '"'
| '"""' anything other than three double quotes '"""'
| \' anything except newline or unescaped single quote \'
| \'\'\' anything other than three single quotes \'\'\')
<qualified_string> ::= <string>
| <id> <base_string>
<bool> ::= true
| false
<uri> ::= [a-zA-Z]+':'[a-zA-Z0-9_.-%%3aNo.]+
<traversal> ::= <id>? ':' <id>?
| <traversal> ':' <id>?
<ids> ::= <id> ('.' <id>)*
<number> ::= 0x[0-9a-fA-F]+
| [0-9]+
<string> ::= ( '"' anything except newline or unescaped double quote '"'
| '"""' anything other than three double quotes '"""'
| \' anything except newline or unescaped single quote \'
| \'\'\' anything other than three single quotes \'\'\')
<qualified_string> ::= <string>
| <id> <base_string>
<bool> ::= true
| false
<uri> ::= [a-zA-Z]+':'[a-zA-Z0-9_.-%%3aNo.]+
<traversal> ::= <id>? ':' <id>?
| <traversal> ':' <id>?
Aliases for readability
<description> ::= <qualified_string>
<module_name> ::= <ids>
<tag_name> ::= <ids>
<pattern_name> ::= <id>
<table_name> ::= <id>
<identify_name> ::= <id>
<node_kind> ::= <id>
<attribute_name> ::= <id>
<variable> ::= <ids>
<scope> ::= <ids>
<function> ::= <ids>
<version_number> ::= <number> '.' <number>
<module_name> ::= <ids>
<tag_name> ::= <ids>
<pattern_name> ::= <id>
<table_name> ::= <id>
<identify_name> ::= <id>
<node_kind> ::= <id>
<attribute_name> ::= <id>
<variable> ::= <ids>
<scope> ::= <ids>
<function> ::= <ids>
<version_number> ::= <number> '.' <number>
Module structure
<module> ::= tpl <version_number> module <ids> ';'
<metadata>?
( <definition> ';' )+
<metadata> ::= metadata
( <id> := <qualified_string>+ )+
end metadata;
<definition> ::= <import>
| <pattern>
| <table>
| <identify>
<import> ::= from <module_name> import <id> <version_number> (as <id>)?
(',' <id> <version_number> (as <id>)?)*
<metadata>?
( <definition> ';' )+
<metadata> ::= metadata
( <id> := <qualified_string>+ )+
end metadata;
<definition> ::= <import>
| <pattern>
| <table>
| <identify>
<import> ::= from <module_name> import <id> <version_number> (as <id>)?
(',' <id> <version_number> (as <id>)?)*
Tags
<tags> ::= tags <tag_name> (',' <tag_name>)*
Top-level declarations
<pattern> ::= pattern <pattern_name> <version_number>
<description>
<metadata>?
<overview>
<constants>?
<triggers>
<pattern_body>
<removal>*
end pattern
<table> ::= table <table_name> <version_number>
<table_row>*
end table
<identify> ::= identify <identify_name> <version_number>
<tags> ';'
<node_kind> <attribute_name> (',' <attribute_name>)+
'->'
<attribute_name> (',' <attribute_name>)+ ';'
<table_row>*
end identify
<table_row> ::= <table_key> '->' <table_value> ';'
| default '->' <table_value> ';'
<table_key> ::= <table_value>
<table_value> ::= <constant_expression> (',' <constant_expression>)*
<description>
<metadata>?
<overview>
<constants>?
<triggers>
<pattern_body>
<removal>*
end pattern
<table> ::= table <table_name> <version_number>
<table_row>*
end table
<identify> ::= identify <identify_name> <version_number>
<tags> ';'
<node_kind> <attribute_name> (',' <attribute_name>)+
'->'
<attribute_name> (',' <attribute_name>)+ ';'
<table_row>*
end identify
<table_row> ::= <table_key> '->' <table_value> ';'
| default '->' <table_value> ';'
<table_key> ::= <table_value>
<table_value> ::= <constant_expression> (',' <constant_expression>)*
Overview
<overview> ::= overview
( <overview_entry> ';' )*
end overview
<overview_entry> ::= <implements>
| <overrides>
| <requires>
| <tags>
<overrides> ::= overrides <pattern_name> ( ',' <pattern_name> )*
<requires> ::= requires <pattern_name> ( ',' <pattern_name> )*
( <overview_entry> ';' )*
end overview
<overview_entry> ::= <implements>
| <overrides>
| <requires>
| <tags>
<overrides> ::= overrides <pattern_name> ( ',' <pattern_name> )*
<requires> ::= requires <pattern_name> ( ',' <pattern_name> )*
Constants
<constants> ::= constants
( <pattern_constant> )+
end constants ';'
<pattern_constant> ::= <id> ':=' <constant_expression> ';'
( <pattern_constant> )+
end constants ';'
<pattern_constant> ::= <id> ':=' <constant_expression> ';'
Triggers
<triggers> ::= triggers (scope <node_kind>)?
<trigger_condition>*
end triggers ';'
<trigger_condition> ::= on <trigger_match_list> ';'
<trigger_match_list> ::= <trigger_match_kind>
<trigger_match_kind> ::= <id> ':=' ( relationship )? <id> <trigger_fires_list>?
where <trigger_match>
<trigger_fires_list> ::= <trigger_fires> ( ',' <trigger_fires> )*
<trigger_fires> ::= created
| modified
| destroyed
| confirmed
<trigger_match> ::= <trigger_match_and>
<trigger_match_and> ::= <trigger_match_attribute>
| <trigger_match_and> and <trigger_match_attribute>
<trigger_match_attribute> ::= <id> '=' <constant_expression>
| <id> exists
| <id> in <constant_expression>
| <id> matches <constant_expression>
| '(' <trigger_match_and> ')'
<trigger_condition>*
end triggers ';'
<trigger_condition> ::= on <trigger_match_list> ';'
<trigger_match_list> ::= <trigger_match_kind>
<trigger_match_kind> ::= <id> ':=' ( relationship )? <id> <trigger_fires_list>?
where <trigger_match>
<trigger_fires_list> ::= <trigger_fires> ( ',' <trigger_fires> )*
<trigger_fires> ::= created
| modified
| destroyed
| confirmed
<trigger_match> ::= <trigger_match_and>
<trigger_match_and> ::= <trigger_match_attribute>
| <trigger_match_and> and <trigger_match_attribute>
<trigger_match_attribute> ::= <id> '=' <constant_expression>
| <id> exists
| <id> in <constant_expression>
| <id> matches <constant_expression>
| '(' <trigger_match_and> ')'
Body
<pattern_body> ::= body
<statements>
end body ';'
<statements>
end body ';'
Removal
<removal> ::= removal
on <variable> ':=' <node_kind> <removal_kind>
( where <trigger_match> )?';'
<statement_list>
end removal ';'
<removal_kind> ::= aged
| unconfirmed
on <variable> ':=' <node_kind> <removal_kind>
( where <trigger_match> )?';'
<statement_list>
end removal ';'
<removal_kind> ::= aged
| unconfirmed
Statements
<statement_list> ::= ( <statement> ';' )*
<statement> ::= <empty_statement>
| <assignment_statement>
| <function_call>
| <if_statement>
| <for_statement>
| <break_statement>
| <continue_statement>
| <stop_statement>
<empty_statement> ::=
<statement> ::= <empty_statement>
| <assignment_statement>
| <function_call>
| <if_statement>
| <for_statement>
| <break_statement>
| <continue_statement>
| <stop_statement>
<empty_statement> ::=
Assignment
<assignment_statement> ::= <lvalue_list> ':=' <logical_expression>
<lvalue_list> ::= <lvalue> ( ',' <lvalue> )*
<lvalue> ::= <ids>
| <lvalue> '[' <logical_expression> ']'
<lvalue_list> ::= <lvalue> ( ',' <lvalue> )*
<lvalue> ::= <ids>
| <lvalue> '[' <logical_expression> ']'
If
<if_statement> ::= if <logical_expression> then <statements>
(elif <logical_expression> then <statements>)*
(else <statements>)?
end if
(elif <logical_expression> then <statements>)*
(else <statements>)?
end if
For
<for_statement> ::= for <variable> in <logical_expression> do
<statements>
end for
<break_statement> ::= break
<continue_statement> ::= continue
<statements>
end for
<break_statement> ::= break
<continue_statement> ::= continue
Stop
<stop_statement> ::= stop
Functions
<function_call> ::= <function> '(' <arg_list>? ')'
<arg_list> ::= <arg_spec> (',' <arg_spec>)*
<arg_spec> ::= <logical_expression>
| <id> ':=' <logical_expression>
<arg_list> ::= <arg_spec> (',' <arg_spec>)*
<arg_spec> ::= <logical_expression>
| <id> ':=' <logical_expression>
Expand expression
<expand_expression> ::= expand '(' <arg_list> ')'
Expressions
<logical_expression> ::= <and_test>
| <logical_expression> or <and_test>
<and_test> ::= <not_test>
| <and_test> and <not_test>
<not_test> ::= <comparison>
| not <not_test>
<comparison> ::= <or_expression>
| <or_expression> <relational> <or_expression>
| '*' <relational> <or_expression>
| <or_expression> is? not? defined
<relational> ::= '<' | '<=' | '>' | '>=' | '=' | '<>' | in
| not in | has subword | has substring | matches
<or_expression> ::= <xor_expression>
| <or_expression> '|' <xor_expression>
<xor_expression> ::= <and_expression>
| <xor_expression> '^' <and_expression>
<and_expression> ::= <shift_expression>
| <and_expression> '&' <shift_expression>
<shift_expression> ::= <add_expression>
| <shift_expression> '<<' <add_expression>
| <shift_expression> '>>' <add_expression>
<add_expression> ::= <multiply_expression>
| <add_expression> '+' <multiply_expression>
| <add_expression> '-' <multiply_expression>
<multiply_expression> ::= <unary_expression>
| <multiply_expression> '*' <unary_expression>
| <multiply_expression> '/' <unary_expression>
| <multiply_expression> '%' <unary_expression>
<unary_expression> ::= <primary>
| '-' <unary_expression>
| '+' <unary_expression>
| '~' <unary_expression>
<constant_expression> ::= <logical_expression>
<primary> ::= <atom>
| <function_call>
| <search_expression>
| <expand_expression>
| <subscript>
| <list_expression>
| <attribute>
| <keyword_expression>
| <group_expression>
<subscript> ::= <primary> '[' <logical_expression> ']'
<list_expression> ::= '[' ( <logical_expression> ',' )* <logical_expression>? ']'
<scoped_attribute> ::= <scope> '.' <attribute>
<attribute> ::= <ids>
| <ids> '.' <key_expression>
<key_expression> ::= '#'
| '##'
| '#id'
| '#' <traversal>
| '#' <traversal> '.' <attribute>
| '#' <string> '(' <attributes> ')'
<keyword_expression> ::= structure
<group_expression> ::= '(' <expression> ( ',' <expression> )* ','? ')'
<atom> ::= none
| <bool>
| <qualified_string>
| <number>
| <logical_expression> or <and_test>
<and_test> ::= <not_test>
| <and_test> and <not_test>
<not_test> ::= <comparison>
| not <not_test>
<comparison> ::= <or_expression>
| <or_expression> <relational> <or_expression>
| '*' <relational> <or_expression>
| <or_expression> is? not? defined
<relational> ::= '<' | '<=' | '>' | '>=' | '=' | '<>' | in
| not in | has subword | has substring | matches
<or_expression> ::= <xor_expression>
| <or_expression> '|' <xor_expression>
<xor_expression> ::= <and_expression>
| <xor_expression> '^' <and_expression>
<and_expression> ::= <shift_expression>
| <and_expression> '&' <shift_expression>
<shift_expression> ::= <add_expression>
| <shift_expression> '<<' <add_expression>
| <shift_expression> '>>' <add_expression>
<add_expression> ::= <multiply_expression>
| <add_expression> '+' <multiply_expression>
| <add_expression> '-' <multiply_expression>
<multiply_expression> ::= <unary_expression>
| <multiply_expression> '*' <unary_expression>
| <multiply_expression> '/' <unary_expression>
| <multiply_expression> '%' <unary_expression>
<unary_expression> ::= <primary>
| '-' <unary_expression>
| '+' <unary_expression>
| '~' <unary_expression>
<constant_expression> ::= <logical_expression>
<primary> ::= <atom>
| <function_call>
| <search_expression>
| <expand_expression>
| <subscript>
| <list_expression>
| <attribute>
| <keyword_expression>
| <group_expression>
<subscript> ::= <primary> '[' <logical_expression> ']'
<list_expression> ::= '[' ( <logical_expression> ',' )* <logical_expression>? ']'
<scoped_attribute> ::= <scope> '.' <attribute>
<attribute> ::= <ids>
| <ids> '.' <key_expression>
<key_expression> ::= '#'
| '##'
| '#id'
| '#' <traversal>
| '#' <traversal> '.' <attribute>
| '#' <string> '(' <attributes> ')'
<keyword_expression> ::= structure
<group_expression> ::= '(' <expression> ( ',' <expression> )* ','? ')'
<atom> ::= none
| <bool>
| <qualified_string>
| <number>
Search expression
<search_expression> ::= search '('
<flags>?
<search_in>?
<kind_list>
<with_funcs>?
<where_clause>?
<traversals>?
<order_by_clause>?
<locale>?
<show>?
<search_process_with>?
')'
<flags> ::= flags '(' <id> ( ',' <id> )* ')'
<search_in> ::= in <id>
| in <string>
<kind_list> ::= '*'
| <kind_comma_list>
<kind_comma_list> ::= <node_kind> ( ',' <node_kind> )*
<flags>?
<search_in>?
<kind_list>
<with_funcs>?
<where_clause>?
<traversals>?
<order_by_clause>?
<locale>?
<show>?
<search_process_with>?
')'
<flags> ::= flags '(' <id> ( ',' <id> )* ')'
<search_in> ::= in <id>
| in <string>
<kind_list> ::= '*'
| <kind_comma_list>
<kind_comma_list> ::= <node_kind> ( ',' <node_kind> )*
with functions
<with_funcs> ::= with <with_func> ( ',' <with_func> )*
<with_func> ::= <id> '(' <search_expression_commalist> ')' as <id>
<with_func> ::= <id> '(' <search_expression_commalist> ')' as <id>
traversal
<traversals> ::= <traverse_or_expand>+
<traverse_or_expand> ::= <traverse_clause>
| <expand_clause>
| <step_in_clause>
| <step_out_clause>
<traverse_clause> ::= traverse <traversal> <with_funcs>? <where_clause>?
<expand_clause> ::= expand <traversal> <with_funcs>? <where_clause>?
<step_in_clause> ::= step in <traversal> <with_funcs>? <where_clause>?
<step_out_clause> ::= step out <traversal> <with_funcs>? <where_clause>?
<traverse_or_expand> ::= <traverse_clause>
| <expand_clause>
| <step_in_clause>
| <step_out_clause>
<traverse_clause> ::= traverse <traversal> <with_funcs>? <where_clause>?
<expand_clause> ::= expand <traversal> <with_funcs>? <where_clause>?
<step_in_clause> ::= step in <traversal> <with_funcs>? <where_clause>?
<step_out_clause> ::= step out <traversal> <with_funcs>? <where_clause>?
where
<where_clause> ::= where <search_logical_expression>
order by
<order_by_clause> ::= order by <order_by_commalist>
| order by taxonomy
<order_by_commalist> ::= <order_by> ( ',' <order_by> )*
<order_by> ::= <search_value_expression> <direction>?
<direction> ::= desc
| order by taxonomy
<order_by_commalist> ::= <order_by> ( ',' <order_by> )*
<order_by> ::= <search_value_expression> <direction>?
<direction> ::= desc
locale
<locale> ::= locale <string>
| locale <id>
| locale <id>
show
<show> ::= show <show_list>?
<show_list> ::= <show_clause> ( ',' <show_clause> )*
<show_clause> ::= <search_value_expression> <as>?
| explode <search_value_expression> <as>?
| summary
| '*'
<as> ::= as <id>
| as <string>
<search_logical_expression> ::= <search_and_expression>
| <search_logical_expression> or <search_and_expression>
<search_and_expression> ::= <search_and_expression>
| <search_and_expression> and <search_not_expression>
<search_not_expression> ::= <search_comparison>
| not <search_not_expression>
<search_comparison> ::= <search_value_expression> '=' <search_value_expression>
| <search_value_expression> '<>' <search_value_expression>
| <search_value_expression> >=' <search_value_expression>
| <search_value_expression> '>' <search_value_expression>
| <search_value_expression> '<=' <search_value_expression>
| <search_value_expression> '<' <search_value_expression>
| <search_value_expression> has subword <search_value_expression>
| <search_value_expression> has substring <search_value_expression>
| <search_value_expression> matches <search_value_expression>
| <search_value_expression> not matches <search_value_expression>
| <search_value_expression> in <search_value_expression>
| <search_value_expression> not in <search_value_expression>
| <search_value_expression> defined
| <search_value_expression> is defined
| <search_value_expression> not defined
| <search_value_expression> is not defined
| '*' '=' <search_value_expression>
| '*' has subword <search_value_expression>
| '*' has substring <search_value_expression>
| '*' matches <search_value_expression>
| <search_value_expression>
<search_value_expression> ::= <search_multiply_expression>
| <search_value_expression> '+' <search_multiply_expression>
| <search_value_expression> '-' <search_multiply_expression>
<search_multiple_expression>
::= <search_unary_expression>
| <search_multiply_expression> '/' <search_unary_expression>
| <search_multiply_expression> '*' <search_unary_expression>
<search_unary_expression> ::= <search_primary_expression>
| '-' <search_unary_expression>
<search_primary_expression> ::= <search_value>
| <id> '(' <search_expression_commalist>? ')'
| '[' <search_expression_commalist>? ']'
| '(' <search_logical_expression> ')'
<search_value> ::= nodecount '(' <traversals>? ')'
| nodes '(' <traversals>? ')'
| <number>
| <string>
| <search_attribute>
<search_attribute_commalist> ::= <search_attribute> ( ',' <search_attribute> )*
<search_attribute> ::= <id>
| <search_key_expression>
| <search_at_expression>
<search_key_expression> ::= '#'
| '##'
| '#id'
| '#' <traversal>
| '#' <traversal> '.' <search_attribute>
| '#' <string> '(' <search_attribute_commalist> ')'
<search_expression_commalist> ::=
<search_value_expression> ( ',' <search_value_expression> )*
<search_process_with> ::= processwith <search_process_with_func_list>
<search_process_with_func_list>
::= <search_process_with_func>
| <search_process_with_func_list> ',' <search_process_with_func>
<search_process_with_func> ::= <id>
| <id> '(' <search_expression_commalist>? ')'
<show_list> ::= <show_clause> ( ',' <show_clause> )*
<show_clause> ::= <search_value_expression> <as>?
| explode <search_value_expression> <as>?
| summary
| '*'
<as> ::= as <id>
| as <string>
<search_logical_expression> ::= <search_and_expression>
| <search_logical_expression> or <search_and_expression>
<search_and_expression> ::= <search_and_expression>
| <search_and_expression> and <search_not_expression>
<search_not_expression> ::= <search_comparison>
| not <search_not_expression>
<search_comparison> ::= <search_value_expression> '=' <search_value_expression>
| <search_value_expression> '<>' <search_value_expression>
| <search_value_expression> >=' <search_value_expression>
| <search_value_expression> '>' <search_value_expression>
| <search_value_expression> '<=' <search_value_expression>
| <search_value_expression> '<' <search_value_expression>
| <search_value_expression> has subword <search_value_expression>
| <search_value_expression> has substring <search_value_expression>
| <search_value_expression> matches <search_value_expression>
| <search_value_expression> not matches <search_value_expression>
| <search_value_expression> in <search_value_expression>
| <search_value_expression> not in <search_value_expression>
| <search_value_expression> defined
| <search_value_expression> is defined
| <search_value_expression> not defined
| <search_value_expression> is not defined
| '*' '=' <search_value_expression>
| '*' has subword <search_value_expression>
| '*' has substring <search_value_expression>
| '*' matches <search_value_expression>
| <search_value_expression>
<search_value_expression> ::= <search_multiply_expression>
| <search_value_expression> '+' <search_multiply_expression>
| <search_value_expression> '-' <search_multiply_expression>
<search_multiple_expression>
::= <search_unary_expression>
| <search_multiply_expression> '/' <search_unary_expression>
| <search_multiply_expression> '*' <search_unary_expression>
<search_unary_expression> ::= <search_primary_expression>
| '-' <search_unary_expression>
<search_primary_expression> ::= <search_value>
| <id> '(' <search_expression_commalist>? ')'
| '[' <search_expression_commalist>? ']'
| '(' <search_logical_expression> ')'
<search_value> ::= nodecount '(' <traversals>? ')'
| nodes '(' <traversals>? ')'
| <number>
| <string>
| <search_attribute>
<search_attribute_commalist> ::= <search_attribute> ( ',' <search_attribute> )*
<search_attribute> ::= <id>
| <search_key_expression>
| <search_at_expression>
<search_key_expression> ::= '#'
| '##'
| '#id'
| '#' <traversal>
| '#' <traversal> '.' <search_attribute>
| '#' <string> '(' <search_attribute_commalist> ')'
<search_expression_commalist> ::=
<search_value_expression> ( ',' <search_value_expression> )*
<search_process_with> ::= processwith <search_process_with_func_list>
<search_process_with_func_list>
::= <search_process_with_func>
| <search_process_with_func_list> ',' <search_process_with_func>
<search_process_with_func> ::= <id>
| <id> '(' <search_expression_commalist>? ')'
Tip: For faster searching, add an asterisk to the end of your partial query. Example: cert*