This repository was archived by the owner on Dec 12, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Document Notation
Derk Norton edited this page Sep 3, 2021
·
53 revisions
The follow sections define the formal language specification (using the ANTLR 4 language syntax) for the Bali Document Notation™.
This section defines the rules that are used to define components. For a graphical view of these rules click here.
component: value parameters? note?;
value: element | sequence | procedure;
parameters: '(' catalog ')';
note: NOTE;
sequence: '[' collection ']';
collection: range | list | catalog;
range: expression? connector=('<..<' | '<..' | '..<' | '..') expression?;
list:
expression (',' expression)* |
EOL (expression EOL)* |
/* no items */
;
catalog:
association (',' association)* |
EOL (association EOL)* |
':' /* no associations */
;
association: element ':' expression;
procedure: '{' code '}';
code:
statement (';' statement)* |
EOL (statement EOL)* |
/* no statements */
;
This section defines the rules that are used to define statements. For a graphical view of these rules click here.
statement: comment | mainClause handleClause?;
comment: NOTE | COMMENT;
mainClause:
evaluateClause |
saveClause |
discardClause |
signClause |
checkoutClause |
publishClause |
postClause |
retrieveClause |
acceptClause |
rejectClause |
ifClause |
selectClause |
withClause |
whileClause |
continueClause |
breakClause |
returnClause |
throwClause
;
handleClause: 'handle' symbol (('with' block) | ('matching' expression 'with' block)+);
block: '{' code '}';
evaluateClause: (recipient operator=(':=' | '+=' | '-=' | '*='))? expression;
// save document as $citation
saveClause: 'save' expression ('as' recipient)?;
// discard document
discardClause: 'discard' expression;
// sign contract as /acme/reports/Q3/v1.4
signClause: 'sign' expression 'as' expression;
// checkout level 2 of $contract from /acme/reports/Q3/v1.3.6
checkoutClause: 'checkout' ('level' expression 'of')? recipient 'from' expression;
// publish event
publishClause: 'publish' expression;
// post message to /acme/blogs/v3.2
postClause: 'post' expression 'to' expression;
// retrieve $message from /acme/blogs/v3.2
retrieveClause: 'retrieve' recipient 'from' expression;
// accept message
acceptClause: 'accept' expression;
// reject message
rejectClause: 'reject' expression;
ifClause: 'if' expression 'then' block ('else' 'if' expression 'then' block)* ('else' block)?;
selectClause: 'select' expression 'from' (expression 'do' block)+ ('else' block)?;
withClause: 'with' ('each' symbol 'in')? expression 'do' block;
whileClause: 'while' expression 'do' block;
continueClause: 'continue' 'loop';
breakClause: 'break' 'loop';
returnClause: 'return' expression?;
throwClause: 'throw' expression;
recipient: symbol | attribute;
attribute: variable '[' indices ']';
This section defines the rules that are used to define expressions. For a graphical view of these rules click here.
expression: // Precedence (highest to lowest)
component #componentExpression |
variable #variableExpression |
function '(' arguments ')' #functionExpression |
'(' expression ')' #precedenceExpression |
'@' expression #dereferenceExpression |
expression operator=('.' | '<-') message '(' arguments ')' #messageExpression |
expression '[' indices ']' #attributeExpression |
expression '&' expression #concatenationExpression |
expression '!' #factorialExpression |
<assoc=right> expression '^' expression #exponentialExpression |
operator=('-' | '/' | '*') expression #inversionExpression |
expression operator=('*' | '/' | '//' | '+' | '-') expression #arithmeticExpression |
'|' expression '|' #magnitudeExpression |
expression operator=('<' | '=' | '>' | 'IS' | 'MATCHES') expression #comparisonExpression |
'NOT' expression #complementExpression |
expression operator=('AND' | 'SANS' | 'XOR' | 'OR') expression #logicalExpression |
expression '?' expression #defaultExpression
;
variable: IDENTIFIER;
function: IDENTIFIER;
message: IDENTIFIER;
arguments:
expression (',' expression)* |
/* no expressions */
;
indices: expression (',' expression)*;
This section defines the rules that are used to define elements. For a graphical view of these rules click here.
element:
angle |
binary |
boolean |
duration |
moment |
name |
number |
pattern |
percentage |
probability |
resource |
symbol |
tag |
text |
version
;
angle: ANGLE;
binary: BINARY;
boolean: 'false' | 'true';
duration: DURATION;
moment: MOMENT;
name: NAME;
real: '-'? REAL;
imaginary: '-'? IMAGINARY;
number:
'undefined' |
'0' |
'∞' |
'infinity' |
real |
imaginary |
'(' real (',' imaginary | 'e^' angle 'i') ')'
;
pattern: 'none' | REGEX | 'any';
percentage: PERCENTAGE;
probability: FRACTION | '1.';
resource: RESOURCE;
symbol: SYMBOL;
tag: TAG;
text: QUOTE | NARRATIVE;
version: VERSION;
This section defines the rules that are used to define tokens. For a graphical view of these rules click here.
/* TOKEN RULES
It's important to remember that tokens are recognized by the
lexer in the order declared. The longest first matching token
is returned regardless of how many others might match. Also,
prefix any tokens that are just used as subtokens with the
"fragment" keyword.
*/
ANGLE: '~' ('0' | '-'? REAL);
BINARY: '\'' (BASE64 | SPACE)* ('=' ('=')?)? SPACE* '\'';
DURATION: '~' '-'? 'P' (SPAN 'W' | (SPAN 'Y')? (SPAN 'M')? (SPAN 'D')? ('T' (SPAN 'H')? (SPAN 'M')? (SPAN 'S')?)?);
FRACTION: '.' ('0'..'9')+;
PERCENTAGE: ('0' | '-'? REAL) '%';
// Note: An imaginary number must be higher precedence than a real number.
IMAGINARY: FLOAT 'i' | 'e i' | 'pi i' | 'π i' | 'phi i' | 'φ i' | 'tau i' | 'τ i';
REAL: FLOAT | 'e' | 'pi' | 'π' | 'phi' | 'φ' | 'tau' | 'τ';
MOMENT: '<' YEARS ('-' MONTHS ('-' DAYS ('T' HOURS (':' MINUTES (':' SECONDS FRACTION?)?)?)?)?)? '>';
NAME: ('/' LABEL)+;
RESOURCE: '<' LABEL ':' CONTEXT '>';
REGEX: '"' TEXT '"?';
SYMBOL: '$' IDENTIFIER ('-' NUMBER)?;
TAG: '#' BASE32*;
// Note: A narrative takes precedence over a quote and may contain any character.
NARRATIVE: '"' EOL CHARACTER*? EOL SPACE* '"';
QUOTE: '"' TEXT '"';
// Note: A version like 'v12' takes precedence over an identifier like 'value'.
VERSION: 'v' NUMBER ('.' NUMBER)*;
IDENTIFIER: ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'0'..'9')*;
NOTE: '--' ~[\r\n]*;
COMMENT: '/*' EOL (COMMENT | CHARACTER)*? EOL SPACE* '*/';
EOL: '\r'? '\n';
SPACE: ('\t'..'\r' | ' ') -> channel(HIDDEN);
fragment
TEXT: (ESCAPE | '\\"' | ~["\r\n])*?;
fragment
CHARACTER: .;
fragment
NUMBER: '1'..'9' ('0'..'9')*;
fragment
FLOAT: (NUMBER FRACTION? | '0' FRACTION) ('E' '-'? NUMBER)?;
fragment
INTEGER: '0' | '-'? NUMBER;
fragment
SPAN: INTEGER FRACTION?;
fragment
LABEL: ('a'..'z' | 'A'..'Z' | '0'..'9' | '+' | '-' | '.')+;
fragment
CONTEXT: ('!'..'=' | '?'..'~')*; // skip the space and '>' characters
fragment
YEARS: INTEGER;
fragment
MONTHS: (('0' '0'..'9') | ('1' '0'..'2'));
fragment
DAYS: (('0'..'2' '0'..'9') | ('3' '0'..'1'));
fragment
HOURS: (('0'..'1' '0'..'9') | ('2' '0'..'3'));
fragment
MINUTES: ('0'..'5' '0'..'9');
// Note: We must include 60 to handle leap seconds.
fragment
SECONDS: (('0'..'5' '0'..'9') | '60');
fragment
BASE16: '0'..'9' | 'A'..'F';
// Note: This avoids confusion and possible offensive strings by eliminating
// the 'E', 'I', 'O', and 'U' characters.
fragment
BASE32: '0'..'9' | 'A'..'D' | 'F'..'H' | 'J'..'N' | 'P'..'T' | 'V'..'Z';
fragment
BASE64: '0'..'9' | 'A'..'Z' | 'a'..'z' | '+' | '/';
// Note: The escaped sequences are replaced with actual characters when read.
fragment
ESCAPE: '\\' ('u' BASE16+ | 'b' | 'f' | 'r' | 'n' | 't' | '\\');