bparser.2.13.5.source-code.BParser.scc Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bparser Show documentation
Show all versions of bparser Show documentation
Part of the ProB Parser library
The newest version!
Package de.be4.classicalb.core.parser;
/*******************************************************************
* Helpers *
*******************************************************************/
Helpers
all_chars = [0 .. 0xffff];
lf = 10;
cr = 13;
unicode_line_seperator = 8232; // \x2028
unicode_paragraph_seperator = 8233;
comment_start = '/*';
triple_quote = 39 39 39;
single_quote = 39;
minus = '-' | 0x2212;
// unicode_letter definition from java-1.7.sablecc by Etienne M. Gagnon, http://sablecc.org/java1.7/
// but removed unicode lambda 0x03bb from [0x03a3..0x03ce]
unicode_letter =
[[[0x0041..0x005a] + [0x0061..0x007a]] + [[0x00aa..0x00aa] + [0x00b5..0x00b5]]] |
[[[0x00ba..0x00ba] + [0x00c0..0x00d6]] + [[0x00d8..0x00f6] + [0x00f8..0x01f5]]] |
[[[0x01fa..0x0217] + [0x0250..0x02a8]] + [[0x02b0..0x02b8] + [0x02bb..0x02c1]]] |
[[[0x02d0..0x02d1] + [0x02e0..0x02e4]] + [[0x037a..0x037a] + [0x0386..0x0386]]] |
[[[0x0388..0x038a] + [0x038c..0x038c]] + [[[0x038e..0x03a1] + [0x03a3..0x03ba]] + [0x03bc..0x03ce]]] |
//[[[0x0388..0x038a] + [0x038c..0x038c]] + [[0x038e..0x03a1] + [0x03a3..0x03ce]]] | // removed unicode_lambda 0x03bb
[[[0x03d0..0x03d6] + [0x03da..0x03da]] + [[0x03dc..0x03dc] + [0x03de..0x03de]]] |
[[[0x03e0..0x03e0] + [0x03e2..0x03f3]] + [[0x0401..0x040c] + [0x040e..0x044f]]] |
[[[0x0451..0x045c] + [0x045e..0x0481]] + [[0x0490..0x04c4] + [0x04c7..0x04c8]]] |
[[[0x04cb..0x04cc] + [0x04d0..0x04eb]] + [[0x04ee..0x04f5] + [0x04f8..0x04f9]]] |
[[[0x0531..0x0556] + [0x0559..0x0559]] + [[0x0561..0x0587] + [0x05d0..0x05ea]]] |
[[[0x05f0..0x05f2] + [0x0621..0x063a]] + [[0x0640..0x064a] + [0x0671..0x06b7]]] |
[[[0x06ba..0x06be] + [0x06c0..0x06ce]] + [[0x06d0..0x06d3] + [0x06d5..0x06d5]]] |
[[[0x06e5..0x06e6] + [0x0905..0x0939]] + [[0x093d..0x093d] + [0x0958..0x0961]]] |
[[[0x0985..0x098c] + [0x098f..0x0990]] + [[0x0993..0x09a8] + [0x09aa..0x09b0]]] |
[[[0x09b2..0x09b2] + [0x09b6..0x09b9]] + [[0x09dc..0x09dd] + [0x09df..0x09e1]]] |
[[[0x09f0..0x09f1] + [0x0a05..0x0a0a]] + [[0x0a0f..0x0a10] + [0x0a13..0x0a28]]] |
[[[0x0a2a..0x0a30] + [0x0a32..0x0a33]] + [[0x0a35..0x0a36] + [0x0a38..0x0a39]]] |
[[[0x0a59..0x0a5c] + [0x0a5e..0x0a5e]] + [[0x0a72..0x0a74] + [0x0a85..0x0a8b]]] |
[[[0x0a8d..0x0a8d] + [0x0a8f..0x0a91]] + [[0x0a93..0x0aa8] + [0x0aaa..0x0ab0]]] |
[[[0x0ab2..0x0ab3] + [0x0ab5..0x0ab9]] + [[0x0abd..0x0abd] + [0x0ae0..0x0ae0]]] |
[[[0x0b05..0x0b0c] + [0x0b0f..0x0b10]] + [[0x0b13..0x0b28] + [0x0b2a..0x0b30]]] |
[[[0x0b32..0x0b33] + [0x0b36..0x0b39]] + [[0x0b3d..0x0b3d] + [0x0b5c..0x0b5d]]] |
[[[0x0b5f..0x0b61] + [0x0b85..0x0b8a]] + [[0x0b8e..0x0b90] + [0x0b92..0x0b95]]] |
[[[0x0b99..0x0b9a] + [0x0b9c..0x0b9c]] + [[0x0b9e..0x0b9f] + [0x0ba3..0x0ba4]]] |
[[[0x0ba8..0x0baa] + [0x0bae..0x0bb5]] + [[0x0bb7..0x0bb9] + [0x0c05..0x0c0c]]] |
[[[0x0c0e..0x0c10] + [0x0c12..0x0c28]] + [[0x0c2a..0x0c33] + [0x0c35..0x0c39]]] |
[[[0x0c60..0x0c61] + [0x0c85..0x0c8c]] + [[0x0c8e..0x0c90] + [0x0c92..0x0ca8]]] |
[[[0x0caa..0x0cb3] + [0x0cb5..0x0cb9]] + [[0x0cde..0x0cde] + [0x0ce0..0x0ce1]]] |
[[[0x0d05..0x0d0c] + [0x0d0e..0x0d10]] + [[0x0d12..0x0d28] + [0x0d2a..0x0d39]]] |
[[[0x0d60..0x0d61] + [0x0e01..0x0e2e]] + [[0x0e30..0x0e30] + [0x0e32..0x0e33]]] |
[[[0x0e40..0x0e46] + [0x0e81..0x0e82]] + [[0x0e84..0x0e84] + [0x0e87..0x0e88]]] |
[[[0x0e8a..0x0e8a] + [0x0e8d..0x0e8d]] + [[0x0e94..0x0e97] + [0x0e99..0x0e9f]]] |
[[[0x0ea1..0x0ea3] + [0x0ea5..0x0ea5]] + [[0x0ea7..0x0ea7] + [0x0eaa..0x0eab]]] |
[[[0x0ead..0x0eae] + [0x0eb0..0x0eb0]] + [[0x0eb2..0x0eb3] + [0x0ebd..0x0ebd]]] |
[[[0x0ec0..0x0ec4] + [0x0ec6..0x0ec6]] + [[0x0edc..0x0edd] + [0x0f40..0x0f47]]] |
[[[0x0f49..0x0f69] + [0x10a0..0x10c5]] + [[0x10d0..0x10f6] + [0x1100..0x1159]]] |
[[[0x115f..0x11a2] + [0x11a8..0x11f9]] + [[0x1e00..0x1e9b] + [0x1ea0..0x1ef9]]] |
[[[0x1f00..0x1f15] + [0x1f18..0x1f1d]] + [[0x1f20..0x1f45] + [0x1f48..0x1f4d]]] |
[[[0x1f50..0x1f57] + [0x1f59..0x1f59]] + [[0x1f5b..0x1f5b] + [0x1f5d..0x1f5d]]] |
[[[0x1f5f..0x1f7d] + [0x1f80..0x1fb4]] + [[0x1fb6..0x1fbc] + [0x1fbe..0x1fbe]]] |
[[[0x1fc2..0x1fc4] + [0x1fc6..0x1fcc]] + [[0x1fd0..0x1fd3] + [0x1fd6..0x1fdb]]] |
[[[0x1fe0..0x1fec] + [0x1ff2..0x1ff4]] + [[0x1ff6..0x1ffc] + [0x207f..0x207f]]] |
[[[0x2102..0x2102] + [0x2107..0x2107]] + [[0x210a..0x2113] + [0x2115..0x2115]]] |
[[[0x2118..0x211d] + [0x2124..0x2124]] + [[0x2126..0x2126] + [0x2128..0x2128]]] |
[[[0x212a..0x2131] + [0x2133..0x2138]] + [[0x3005..0x3005] + [0x3031..0x3035]]] |
[[[0x3041..0x3094] + [0x309b..0x309e]] + [[0x30a1..0x30fa] + [0x30fc..0x30fe]]] |
[[[0x3105..0x312c] + [0x3131..0x318e]] + [[0x4e00..0x9fa5] + [0xac00..0xd7a3]]] |
[[[0xf900..0xfa2d] + [0xfb00..0xfb06]] + [[0xfb13..0xfb17] + [0xfb1f..0xfb28]]] |
[[[0xfb2a..0xfb36] + [0xfb38..0xfb3c]] + [[0xfb3e..0xfb3e] + [0xfb40..0xfb41]]] |
[[[0xfb43..0xfb44] + [0xfb46..0xfbb1]] + [[0xfbd3..0xfd3d] + [0xfd50..0xfd8f]]] |
[[[0xfd92..0xfdc7] + [0xfdf0..0xfdfb]] + [[0xfe70..0xfe72] + [0xfe74..0xfe74]]] |
[[[0xfe76..0xfefc] + [0xff21..0xff3a]] + [[0xff41..0xff5a] + [0xff66..0xffbe]]] |
[[[0xffc2..0xffc7] + [0xffca..0xffcf]] + [[0xffd2..0xffd7] + [0xffda..0xffdc]]];
// not used yet:
//unicode_digit =
// [[[0x0030..0x0039] + [0x0660..0x0669]] + [[0x06f0..0x06f9] + [0x0966..0x096f]]] |
// [[[0x09e6..0x09ef] + [0x0a66..0x0a6f]] + [[0x0ae6..0x0aef] + [0x0b66..0x0b6f]]] |
// [[[0x0be7..0x0bef] + [0x0c66..0x0c6f]] + [[0x0ce6..0x0cef] + [0x0d66..0x0d6f]]] |
// [[[0x0e50..0x0e59] + [0x0ed0..0x0ed9]] + [[0x0f20..0x0f29] + [0xff10..0xff19]]];
unicode_superscripts = [0x2070..0x2079]; // TODO: add 185,178,179
unicode_subscripts = [0x2080..0x2089];
unicode_prime = [0x2032 + [8216..8217]]; // 0x2032=8242 ' primes / quotes // TODO: add hats
digit = ['0' .. '9'];
hexdigit = [[digit + ['a' .. 'f']] + ['A' .. 'F']];
line_break = [[[lf + cr] + unicode_line_seperator] + unicode_paragraph_seperator]; // newline
layout_char = [[9 + 32] + 160];
// 160: non-breaking space
white_space = line_break | layout_char+;
single_line_string_char = [all_chars - line_break];
string_literal = '"' ([single_line_string_char - ['"' + '\']] | '\' single_line_string_char)* '"';
// backquote to generate identifiers with special symbols or which clash with keywords
quoted_identifier_literal = '`' ([single_line_string_char - ['`' + '\']] | '\' single_line_string_char)* '`';
unicode_lambda = 0x03bb | 0x1d706; // 120582 in decimal; generated in Jupyter when pretty printing
regular_identifier_literal = (unicode_letter) (unicode_letter | unicode_lambda | digit | '_')* (unicode_subscripts)* (unicode_prime)*; // B identifiers, where we allow subscripts and Unicode quotes at the end
identifier_literal = regular_identifier_literal | quoted_identifier_literal;
pragma_prefix = '/*@' layout_char*;
pragma_identifier_literal = ([[0x21 .. 0x7e] - [['"' + '`'] + '*']] | unicode_letter)+;
// we could try and also allow '*', note: if we allow whitespace then the pragma keywords are no longer
// accepted due to the maximal munching
// versions below do not work:
// layout_char_with_ws = [[[0 .. 32] + [127..160]] + [[8206 .. 8207] + [8232 .. 8233]]];
// pragma_identifier_literal = ([all_chars - [layout_char_with_ws + '*']]+ ('*' [all_chars - [layout_char_with_ws + '/']])?)* '*'?;
/*******************************************************************
* States *
*******************************************************************/
States
// Initial state in which the lexer recognizes only keywords that start a model.
// The internal keywords for special parsing modes (#EXPRESSION, etc. - see below)
// are recognized only in this start state.
// This avoids conflicts with the symbol # (existential quantification) in regular B syntax.
// After the first keyword has been lexed,
// the parser switches to the normal state and never returns to the start state.
start,
normal,
// Multiline constructs (block comments, pragmas, multiline strings) have their own lexer states
// to provide better errors when the closing delimiter is missing.
// If e. g. block comments were parsed as a single token,
// then a long unclosed block comment would cause a pushback buffer overflow:
// the lexer first tries to lex the entire remaining text as a block comment,
// but once EOF is reached,
// it tries to backtrack all the way to the start of the comment.
// This is not an issue for line comments,
// because EOF is a valid line comment terminator.
block_comment,
multiline_string,
pragma_description_content,
pragma_content,
multiline_template;
/*******************************************************************
* Tokens *
*******************************************************************/
Tokens
{start->normal,normal} shebang = '#!' [all_chars - line_break]* line_break?;
{start->normal,normal} line_comment = '//' [all_chars - line_break]* line_break?;
{pragma_content->normal,pragma_description_content->normal} pragma_end = '*/';
{start->pragma_content,normal->pragma_content} pragma_generated = pragma_prefix 'generated'; // we could enforce nothing follows it
{start->pragma_content,normal->pragma_content} pragma_symbolic = pragma_prefix 'symbolic'; // ditto
{start->pragma_content,normal->pragma_content} pragma_label = pragma_prefix 'label';
{start->pragma_content,normal->pragma_content} pragma_file = pragma_prefix 'file';
{start->pragma_content,normal->pragma_content} pragma_package = pragma_prefix 'package';
{start->pragma_description_content,normal->pragma_description_content} pragma_description = pragma_prefix 'desc';
{start->pragma_content,normal->pragma_content} pragma_import_package = pragma_prefix 'import-package';
{start->block_comment,normal->block_comment} unrecognised_pragma = pragma_prefix;
// content of description pragma
// A single pragma_free_text token is either all whitespace or all non-whitespace.
// This simplifies removing leading/trailing whitespace from the description text later.
{pragma_description_content} pragma_free_text = [[all_chars - '*'] - [line_break + layout_char]]* | '*' | white_space;
// the pragma_content state collects attributes for label and file pragmas
{pragma_content} pragma_id_or_string = string_literal | pragma_identifier_literal;
{start->block_comment, normal->block_comment} comment = comment_start; // comment_start helper is a workaround to force SableCC to allow modifying text of comment tokens.
{block_comment->normal} comment_end = '*/';
{block_comment} comment_body = [all_chars - '*']*;
{block_comment} star = '*';
{normal->multiline_string} multiline_string_start = triple_quote;
{multiline_string->normal} multiline_string_end = triple_quote;
// One or two single quotes followed by a different character don't terminate the string.
{multiline_string} multiline_string_content = ((single_quote single_quote?)? [all_chars - [single_quote + '\']] | '\' all_chars)*;
{normal->multiline_template} multiline_template_start = '```';
{multiline_template->normal} multiline_template_end = '```';
// One or two backquotes followed by a different character don't terminate the string.
{multiline_template} multiline_template_content = (('`' '`'?)? [all_chars - ['`' + '\']] | '\' all_chars)*;
{normal} string_literal = string_literal;
{normal} for_any = '!' | 0x2200;
{normal} exists = '#' | 0x2203;
{normal} b_prime = '$0';
{normal} lambda = '%' | unicode_lambda;
{normal} conjunction = '&' | 0x2227; // 0x2227 Unicode wedge
{normal} illegal_unicode_symbol = 0x22c0 | // 0x22c0 = 8896 is n-ary conjunction, not normal conjunction
0x22c1 | // n-ary disjunction
0x2204 | // not exists
0x228e | // multi-set union bags
0x22a2 | 0x22a6 | 0x22a7 | // models / entails / sequent / turnstyle operators
0x21d0 | 0x27f8 | // inverse implies; we do not handle it in grammar because associativity not clear
0x220a | 0x220d; // small element of and contains operators
{normal} single_quotation = 39; // single quote: '
{normal} left_par = '('; // opening/left parenthesis
{normal} right_par = ')'; // closing/right parenthesis
{normal} product = '*' | 0x2217; // Unicode asterisk operator; used in Camille in Rodin
{normal} cartesian_product = 0x00d7 | // 215 decimal; used in rodin
0x2a2f; // vector or cross product, used in IDP-Z3
{normal} power_of = '**' | 0x02c4; // variation of ^ in Unicode; up-arrow used for sequence restrict_front below
{normal} plus = '+';
{normal} partial_function = '+' minus '>' | 0x21f8;
{normal} partial_surjection = '+' minus '>>' | 0x2900;
{normal} comma = ',';
{normal} minus = minus;
{normal} total_function = minus minus '>' | 0x2192;
{normal} total_surjection = minus minus '>>' | 0x21a0;
{normal} insert_start_sequence = minus '>' | 0x21fe;
{normal} dot = '.' ; // Ascii dot
{normal} dot2 = '·' | 0x22c5 | '•'; // is the bullet, Option-8 on US keyboards
// seperate from dot below to avoid shift-reduce conflicts for event-b comprehension with composed identifiers
{normal} interval = '..' | 0x2025;
{normal} division = '/' | 0xf7;
{normal} finite = '@finite'; // Event-B finite predicate (ProB-specific syntax)
{normal} partition = '@partition'; // Event-B partition predicate (ProB-specific syntax)
{normal} not_belonging = '/:' | 0x2209;
{normal} non_inclusion = '/<:' | 0x2288;
{normal} strict_non_inclusion = '/<<:' | 0x2284;
{normal} not_equal = '/=' | 0x2260;
{normal} set_subtraction = '\' | 0x2216; // decimal 8726, used in Rodin
{normal} intersection = '/\' | 0x2229;
{normal} restrict_head_sequence = '/|\' | 0x2191; // unicode uparrow for restrict_front operator
{normal} element_of = ':' | 0x2208;
{normal} double_colon = '::' | ':' 0x2208; /* becomes_element_of */
// Note TLA+ propses 0x2237 (PROPORTION) for label_as operator ::
{normal} assign = ':=' | 0x2254; //8788 decimal, used in Rodin and proposed for TLA+
{normal} semicolon = ';'; // separator, sequential composition and also forward composition (is 0x3b)
{normal} less = '<';
{normal} ring = 0x2218; // circ or backward composition from Event-B, normally not allowed by Atelier-B
{normal} less_greater = '<' white_space* '>'; // for empty sequence
{normal} overwrite_relation = '<+' | 0xe103 | 0x22d6; /* 0xe103 is EventB Style override, 0x22d6 is the AtelierB version */
{normal} set_relation = '<' minus '>' | 0x2194;
{normal} insert_end_sequence = '<-' | 0x21fd;
{normal} output_parameters = '<--' | 0x2190 | 0x27f5; // 2190: Leftwards Arrow; 27f5: Long Leftwards Arrow proposed in https://github.com/tlaplus-community/tlaplus-standard
{normal} inclusion = '<:' | 0x2286;
{normal} strict_inclusion = '<<:' | 0x2282 | 0x228a; // 0x228a actually less ambiguous mathematically, see
// https://math.stackexchange.com/questions/1038233/subset-of-above-not-equal-to-subsetneqq-symbol
{normal} superset = 0x2287; // no ASCII syntax
{normal} superset_strict = 0x2283; // no ASCII syntax
{normal} not_superset_strict = 0x2285 | 0x228b; // no ASCII syntax, 228b has struck-through equal sign
{normal} not_superset = 0x2289; // no ASCII syntax
{normal} contains_element = 0x220b; // no ASCII syntax, inverted element of symbol
{normal} not_contains_element = 0x220c; // no ASCII syntax
{normal} domain_subtraction = '<<|' | 0x2a64 | 0x25c0;
{normal} less_equal = '<=' | 0x2264;
{normal} equivalence = '<=>' | 0x21d4 | 0x27fa; // 0x21d4 is LEFT RIGHT DOUBLE ARROW; TLA proposes 0x27fa (LONG LEFT RIGHT DOUBLE ARROW) for iff
// there also is \equiv with 0x2261 (IDENTICAL TO)
{normal} domain_restriction = '<|' | 0x25c1;
{normal} equal = '=';
{normal} double_equal = '==' | 0x225c; // == , Unicode DELTA EQUAL TO proposed in https://github.com/tlaplus-community/tlaplus-standard
{normal} implies = '=>' | 0x21d2 | 0x27f9; // 0x21d2 is RIGHTWARDS DOUBLE ARROW; TLA proposes 0x27f9 (LONG RIGHTWARDS DOUBLE ARROW)
{normal} greater = '>';
{normal} partial_injection = '>+>' | 0x2914;
{normal} total_injection = '>' minus '>' | 0x21a3; // >->
{normal} partial_bijection = '>+>>';
{normal} total_bijection = '>' minus '>>' | 0x2916; // >->>
{normal} direct_product = '><' | 0x2297;
{normal} greater_equal = '>=' | 0x2265;
{normal} abstract_constants = 'ABSTRACT_CONSTANTS';
{normal} abstract_variables = 'ABSTRACT_VARIABLES';
{normal} any = 'ANY';
{normal} assert = 'ASSERT';
{normal} assertions = 'ASSERTIONS';
{normal} be = 'BE';
{normal} begin = 'BEGIN';
{normal} bool = 'BOOL'
| 0x1d539; // BOOL B bool_set symbol, similar to NATURAL N or INTEGER Z symbol; used by IDP-Z3
{normal} bfalse = 'bfalse' | 0x22A5; // falsity
{normal} case = 'CASE';
{normal} choice = 'CHOICE';
{normal} concrete_constants = 'CONCRETE_CONSTANTS';
{normal} concrete_variables = 'CONCRETE_VARIABLES';
{normal} constants = 'CONSTANTS';
{normal} constraints = 'CONSTRAINTS';
{start->normal,normal} definitions = 'DEFINITIONS';
{normal} expressions = 'EXPRESSIONS';
{normal} predicates = 'PREDICATES';
{normal} do = 'DO';
{normal} either = 'EITHER';
{normal} else = 'ELSE';
{normal} elsif = 'ELSIF';
{normal} end = 'END';
{normal} extends = 'EXTENDS';
{normal} false = 'FALSE'; // now reserved for falsity | 0x22a5;
{normal} fin = 'FIN';
{normal} fin1 = 'FIN1'; // add 'FIN'0x8321 ?
{normal} if = 'IF';
{start->normal,normal} implementation = 'IMPLEMENTATION';
{normal} imports = 'IMPORTS';
{normal} in = 'IN';
{normal} includes = 'INCLUDES';
{normal} initialisation = 'INITIALISATION' | 'INITIALIZATION'; /* amerikanische Version scheinbar auch erlaubt */
{normal} int = 'INT';
{normal} integer = 'INTEGER' | 0x2124;
{normal} real = 'REAL' | 0x211D;
{normal} float = 'FLOAT';
{normal} quantified_inter = 'INTER' | 0x22c2; // 0x22c2 is the n-ary intersection symbol
{normal} invariant = 'INVARIANT';
{normal} let = 'LET';
{normal} local_operations = 'LOCAL_OPERATIONS';
{start->normal,normal} machine = 'MACHINE';
{start->normal,normal} model = 'MODEL';
{start->normal,normal} system = 'SYSTEM'; /* SYSTEM fuer Event-B */
{normal} max_int = 'MAXINT';
{normal} min_int = 'MININT';
{normal} nat = 'NAT';
{normal} nat1 = 'NAT1';
{normal} natural = 'NATURAL' | 0x2115;
{normal} natural1 = 'NATURAL1' | 0x2115 0x0031 | 0x2115 0x2081;
{normal} of = 'OF';
{normal} operations = 'OPERATIONS' | 'EVENTS'; /* EVENTS fuer Event-B */
{normal} or = 'OR';
{normal} pi = 'PI' | 0x220f;
{normal} pow = 'POW' | 0x2119;
{normal} pow1 = 'POW1' | 0x2119 0x0031 | 0x2119 0x2081;
{normal} pre = 'PRE';
{normal} promotes = 'PROMOTES';
{normal} properties = 'PROPERTIES';
{normal} refines = 'REFINES';
{start->normal,normal} refinement = 'REFINEMENT';
{normal} sees = 'SEES';
{normal} select = 'SELECT';
{normal} sets = 'SETS';
{normal} sigma = 'SIGMA' | 0x2211;
{normal} string = 'STRING';
{normal} then = 'THEN';
{normal} true = 'TRUE'; // now reserved for truth: | 0x22a4
{normal} quantified_union = 'UNION' | 0x22c3; // 0x22c3 is the n-ary union symbol
{normal} uses = 'USES';
{normal} value = 'VALUES';
{normal} var = 'VAR';
{normal} variant = 'VARIANT';
{normal} variables = 'VARIABLES';
{normal} when = 'WHEN';
{normal} where = 'WHERE';
{normal} while = 'WHILE';
{normal} witness_kw = 'WITNESS';
{normal} left_bracket = '[';
{normal} right_bracket = ']';
{normal} union = '\/' | 0x222a;
{normal} restrict_tail_sequence = '\|/' | 0x2193;
{normal} concat_sequence = '^' | 0x2312;
{normal} bool_cast = 'bool';
{normal} card = 'card';
{normal} convert_int_floor = 'floor';
{normal} convert_int_ceiling = 'ceiling';
{normal} convert_real = 'real';
{normal} closure = 'closure';
{normal} closure1 = 'closure1'; // add 'closure' 0x8321 ?
{normal} conc = 'conc';
{normal} dom = 'dom';
{normal} first = 'first';
{normal} fnc = 'fnc';
{normal} front = 'front';
{normal} id = 'id';
{normal} generalized_inter = 'inter';
{normal} iseq = 'iseq';
{normal} iseq1 = 'iseq1'; // add 'iseq'0x8321 ?
{normal} iterate = 'iterate';
{normal} last = 'last';
{normal} max = 'max';
{normal} min = 'min';
{normal} mod = 'mod';
{normal} not = 'not' | 0x00ac;
{normal} logical_or = 'or' | 0x2228; // disjunction, 0x2228=8744 is Unicode vee inserted by macOS symbol table
{normal} perm = 'perm';
{normal} pred = 'pred';
{normal} prj1 = 'prj1';
{normal} prj2 = 'prj2';
{normal} prj1_v2 = '@prj1'; // prj1 which requires no arguments, typechecker infers type
{normal} prj2_v2 = '@prj2'; // ditto; TODO: find better keyword or detect prj1/prj2 differently
{normal} ran = 'ran';
{normal} rec = 'rec';
{normal} rel = 'rel';
{normal} rev = 'rev';
{normal} seq = 'seq';
{normal} seq1 = 'seq1'; // add | 'seq'0x8321 ?
{normal} size = 'size';
{normal} skip = 'skip';
{normal} struct = 'struct';
{normal} succ = 'succ';
{normal} tail = 'tail';
{normal} generalized_union = 'union';
{normal} empty_set = 0x2205;
{normal} left_brace = '{';
{normal} right_brace = '}';
{normal} vertical_bar = '|' | 0x2223; // Unicode divides; generated by Rodin
{normal} double_vertical_bar = '||' | 0x2225 | 0x2016; // 2225 Parallel To; 2016: Double Vertical Line
{normal} maplet = '|->' | 0x21a6; // TLA+ proposes 0x27fc (LONG RIGHTWARDS ARROW FROM BAR) for all_map_to |->
{normal} range_restriction = '|>' | 0x25b7;
{normal} range_subtraction = '|>>' | 0x2a65 | 0x25b6;
{normal} tilde = '~' | 0x223c | 0x207b 0xb9; // coming from Rodin
{normal} oftype = 0x2982; // coming from Rodin; we do not support the ASCII version oftype (yet)
// Extensions (see https://wiki.event-b.org/index.php/Rodin_Keyboard_User_Guide)
{normal} total_relation = '<<' minus '>' | 0xe100; // <<->
{normal} surjection_relation = '<' minus '>>' | 0xe101; // <->>
{normal} total_surjection_relation = '<<' minus '>>' | 0xe102; // <<->>
{normal} kw_freetypes = 'FREETYPES';
// keywords for special parsing modes;
// these # keywords do not interfere with normal parsing
{start->normal} kw_expression = '#EXPRESSION';
{start->normal} kw_predicate = '#PREDICATE';
{start->normal} kw_formula = '#FORMULA';
{start->normal} kw_substitution = '#SUBSTITUTION';
{start->normal} kw_oppattern = '#OPPATTERN';
{start->normal} kw_machine_clause = '#MACHINECLAUSE';
{normal} truth_predicate = 'btrue' | 0x22A4; // truth, no longer accept #truth_predicate
{start->normal,normal} identifier_literal = identifier_literal; // Also allowed in start state because of rules DSL - the RULES_MACHINE keyword is parsed as an identifier before RulesGrammar transforms it.
{normal} integer_literal = digit+;
{normal} real_literal = digit+ '.' digit+ ('E' | 'e') ('+' | '-')? digit+ | digit+ '.' digit+;
{normal} hex_literal = '0x' hexdigit+; // currently BLexer.java replaces THexLiteral with TIntegerLiteral
{normal} underscore = '_';
{start,normal,pragma_content} white_space = white_space;
// The following tokens are never recognized by the lexer because they are declared below identifier_literal.
// Dummy tokens for non-expression definitions.
// The corresponding syntax nodes are generated by Java code (by BLexer using PreParser definition list).
{normal} def_literal_substitution = identifier_literal;
{normal} def_literal_predicate = identifier_literal;
// Grammar extensions.
// The keywords should be synchronized with RulesGrammar.java.
{normal} kw_rule = 'RULE';
{normal} kw_substitution_operator = identifier_literal;
{normal} kw_predicate_operator = identifier_literal;
{normal} kw_expression_operator = identifier_literal;
{normal} kw_predicate_attribute = identifier_literal;
{normal} kw_attribute_identifier = identifier_literal;
{normal} kw_for = 'FOR';
{normal} kw_rule_for_all = 'RULE_FORALL';
{normal} kw_rule_fail = 'RULE_FAIL';
{normal} kw_rule_error_type = 'ERROR_TYPE';
{normal} kw_expect = 'EXPECT';
{normal} kw_computation = 'COMPUTATION';
{normal} kw_define = 'DEFINE';
{normal} kw_type = 'TYPE';
{normal} kw_value = 'VALUE';
{normal} kw_body = 'BODY';
{normal} kw_dummy_value = 'DUMMY_VALUE';
{normal} kw_on_success = 'ON_SUCCESS';
{normal} kw_counterexample = 'COUNTEREXAMPLE';
{normal} kw_function = 'FUNCTION';
{normal} kw_references = 'REFERENCES';
/*******************************************************************
* Ignored Tokens *
*******************************************************************/
Ignored Tokens
white_space,
comment, comment_body, star, comment_end,
unrecognised_pragma,
line_comment;
/*******************************************************************
* Productions *
*******************************************************************/
//[0,0] Production ... doesn't exist in section AST
// Such an error message indicates that a vertical bar '|' is followed by a semicolon ';'.
Productions
parse_unit {-> parse_unit} =
{machine} shebang? P.machine {-> machine.parse_unit} |
{definition_file} shebang? [clause]:definitions_clause {-> New parse_unit.definition_file(clause.machine_clause)} |
{predicate} kw_predicate [pred]:predicate_top {-> New parse_unit.predicate(pred.predicate)} |
{expression} kw_expression [expr]:expression_or_id_list {-> New parse_unit.expression(expr.expression)} |
{predformula} kw_formula [pred]:predicate_top {-> New parse_unit.predicate(pred.predicate)} |
{exprformula} kw_formula [expr]:expression_or_id_list {-> New parse_unit.expression(expr.expression)} |
{substitution} kw_substitution [subst]:substitution_l1 {-> New parse_unit.substitution(subst.substitution)} |
{oppattern} kw_oppattern [pattern]:operation_pattern {-> pattern.parse_unit} |
{machine_clause} kw_machine_clause [clause]:machine_clause {-> New parse_unit.machine_clause(clause.machine_clause)}; // used to single machine clauses
machine {-> parse_unit} =
machine_x {-> machine_x.parse_unit} |
{generated} pragma_generated pragma_end [lower]:P.machine {-> New parse_unit.generated(lower.parse_unit)} |
{package} pragma_package [package]:pragma_id_or_string pragma_end [imports]:import_package_list? [parse_unit]:P.machine
{-> New parse_unit.package(package, [imports.import_package], parse_unit.parse_unit)};
import_package_list {-> import_package*} =
{single} pragma_import_package [package_or_machine]:pragma_id_or_string pragma_end {-> [New import_package(package_or_machine)]} |
{multiple} [rest]:import_package_list pragma_import_package [package_or_machine]:pragma_id_or_string pragma_end {-> [rest.import_package, New import_package(package_or_machine)]};
machine_x {-> parse_unit} =
{abstract} [variant]: machine_variant [header]:machine_header [machine_clauses]:machine_clause_list? end {-> New parse_unit.abstract_machine(variant, header.machine_header, [machine_clauses.machine_clause])} |
{refinement} T.refinement [header]:machine_header refines [ref_machine]:identifier_literal [machine_clauses]:machine_clause_list? end {-> New parse_unit.refinement_machine(header.machine_header, ref_machine, [machine_clauses.machine_clause])} |
{implementation} T.implementation [header]:machine_header refines [ref_machine]:identifier_literal [machine_clauses]:machine_clause_list? end {-> New parse_unit.implementation_machine(header.machine_header, ref_machine, [machine_clauses.machine_clause])};
machine_variant {-> machine_variant} =
{machine} T.machine {-> New machine_variant.machine()} |
{model} T.model {-> New machine_variant.model()} |
{system} T.system {-> New machine_variant.system()};
machine_header {-> machine_header} =
[name]:composed_identifier [parameters]:machine_params? {-> New machine_header([name.identifier_literal], [parameters.expression])};
machine_params {-> expression*} = left_par [param_list]:machine_param_list right_par {-> [param_list.expression]};
machine_param_list {-> expression*} =
{single} [param]:machine_param {-> [param.expression]} |
{multi} [rest]:machine_param_list comma [first]:machine_param {-> [rest.expression, first.expression]};
machine_param {-> expression} = [parameter]:expression_in_par {-> parameter.expression};
machine_clause_list {-> machine_clause*} =
{single} [clause]:machine_clause {-> [clause.machine_clause]} |
{multiple} [rest]:machine_clause_list [clause]:machine_clause {-> [rest.machine_clause, clause.machine_clause]};
machine_clause {-> machine_clause} =
{definitions} [clause]:definitions_clause {-> clause.machine_clause} |
{constraints} [clause]:constraints_clause {-> clause.machine_clause} |
{sees} [clause]:sees_clause {-> clause.machine_clause} |
{promotes} [clause]:promotes_clause {-> clause.machine_clause} |
{uses} [clause]:uses_clause {-> clause.machine_clause} |
{includes} [clause]:includes_clause {-> clause.machine_clause} |
{extends} [clause]:extends_clause {-> clause.machine_clause} |
{imports} [clause]:imports_clause {-> clause.machine_clause} |
{sets} [clause]:sets_clause {-> clause.machine_clause} |
{constants} [clause]:constants_clause {-> clause.machine_clause} |
{abstract_constants} [clause]:abstract_constants_clause {-> clause.machine_clause} |
{properties} [clause]:properties_clause {-> clause.machine_clause} |
{concrete_variables} [clause]:concrete_variables_clause {-> clause.machine_clause} |
{variables} [clause]:variables_clause {-> clause.machine_clause} |
{assertions} [clause]:assertions_clause {-> clause.machine_clause} |
{initialisation} [clause]:initialisation_clause {-> clause.machine_clause} |
{local_operations} [clause]:local_operations_clause {-> clause.machine_clause} |
{operations} [clause]:operations_clause {-> clause.machine_clause} |
{values} [clause]:values_clause {-> clause.machine_clause} |
{invariant} [clause]:invariant_clause {-> clause.machine_clause} |
{freetypes} [clause]:freetypes_clause {-> clause.machine_clause} |
{references} [clause]:references_clause {-> clause.machine_clause} |
{expressions} [clause]:expressions_clause {-> clause.machine_clause} |
{predicate} [clause]:predicates_clause {-> clause.machine_clause};
expressions_clause {-> machine_clause} = expressions [expression_def_list]:expression_def_list semicolon?
{-> New machine_clause.expressions([expression_def_list.expression_definition])};
predicates_clause {-> machine_clause} = predicates [predicate_def_list]:predicate_def_list semicolon?
{-> New machine_clause.predicates([predicate_def_list.predicate_definition])};
definitions_clause {-> machine_clause} = definitions [definition_list]:definition_list semicolon? {-> New machine_clause.definitions([definition_list.definition])};
expression_def_list {-> expression_definition*} =
{single} [def]:expression_def {-> [def.expression_definition]} |
{multi} [rest]:expression_def_list semicolon [def]:expression_def {-> [rest.expression_definition, def.expression_definition]};
predicate_def_list {-> predicate_definition*} =
{single} [def]:predicate_def {-> [def.predicate_definition]} |
{multi} [rest]:predicate_def_list semicolon [def]:predicate_def {-> [rest.predicate_definition, def.predicate_definition]};
definition_list {-> definition*} =
{single} [def]:definition {-> [def.definition]} |
{multi} [rest]:definition_list semicolon [def]:definition {-> [rest.definition, def.definition]};
expression_def {-> expression_definition} =
[name]:identifier_literal [parameters]:def_parameters? double_equal [rhs]:expression_or_id_list
{-> New expression_definition(name, [parameters.expression], rhs.expression)};
predicate_def {-> predicate_definition} =
[name]:identifier_literal [parameters]:def_parameters? double_equal [rhs]:predicate_top
{-> New predicate_definition(name, [parameters.expression], rhs.predicate)};
definition {-> definition} =
{predicate} [name]:def_literal_predicate [parameters]:def_parameters? double_equal [rhs]:predicate_top
{-> New definition.predicate_definition(name, [parameters.expression], rhs.predicate)}
|
{substitution} [name]:def_literal_substitution [parameters]:def_parameters? double_equal [rhs]:substitution_l3
{-> New definition.substitution_definition(name, [parameters.expression], rhs.substitution)}
|
{expression} [name]:identifier_literal [parameters]:def_parameters? double_equal [rhs]:expression_or_id_list
{-> New definition.expression_definition(name, [parameters.expression], rhs.expression)}
|
{file} [filename]:string_literal
{-> New definition.file_definition(filename)};
normal_identifier_expression {-> expression} =
{identifier} [identifier]:identifier_literal {-> New expression.identifier([identifier])};
// a list of normal identifiers (without dot prefixes)
normal_identifier_expression_list {-> expression*} =
[first]:normal_identifier_expression [rest]:normal_identifier_expression_list_tail* {-> [first.expression, rest.expression]};
normal_identifier_expression_list_tail {-> expression} =
comma [expr]:normal_identifier_expression {-> expr.expression};
// allow either a top-level expression (with optional desc pragmas) or an identifier list (treated as a couple)
// Idea to allow identifier lists in DEFINITIONs:
// note: expression_list instead of normal_identifier_expression_list also works
// Note: it is also important to adapt kw_formula grammar rule to allow identifier lists
// as PreParser.java method determineType will parse rhs using this to determine type of definition
expression_or_id_list {-> expression} =
{id_list} [first]:normal_identifier_expression comma [rest]:normal_identifier_expression_list
{-> New expression.couple([first.expression, rest.expression])} |
{expr} [expr]:expression_top_with_opt_desc {-> expr.expression};
def_parameters {-> expression*} = left_par [parameters]:identifier_declaration_list right_par {-> [parameters.expression]};
sees_clause {-> machine_clause} = sees [machine_names]:machine_reference_no_params_list {-> New machine_clause.sees([machine_names.machine_reference_no_params])};
references_clause {-> machine_clause} = kw_references [machine_references]:machine_ref_list {-> New machine_clause.references([machine_references.machine_reference])};
promotes_clause {-> machine_clause} = promotes [operation_names]:operation_reference_list {-> New machine_clause.promotes([operation_names.operation_reference])};
uses_clause {-> machine_clause} = uses [machine_names]:machine_reference_no_params_list {-> New machine_clause.uses([machine_names.machine_reference_no_params])};
includes_clause {-> machine_clause} = includes [machine_references]:machine_ref_list {-> New machine_clause.includes([machine_references.machine_reference])};
extends_clause {-> machine_clause} = extends [machine_references]:machine_ref_list {-> New machine_clause.extends([machine_references.machine_reference])};
imports_clause {-> machine_clause} = imports [machine_references]:machine_ref_list {-> New machine_clause.imports([machine_references.machine_reference])};
machine_ref_list {-> machine_reference*} =
{single} [ref]:machine_reference {-> [ref.machine_reference]} |
{multi} [rest]:machine_ref_list comma [first]:machine_reference {-> [rest.machine_reference, first.machine_reference]};
machine_reference {-> machine_reference} =
{simple} [machine_reference]:machine_reference2 {-> machine_reference.machine_reference} |
{file} [machine_reference]:machine_reference2 pragma_file [file]:pragma_id_or_string pragma_end
{-> New machine_reference.file(machine_reference.machine_reference, file)};
machine_reference2 {-> machine_reference} =
{simple} [machine_name]:composed_identifier [parameters]:machine_params? {-> New machine_reference([machine_name.identifier_literal], [parameters.expression])};
machine_reference_no_params_list {-> machine_reference_no_params*} =
{single} [ref]:machine_reference_no_params {-> [ref.machine_reference_no_params]} |
{multi} [rest]:machine_reference_no_params_list comma [last]:machine_reference_no_params {-> [rest.machine_reference_no_params, last.machine_reference_no_params]};
machine_reference_no_params {-> machine_reference_no_params} =
{simple} [ref]:machine_reference_no_params2 {-> ref.machine_reference_no_params} |
{file} [ref]:machine_reference_no_params2 pragma_file [file]:pragma_id_or_string pragma_end {-> New machine_reference_no_params.file(ref.machine_reference_no_params, file)};
machine_reference_no_params2 {-> machine_reference_no_params} =
{simple} [machine_name]:composed_identifier {-> New machine_reference_no_params([machine_name.identifier_literal])};
operation_reference_list {-> operation_reference*} =
{single} [ref]:operation_reference {-> [ref.operation_reference]} |
{multi} [rest]:operation_reference_list comma [last]:operation_reference {-> [rest.operation_reference, last.operation_reference]};
operation_reference {-> operation_reference} = [operation_name]:composed_identifier {-> New operation_reference([operation_name.identifier_literal])};
description_pragma {-> description_pragma} =
pragma_description [parts]:pragma_free_text* pragma_end {-> New description_pragma([parts])};
variables_clause {-> machine_clause} =
{abstract} abstract_variables [identifiers]:identifier_declaration_list {-> New machine_clause.variables([identifiers.expression])} |
variables [identifiers]:identifier_declaration_list {-> New machine_clause.variables([identifiers.expression])};
constants_clause {-> machine_clause} =
{concrete} concrete_constants [identifiers]:identifier_declaration_list {-> New machine_clause.constants([identifiers.expression])} |
constants [identifiers]:identifier_declaration_list {-> New machine_clause.constants([identifiers.expression])};
concrete_variables_clause {-> machine_clause} = concrete_variables [identifiers]:identifier_declaration_list {-> New machine_clause.concrete_variables([identifiers.expression])};
abstract_constants_clause {-> machine_clause} = abstract_constants [identifiers]:identifier_declaration_list {-> New machine_clause.abstract_constants([identifiers.expression])};
sets_clause {-> machine_clause} = sets [set_definitions]:set_def_list {-> New machine_clause.sets([set_definitions.set])};
set_def_list {-> set*} =
{single} [set]:set {-> [set.set]} |
{multi} [rest]:set_def_list semicolon [last]:set {-> [rest.set, last.set]};
set {-> set} =
{description} [set]:set [description]:description_pragma {-> New set.description(description.description_pragma, set)} |
{deferred} [identifier]:composed_identifier {-> New set.deferred_set([identifier.identifier_literal])} |
{enumerated} [identifier]:composed_identifier equal left_brace [elements]:identifier_declaration_list right_brace {-> New set.enumerated_set([identifier.identifier_literal], [elements.expression])} |
{enumerated_set_via_def} [identifier]:composed_identifier equal [elem_def]:composed_identifier // covers: SETS Id = ED; DEFINITIONS ED == {a,b,c}
{-> New set.enumerated_set_via_def([identifier.identifier_literal], [elem_def.identifier_literal])};
// TO DO: allow description pragmas for enumerated set elements
properties_clause {-> machine_clause} = properties [predicates]:predicate_top {-> New machine_clause.properties(predicates.predicate)};
initialisation_clause {-> machine_clause} = initialisation [substitutions]:substitution_l1 {-> New machine_clause.initialisation(substitutions.substitution)};
invariant_clause {-> machine_clause} = invariant [predicates]:predicate_top {-> New machine_clause.invariant(predicates.predicate)};
constraints_clause {-> machine_clause} = constraints [predicates]:predicate_top {-> New machine_clause.constraints(predicates.predicate)};
assertions_clause {-> machine_clause} = assertions [predicates]:assertions_pred_list {-> New machine_clause.assertions([predicates.predicate])};
assertions_pred_list {-> predicate*} =
{single} [predicate]:predicate_top {-> [predicate.predicate]} |
{multi} [rest]:assertions_pred_list semicolon [predicate]:predicate_top {-> [rest.predicate, predicate.predicate]};
values_clause {-> machine_clause} = value [entries]:values_entries_list {-> New machine_clause.values([entries.values_entry])};
values_entries_list {-> values_entry*} =
{single} [entry]:values_entry {-> [entry.values_entry]} |
{multi} [rest]:values_entries_list semicolon [entry]:values_entry {-> [rest.values_entry, entry.values_entry]};
values_entry = [identifier]:composed_identifier equal [value]:expression_top_with_opt_desc
// one could allow expression_or_id_list here w/o creating shift/reduce conflicts
{-> New values_entry([identifier.identifier_literal], value.expression)};
local_operations_clause {-> machine_clause} = local_operations [operation_list]:operation_list {-> New machine_clause.local_operations([operation_list.operation])};
operations_clause {-> machine_clause} =
operations [operation_list]:operation_list {-> New machine_clause.operations([operation_list.operation])} |
{invalid_semicolon} operations [operation_list]:operation_list semicolon {-> New machine_clause.invalid_operations_clause(semicolon)};
operation_list {-> operation*} =
{single} [operation]:operation {-> [operation.operation]} |
{multi} [rest]:operation_list semicolon [operation]:operation {-> [rest.operation, operation.operation]} |
{missing_semicolon} [rest]:operation_list [operation]:operation {-> [rest.operation, New operation.missing_semicolon(operation)]};
operation {-> operation} =
{description} [operation]:operation [description]:description_pragma {-> New operation.description(description.description_pragma, operation)}
// this allows description pragmas at the very end of an operation, not before the equal (=) sign
|
{normal_operation} [return_values]:operation_return_values? [op_name]:composed_identifier [parameters]:op_params? equal [operation_body]:substitution_l2
{-> New operation([return_values.expression], [op_name.identifier_literal], [parameters.expression], operation_body.substitution)}
// Note: operation names can be composed identifiers within refinements, see section 7.23 in Atelier-B handbook
// TODO: allow also to use description pragmas here
|
{refined_operation} [return_values]:operation_return_values? [op_name]:composed_identifier [parameters]:op_params? [ref]:identifier_literal [ab_op_name]:identifier_literal equal [operation_body]:substitution_l2
{-> New operation.refined([return_values.expression], [op_name.identifier_literal], [parameters.expression], ref, ab_op_name , operation_body.substitution)}
// this supports the ref keyword for Event-B style refinement
|
{rule_operation} kw_rule [rule_name]:identifier_literal [attributes]:operation_attribute_list? kw_body [operation_body]:substitution_l0 end
{-> New operation.rule(rule_name, [attributes.operation_attribute], operation_body.substitution)} |
{computation} kw_computation [name]:identifier_literal [attributes]:operation_attribute_list? kw_body [body]:substitution_l0 end
{-> New operation.computation(name, [attributes.operation_attribute], body.substitution)}
|
{function} kw_function [return_values]:operation_return_values [name]:identifier_literal [parameters]:op_params? [attributes]:operation_attribute_list? kw_body [body]:substitution_l0 end
{-> New operation.function([return_values.expression], name, [parameters.expression], [attributes.operation_attribute], body.substitution)};
operation_attribute_list {-> operation_attribute*} =
{single} [attr]:operation_attribute {-> [attr.operation_attribute]} |
{multi} [rest]:operation_attribute_list [attr]:operation_attribute {-> [rest.operation_attribute, attr]};
operation_attribute {-> operation_attribute} =
{attribute} [name]:kw_attribute_identifier [arguments]:expression_list {-> New operation_attribute(name, [arguments.expression])} |
{predicate_attribute} [name]:kw_predicate_attribute [predicate]:predicate_top {-> New operation_attribute.predicate_attribute(name, predicate.predicate)};
operation_return_values {-> expression*} =
[return_values]:identifier_declaration_list output_parameters {-> [return_values.expression]};
freetypes_clause {-> machine_clause} = kw_freetypes [freetype_list]:freetype_list {-> New machine_clause.freetypes([freetype_list.freetype])};
freetype_list {-> freetype*} =
{single} [freetype]:freetype {-> [freetype.freetype]} |
{multi} [rest]:freetype_list semicolon [freetype]:freetype {-> [rest.freetype, freetype.freetype]} ;
freetype {-> freetype} = [name]:identifier_literal [parameters]:def_parameters? equal [cons_list]:freetypecons_list
{-> New freetype(name, [parameters.expression], [cons_list.freetype_constructor])};
freetypecons_list {-> freetype_constructor*} =
{single} [constructor]:freetypecons {-> [constructor.freetype_constructor]} |
{multi} [rest]:freetypecons_list comma [constructor]:freetypecons {-> [rest.freetype_constructor, constructor.freetype_constructor]};
freetypecons {-> freetype_constructor} =
{element} [name]:identifier_literal {-> New freetype_constructor.element(name)} |
{constructor} [name]:identifier_literal left_par [argument]:expression_in_par right_par {-> New freetype_constructor.constructor(name, argument.expression)};
/* Predicates */
predicate_top {-> predicate} = [pred]:predicate_p30 {-> pred.predicate};
predicate_p30 {-> predicate} =
{implication} [left]:predicate_p30 implies [right]:predicate_p40 {-> New predicate.implication(left.predicate, right.predicate)} | // rechtsassoziativ?
{next_level} [pred]:predicate_p40 {-> pred.predicate};
predicate_p40 {-> predicate} =
{disjunct} [left]:predicate_p40 logical_or [right]:predicate_x40 {-> New predicate.disjunct(left.predicate, right.predicate)} |
{conjunct} [left]:predicate_p40 conjunction [right]:predicate_x40 {-> New predicate.conjunct(left.predicate, right.predicate)} |
{next_level} [pred]:predicate_x40 {-> pred.predicate};
predicate_x40 {-> predicate} =
{label} pragma_label [name]:pragma_id_or_string pragma_end [predicate]:predicate_x40 {-> New predicate.label(name,predicate.predicate)} |
{next_level} [pred]:predicate_x41 {-> pred.predicate};
predicate_x41 {-> predicate} =
{description} [predicate]:predicate_p60 [description]:description_pragma
{-> New predicate.description(description.description_pragma, predicate.predicate)} |
{next_level} [pred]:predicate_x42
{-> pred.predicate};
predicate_x42 {-> predicate} = [pred]:predicate_p60 {-> pred.predicate};
predicate_p60 {-> predicate} =
{equivalence} [left]:predicate_p60 equivalence [right]:predicate_x60 {-> New predicate.equivalence(left.predicate, right.predicate)} |
{next_level} [pred]:predicate_x60 {-> pred.predicate};
predicate_x60 {-> predicate} = [pred]:predicate_atomic {-> pred.predicate};
/* The predicates of the following levels have completely moved down to the atomic level:
predicate_p110 {-> predicate} =
{next_level} [pred]:predicate_x110 {-> pred.predicate};
predicate_x110 {-> predicate} = [pred]:predicate_p160 {-> pred.predicate};
predicate_p160 {-> predicate} =
{next_level} [pred]:predicate_x160 {-> pred.predicate};
predicate_x160 {-> predicate} = [pred]:predicate_atomic {-> pred.predicate};
*/
predicate_atomic {-> predicate} =
// lhs_expression should really be assign_list and not expression_list,
// but that causes reduce/reduce conflicts with sequence extensions.
{subst} left_bracket [lhs_expression]:expression_list assign [rhs_expressions]:expression_list right_bracket [pred]:predicate_atomic
{-> New predicate.substitution(New substitution.assign([lhs_expression.expression], [rhs_expressions.expression]), pred.predicate) } | //weakest precondition
/* The following predicates have a priority in the AtelierB manual.
But we (in contrast to AtelierB) distinguish between predicates and expression and
can put the predicates of the form EXPR*EXPR -> PRED here.
Thus fewer parenthesis can be used */
/* Original priority: 60 */
{equal} [left]:expression_top equal [right]:expression_top {-> New predicate.equal(left.expression, right.expression)} |
{member} [left]:expression_top element_of [right]:expression_top {-> New predicate.member(left.expression, right.expression)} |
/* Original priority: 110 */
{subset} [left]:expression_top inclusion[right]:expression_top {-> New predicate.subset(left.expression, right.expression)} |
{subset_strict} [left]:expression_top strict_inclusion [right]:expression_top {-> New predicate.subset_strict(left.expression, right.expression)} |
{not_subset} [left]:expression_top non_inclusion [right]:expression_top {-> New predicate.not_subset(left.expression, right.expression)} |
{not_subset_strict} [left]:expression_top strict_non_inclusion [right]:expression_top {-> New predicate.not_subset_strict(left.expression, right.expression)} |
{superset} [left]:expression_top superset[right]:expression_top {-> New predicate.subset(right.expression, left.expression)} | // reverse arguments
{superset_strict} [left]:expression_top superset_strict[right]:expression_top {-> New predicate.subset_strict(right.expression, left.expression)} | // reverse arguments
{not_superset_strict} [left]:expression_top not_superset_strict[right]:expression_top {-> New predicate.not_subset_strict(right.expression, left.expression)} | // reverse arguments
{not_superset} [left]:expression_top not_superset[right]:expression_top {-> New predicate.not_subset(right.expression, left.expression)} | // reverse arguments
{contains_element} [left]:expression_top contains_element [right]:expression_top {-> New predicate.member(right.expression, left.expression)} | // reverse arguments
/* Original priority: 160 */
{not_equal} [left]:expression_top not_equal [right]:expression_top {-> New predicate.not_equal(left.expression, right.expression)} |
{not_member} [left]:expression_top not_belonging [right]:expression_top {-> New predicate.not_member(left.expression, right.expression)} |
{not_contains_element} [left]:expression_top not_contains_element [right]:expression_top {-> New predicate.not_member(right.expression, left.expression)} | // reverse arguments
{less_equal} [left]:expression_top less_equal [right]:expression_top {-> New predicate.less_equal(left.expression, right.expression)} |
{less} [left]:expression_top less [right]:expression_top {-> New predicate.less(left.expression, right.expression)} |
{greater_equal} [left]:expression_top greater_equal [right]:expression_top {-> New predicate.greater_equal(left.expression, right.expression)} |
{greater} [left]:expression_top greater [right]:expression_top {-> New predicate.greater(left.expression, right.expression)} |
/* Now we continue with the real atomic predicates: */
{bfalse} bfalse {-> New predicate.falsity()} |
{truth_predicate} truth_predicate {-> New predicate.truth()} |
{bracketed} left_par [predicate]:predicate_top right_par {-> predicate.predicate} |
{negation} not left_par [predicate]:predicate_top right_par {-> New predicate.negation(predicate.predicate)} |
{finite} finite left_par [set]:expression_in_par right_par {-> New predicate.finite(set.expression)} |
{partition} partition left_par [set]:expression_top [elements]:comma_expression_list? right_par {-> New predicate.partition(set.expression, [elements.expression])} |
{forall} for_any [identifiers]:quantified_variables_list dot left_par [implication]:predicate_top right_par {-> New predicate.forall([identifiers.expression], implication.predicate)}
| // check in typechecker: predicate must be an implication predicate
{forall2} for_any [identifiers]:quantified_variables_list dot2 left_par [implication]:predicate_top right_par {-> New predicate.forall([identifiers.expression], implication.predicate)}
| // version with alternate dot
{exists} exists [identifiers]:quantified_variables_list dot left_par [predicate]:predicate_top right_par {-> New predicate.exists([identifiers.expression], predicate.predicate)}
|
{exists2} exists [identifiers]:quantified_variables_list dot2 left_par [predicate]:predicate_top right_par {-> New predicate.exists([identifiers.expression], predicate.predicate)}
|
{definition} [def_literal]:def_literal_predicate [parameters]:def_call_params? {-> New predicate.definition(def_literal, [parameters.expression])}
|
{if_predicate} if [condition]:predicate_top then [then_pred]:predicate_top [elsifs]:if_elseif_predicate* else [else_pred]:predicate_top end
{-> New predicate.if_predicate(condition.predicate, then_pred.predicate, [elsifs.predicate], else_pred.predicate)} |
{let_predicate} let [identifiers]:identifier_declaration_list be [definition]:predicate_top in [pred]:predicate_top end
{-> New predicate.let_predicate([identifiers.expression], definition.predicate, pred.predicate)} |
{predicate_operator} [name]:kw_predicate_operator [parameters]:op_params {-> New predicate.operator(name,[parameters.expression])}; // extension
if_elseif_predicate {-> predicate} =
elsif [condition]:predicate_top then [pred]:predicate_top {-> New predicate.if_elsif_predicate(condition.predicate, pred.predicate)};
/* Expressions */
/* expression_in_par contains the priority level 20, it is not considered as expression_top
because ; and || should only be used inside parentheses */
expression_in_par {-> expression} =
{description} [expression]:expression_in_par2 [description]:description_pragma
/* we allow descriptions for expressions in parentheses; no ambiguity possible */
{-> New expression.description(description.description_pragma, expression.expression)} |
{next_level} [expr]:expression_in_par2
{-> expr.expression};
/* expressions inside (.) allowing ; and || operators */
expression_in_par2 {-> expression} =
{composition} [left]:expression_in_par semicolon [right]:expression_top
{-> New expression.composition(left.expression, right.expression)} |
{symbolic_composition} [left]:expression_in_par pragma_symbolic pragma_end semicolon [right]:expression_top
{-> New expression.symbolic_composition(left.expression, right.expression)} |
{parallel_product} [left]:expression_in_par double_vertical_bar [right]:expression_top
{-> New expression.parallel_product(left.expression, right.expression)} |
{next_level} [expr]:expression_top_with_opt_desc // using expression_or_id_list here leads to shit/reduce conflict
/* we allow descriptions for expressions inside parentheses, no ambiguity with predicates possible */
{-> expr.expression};
/* expressions top, with optional desc pragma, but without ; and || */
expression_top_with_opt_desc {-> expression} =
{description} [expression]:expression_top [description]:description_pragma
/* we allow descriptions for expressions, can be used when no ambiguity (e.g., with predicate desc) possible */
{-> New expression.description(description.description_pragma, expression.expression)} |
{next_level} [expr]:expression_p125
{-> expr.expression};
/* expressions top, without ; and || */
expression_top {-> expression} = [expr]:expression_p125 {-> expr.expression};
/*expression_p20 {-> expression} =
{parallel_product} left_par [left]:expression_p20 double_vertical_bar [right]:expression_x20 right_par {-> New expression.parallel_product(left.expression, right.expression)} | // zu sehr eingeschraenkt?!?
{next_level} [expr]:expression_x20 {-> expr.expression};
expression_x20 {-> expression} = [expr]:expression_p125 {-> expr.expression}; */
// Priority 125:
expression_p125 {-> expression} =
{relations} [left]:expression_p125 set_relation [right]:expression_p160 {-> New expression.relations(left.expression, right.expression)} |
{partial_function} [left]:expression_p125 partial_function [right]:expression_p160 {-> New expression.partial_function(left.expression, right.expression)} |
{total_function} [left]:expression_p125 total_function [right]:expression_p160 {-> New expression.total_function(left.expression, right.expression)} |
{partial_injection} [left]:expression_p125 partial_injection [right]:expression_p160 {-> New expression.partial_injection(left.expression, right.expression)} |
{total_injection} [left]:expression_p125 total_injection [right]:expression_p160 {-> New expression.total_injection(left.expression, right.expression)} |
{partial_surjection} [left]:expression_p125 partial_surjection [right]:expression_p160 {-> New expression.partial_surjection(left.expression, right.expression)} |
{total_surjection} [left]:expression_p125 total_surjection [right]:expression_p160 {-> New expression.total_surjection(left.expression, right.expression)} |
{partial_bijection} [left]:expression_p125 partial_bijection [right]:expression_p160 {-> New expression.partial_bijection(left.expression, right.expression)} |
{total_bijection} [left]:expression_p125 total_bijection [right]:expression_p160 {-> New expression.total_bijection(left.expression, right.expression)} |
{total_relation} [left]:expression_p125 total_relation [right]:expression_p160 {-> New expression.total_relation(left.expression, right.expression)} |
{surjection_relation} [left]:expression_p125 surjection_relation [right]:expression_p160 {-> New expression.surjection_relation(left.expression, right.expression)} |
{total_surjection_relation} [left]:expression_p125 total_surjection_relation [right]:expression_p160 {-> New expression.total_surjection_relation(left.expression, right.expression)} |
{next_level} [expr]:expression_p160 {-> expr.expression};
// Priority 160:
expression_p160 {-> expression} =
{overwrite} [left]:expression_p160 overwrite_relation [right]:expression_p170 {-> New expression.overwrite(left.expression, right.expression)} |
{direct_product} [left]:expression_p160 direct_product [right]:expression_p170 {-> New expression.direct_product(left.expression, right.expression)} |
{ring} [left]:expression_p160 ring [right]:expression_p170 {-> New expression.ring(left.expression, right.expression)} |
{concat} [left]:expression_p160 concat_sequence [right]:expression_p170 {-> New expression.concat(left.expression, right.expression)} |
{domain_restriction} [left]:expression_p160 domain_restriction [right]:expression_p170 {-> New expression.domain_restriction(left.expression, right.expression)} |
{domain_subtraction} [left]:expression_p160 domain_subtraction [right]:expression_p170 {-> New expression.domain_subtraction(left.expression, right.expression)} |
{range_restriction} [left]:expression_p160 range_restriction [right]:expression_p170 {-> New expression.range_restriction(left.expression, right.expression)} |
{range_subtraction} [left]:expression_p160 range_subtraction [right]:expression_p170 {-> New expression.range_subtraction(left.expression, right.expression)} |
{insert_front} [left]:expression_p160 insert_start_sequence [right]:expression_p170 {-> New expression.insert_front(left.expression, right.expression)} |
{insert_tail} [left]:expression_p160 insert_end_sequence [right]:expression_p170 {-> New expression.insert_tail(left.expression, right.expression)} |
{union} [left]:expression_p160 union [right]:expression_p170 {-> New expression.union(left.expression, right.expression)} |
{intersection} [left]:expression_p160 intersection [right]:expression_p170 {-> New expression.intersection(left.expression, right.expression)} |
{restrict_front} [left]:expression_p160 restrict_head_sequence [right]:expression_p170 {-> New expression.restrict_front(left.expression, right.expression)} |
{restrict_tail} [left]:expression_p160 restrict_tail_sequence [right]:expression_p170 {-> New expression.restrict_tail(left.expression, right.expression)} |
{couple1} [left]:expression_p160 maplet [right]:expression_p170 {-> New expression.couple([left.expression, right.expression])} |
{next_level} [expr]:expression_p170 {-> expr.expression};
// Priority 170:
expression_p170 {-> expression} =
{interval} [left_border]:expression_p170 interval [right_border]:expression_p180 {-> New expression.interval(left_border.expression, right_border.expression)} |
{next_level} [expr]:expression_p180 {-> expr.expression};
// Priority 180:
expression_p180 {-> expression} =
{minus_or_set_subtract} [left]:expression_p180 minus [right]:expression_p190 {-> New expression.minus_or_set_subtract(left.expression, right.expression)} |
{add} [left]:expression_p180 plus [right]:expression_p190 {-> New expression.add(left.expression, right.expression)} |
{set_subtraction} [left]:expression_p180 set_subtraction [right]:expression_p190 {-> New expression.set_subtraction(left.expression, right.expression)} |
{next_level} [expr]:expression_p190 {-> expr.expression};
// Priority 190:
expression_p190 {-> expression} =
{mul} [left]:expression_p190 product [right]:expression_p200 {-> New expression.mult_or_cart(left.expression, right.expression)} |
{mulcart} [left]:expression_p190 cartesian_product [right]:expression_p200 {-> New expression.cartesian_product(left.expression, right.expression)} |
{div} [left]:expression_p190 division [right]:expression_p200 {-> New expression.div(left.expression, right.expression)} |
{modulo} [left]:expression_p190 mod [right]:expression_p200 {-> New expression.modulo(left.expression, right.expression)} |
{next_level} [expr]:expression_p200 {-> expr.expression};
// Priority 200:
/* Attention: power_of is right-assoziative! */
expression_p200 {-> expression} =
{power_of} [left]:expression_x200 power_of [right]:expression_p200 {-> New expression.power_of(left.expression, right.expression)} | // right associative!
{next_level} [expr]:expression_x200 {-> expr.expression};
// Priority 201: CHECK IF Correct place for oftype
expression_x200 {-> expression} =
{typeof} [left]:expression_p210 oftype [right]:expression_p210 {-> New expression.typeof(left.expression, right.expression)} | // TODO: check priority and nesting that should be allowed
[expr]:expression_p210 {-> expr.expression};
// Priority 210:
expression_p210 {-> expression} =
{unary_minus} minus [expression]:expression_p230 {-> New expression.unary_minus(expression.expression)} |
{next_level} [expr]:expression_p230 {-> expr.expression};
// Priority 230:
expression_p230 {-> expression} =
{reverse} [expression]:expression_p231 tilde {-> New expression.reverse(expression.expression)} |
{next_level} [expr]:expression_p231 {-> expr.expression};
// Priority 231:
expression_p231 {-> expression} =
{image} [left]:expression_p230 left_bracket [right]:expression_in_par right_bracket {-> New expression.image(left.expression, right.expression)} |
{next_level} [expr]:expression_keyword {-> expr.expression};
expression_keyword {-> expression} =
{convert_bool} bool_cast left_par [predicate]:predicate_top right_par {-> New expression.convert_bool(predicate.predicate)} |
{max} max left_par [expression]:expression_in_par right_par {-> New expression.max(expression.expression)} |
{min} min left_par [expression]:expression_in_par right_par {-> New expression.min(expression.expression)} |
{card} card left_par [expression]:expression_in_par right_par {-> New expression.card(expression.expression)} |
{convert_int_floor} convert_int_floor left_par [expression]:expression_in_par right_par {-> New expression.convert_int_floor(expression.expression)} |
{convert_int_ceiling} convert_int_ceiling left_par [expression]:expression_in_par right_par {-> New expression.convert_int_ceiling(expression.expression)} |
{convert_real} convert_real left_par [expression]:expression_in_par right_par {-> New expression.convert_real(expression.expression)}
|
{general_sum} sigma [identifiers]:quantified_variables_list dot left_par [predicates]:predicate_top vertical_bar [expression]:expression_in_par right_par {-> New expression.general_sum([identifiers.expression], predicates.predicate, expression.expression)} |
{general_sum2} sigma [identifiers]:quantified_variables_list dot2 left_par [predicates]:predicate_top vertical_bar [expression]:expression_in_par right_par {-> New expression.general_sum([identifiers.expression], predicates.predicate, expression.expression)} |
{general_product} pi [identifiers]:quantified_variables_list dot left_par [predicates]:predicate_top vertical_bar [expression]:expression_in_par right_par {-> New expression.general_product([identifiers.expression], predicates.predicate, expression.expression)} |
{general_product2} pi [identifiers]:quantified_variables_list dot2 left_par [predicates]:predicate_top vertical_bar [expression]:expression_in_par right_par {-> New expression.general_product([identifiers.expression], predicates.predicate, expression.expression)}
|
{pow_subset} pow left_par [expression]:expression_in_par right_par {-> New expression.pow_subset(expression.expression)} |
{pow1_subset} pow1 left_par [expression]:expression_in_par right_par {-> New expression.pow1_subset(expression.expression)} |
{fin_subset} fin left_par [expression]:expression_in_par right_par {-> New expression.fin_subset(expression.expression)} |
{fin1_subset} fin1 left_par [expression]:expression_in_par right_par {-> New expression.fin1_subset(expression.expression)} |
{general_union} generalized_union left_par [expression]:expression_in_par right_par {-> New expression.general_union(expression.expression)} |
{general_intersection} generalized_inter left_par [expression]:expression_in_par right_par {-> New expression.general_intersection(expression.expression)} |
{identity} id left_par [expression]:expression_in_par right_par {-> New expression.identity(expression.expression)} |
{reflexive_closure} closure left_par [expression]:expression_in_par right_par {-> New expression.reflexive_closure(expression.expression)} |
{closure} closure1 left_par [expression]:expression_in_par right_par {-> New expression.closure(expression.expression)}
|
{domain} dom left_par [expression]:expression_in_par right_par {-> New expression.domain(expression.expression)} |
{range} ran left_par [expression]:expression_in_par right_par {-> New expression.range(expression.expression)}
|
{lambda} lambda [identifiers]:quantified_variables_list dot left_par [predicate]:predicate_top vertical_bar [expression]:expression_in_par right_par
{-> New expression.lambda([identifiers.expression], predicate.predicate, expression.expression)} |
{lambda2} lambda [identifiers]:quantified_variables_list dot2 left_par [predicate]:predicate_top vertical_bar [expression]:expression_in_par right_par
{-> New expression.lambda([identifiers.expression], predicate.predicate, expression.expression)}
|
{symbolic_lambda} pragma_symbolic pragma_end lambda [identifiers]:quantified_variables_list dot left_par [predicate]:predicate_top vertical_bar [expression]:expression_in_par right_par
{-> New expression.symbolic_lambda([identifiers.expression], predicate.predicate, expression.expression)} |
{symbolic_lambda2} pragma_symbolic pragma_end lambda [identifiers]:quantified_variables_list dot2 left_par [predicate]:predicate_top vertical_bar [expression]:expression_in_par right_par
{-> New expression.symbolic_lambda([identifiers.expression], predicate.predicate, expression.expression)}
|
{trans_function} fnc left_par [expression]:expression_in_par right_par {-> New expression.trans_function(expression.expression)} |
{trans_relation} rel left_par [expression]:expression_in_par right_par {-> New expression.trans_relation(expression.expression)}
|
{seq} seq left_par [expression]:expression_in_par right_par {-> New expression.seq(expression.expression)} |
{seq1} seq1 left_par [expression]:expression_in_par right_par {-> New expression.seq1(expression.expression)} |
{iseq} iseq left_par [expression]:expression_in_par right_par {-> New expression.iseq(expression.expression)} |
{iseq1} iseq1 left_par [expression]:expression_in_par right_par {-> New expression.iseq1(expression.expression)} |
{perm} perm left_par [expression]:expression_in_par right_par {-> New expression.perm(expression.expression)} |
{empty_sequence1} left_bracket right_bracket {-> New expression.empty_sequence()} |
{empty_sequence2} less_greater {-> New expression.empty_sequence()} | // not allowed by Atelier-B
{size} size left_par [expression]:expression_in_par right_par {-> New expression.size(expression.expression)} |
{first} first left_par [expression]:expression_in_par right_par {-> New expression.first(expression.expression)} |
{last} last left_par [expression]:expression_in_par right_par {-> New expression.last(expression.expression)} |
{front} front left_par [expression]:expression_in_par right_par {-> New expression.front(expression.expression)} |
{tail} tail left_par [expression]:expression_in_par right_par {-> New expression.tail(expression.expression)} |
{rev} rev left_par [expression]:expression_in_par right_par {-> New expression.rev(expression.expression)}
|
{first_projection} prj1 left_par [exp1]:expression_in_par comma [exp2]:expression_in_par right_par {-> New expression.first_projection(exp1.expression, exp2.expression)} |
{second_projection} prj2 left_par [exp1]:expression_in_par comma [exp2]:expression_in_par right_par {-> New expression.second_projection(exp1.expression, exp2.expression)}
| // now prj1/prj2 without typing arguments, e.g., prj1(1|->2) = 1
{first_projection_no_types} prj1 left_par [exp1]:expression_in_par right_par {-> New expression.function( New expression.event_b_first_projection_v2(), [exp1.expression])} |
{second_projection_no_types} prj2 left_par [exp1]:expression_in_par right_par {-> New expression.function( New expression.event_b_second_projection_v2(), [exp1.expression])}
| // prj1/prj2 fully without parameters such as in @prj1[{1|->2}]
{event_b_first_projection} prj1_v2 {-> New expression.event_b_first_projection_v2()} |
{event_b_second_projection} prj2_v2 {-> New expression.event_b_second_projection_v2()}
|
{iteration} iterate left_par [left]:expression_in_par comma [right]:expression_in_par right_par {-> New expression.iteration(left.expression, right.expression)}
|
// The identifier lists in all comprehension sets should really be quantified_variables_list and not expression_list(_in_par),
// but that causes reduce/reduce conflicts with set extensions (literals).
// Instead, IdentListCheck later enforces that only identifiers are used.
{comprehension_set} left_brace [identifiers]:expression_list_in_par vertical_bar [predicates]:predicate_top right_brace {-> New expression.comprehension_set([identifiers.expression], predicates.predicate)} |
{symbolic_comprehension_set} pragma_symbolic pragma_end left_brace [identifiers]:expression_list_in_par vertical_bar [predicates]:predicate_top right_brace {-> New expression.symbolic_comprehension_set([identifiers.expression], predicates.predicate)}
|
// because of possible conflicts this requires parentheses around identifiers when using the dot as a separator!
{event_b_comprehension_set} left_brace [identifiers]:comprehension_set_identifiers_with_parentheses dot [predicates]:predicate_top vertical_bar [expression]:expression_in_par right_brace
{-> New expression.event_b_comprehension_set([identifiers.expression], expression.expression, predicates.predicate)} |
{symbolic_event_b_comprehension_set} pragma_symbolic pragma_end left_brace [identifiers]:comprehension_set_identifiers_with_parentheses dot [predicates]:predicate_top vertical_bar [expression]:expression_in_par right_brace
{-> New expression.symbolic_event_b_comprehension_set([identifiers.expression], expression.expression, predicates.predicate)} |
{event_b_comprehension_set2} left_brace [identifiers]:expression_list_in_par dot2 [predicates]:predicate_top vertical_bar [expression]:expression_in_par right_brace
{-> New expression.event_b_comprehension_set([identifiers.expression], expression.expression, predicates.predicate)} |
{symbolic_event_b_comprehension_set2} pragma_symbolic pragma_end left_brace [identifiers]:expression_list_in_par dot2 [predicates]:predicate_top vertical_bar [expression]:expression_in_par right_brace
{-> New expression.symbolic_event_b_comprehension_set([identifiers.expression], expression.expression, predicates.predicate)}
|
{quantified_union} quantified_union [identifiers]:quantified_variables_list dot left_par [predicates]:predicate_top vertical_bar [expression]:expression_in_par right_par {-> New expression.quantified_union([identifiers.expression], predicates.predicate, expression.expression)} |
{quantified_union2} quantified_union [identifiers]:quantified_variables_list dot2 left_par [predicates]:predicate_top vertical_bar [expression]:expression_in_par right_par {-> New expression.quantified_union([identifiers.expression], predicates.predicate, expression.expression)} |
{symbolic_quantified_union} pragma_symbolic pragma_end quantified_union [identifiers]:quantified_variables_list dot left_par [predicates]:predicate_top vertical_bar [expression]:expression_in_par right_par {-> New expression.symbolic_quantified_union([identifiers.expression], predicates.predicate, expression.expression)} |
{symbolic_quantified_union2} pragma_symbolic pragma_end quantified_union [identifiers]:quantified_variables_list dot2 left_par [predicates]:predicate_top vertical_bar [expression]:expression_in_par right_par {-> New expression.symbolic_quantified_union([identifiers.expression], predicates.predicate, expression.expression)}
|
{quantified_intersection} quantified_inter [identifiers]:quantified_variables_list dot left_par [predicates]:predicate_top vertical_bar [expression]:expression_in_par right_par {-> New expression.quantified_intersection([identifiers.expression], predicates.predicate, expression.expression)} |
{quantified_intersection2} quantified_inter [identifiers]:quantified_variables_list dot2 left_par [predicates]:predicate_top vertical_bar [expression]:expression_in_par right_par {-> New expression.quantified_intersection([identifiers.expression], predicates.predicate, expression.expression)}
|
{set_extension} left_brace [expressions]:expression_list_in_par right_brace {-> New expression.set_extension([expressions.expression])} |
{sequence_extension} left_bracket [expressions]:expression_list right_bracket {-> New expression.sequence_extension([expressions.expression])} |
{couple2} [expression]:couple2 {-> expression.expression} |
{general_concat} conc left_par [expression]:expression_in_par right_par {-> New expression.general_concat(expression.expression)} |
{struct} struct left_par [entries]:rec_entry_list right_par {-> New expression.struct([entries.rec_entry])} |
{rec} rec left_par [entries]:rec_entry_list right_par {-> New expression.rec([entries.rec_entry])} |
{record_field} [record]:expression_p231 single_quotation [identifier]:identifier_literal {-> New expression.record_field(record.expression, identifier)} |
{expression_operator} [name]:kw_expression_operator [parameters]:op_params {-> New expression.operator(name, [parameters.expression])} | // extension
{next_level} [expr]:expression_func {-> expr.expression};
rec_entry {-> rec_entry} =
{in_pars} left_par [identifier]:identifier_literal element_of [value]:expression_in_par right_par {-> New rec_entry(identifier, value.expression)} |
{no_pars} [identifier]:identifier_literal element_of [value]:expression_in_par {-> New rec_entry(identifier, value.expression)};
rec_entry_list {-> rec_entry*} =
{single} [entry]:rec_entry {-> [entry.rec_entry]} |
{multi} [rest]:rec_entry_list comma [last]:rec_entry {-> [rest.rec_entry, last.rec_entry]};
expression_func {-> expression} =
{function} [function]:expression_p230 left_par [parameters]:expression_list right_par {-> New expression.function(function.expression, [parameters.expression])} |
{next_level} expression_atomic {-> expression_atomic.expression};
expression_atomic {-> expression} =
{paren} left_par [expression]:expression_in_par right_par {-> expression.expression} |
{identifier} [identifier]:composed_identifier {-> New expression.identifier([identifier.identifier_literal])} |
{primed_identifier} [identifier]:composed_identifier b_prime {-> New expression.primed_identifier([identifier.identifier_literal])} |
{string} [content]:string_literal {-> New expression.string(content)} |
{multiline_string} multiline_string_start [content]:multiline_string_content multiline_string_end {-> New expression.multiline_string(content)} |
{multiline_template} multiline_template_start [content]:multiline_template_content multiline_template_end {-> New expression.multiline_template(content)} |
{boolean_true} true {-> New expression.boolean_true()} |
{boolean_false} false {-> New expression.boolean_false()} |
{successor} succ {-> New expression.successor()} |
{predecessor} pred {-> New expression.predecessor()} |
{integer} [literal]:integer_literal {-> New expression.integer(literal)} |
{real} [literal]:real_literal {-> New expression.real(literal)} |
{hex_integer} [literal]:hex_literal {-> New expression.hex_integer(literal)} |
{max_int} max_int {-> New expression.max_int()} |
{min_int} min_int {-> New expression.min_int()} |
{empty_set_symbol} empty_set {-> New expression.empty_set()} |
{empty_set} left_brace right_brace {-> New expression.empty_set()} |
{integer_set} integer {-> New expression.integer_set()} |
{real_set} real {-> New expression.real_set()} |
{float_set} float {-> New expression.float_set()} |
{natural_set} natural {-> New expression.natural_set()} |
{natural1_set} natural1 {-> New expression.natural1_set()} |
{nat_set} nat {-> New expression.nat_set()} |
{nat1_set} nat1 {-> New expression.nat1_set()} |
{int_set} int {-> New expression.int_set()} |
{bool_set} bool {-> New expression.bool_set()} |
{if_expression} if [condition]:predicate_top then [then_expr]:expression_top_with_opt_desc [elsifs]:if_elseif_expression* else [else_expr]:expression_top_with_opt_desc end
// Note: one could allow expression_or_id_list here w/o creating shift/reduce conflicts
{-> New expression.if_then_else(condition.predicate, then_expr.expression, [elsifs.expression], else_expr.expression)} |
{let_expression} let [identifiers]:identifier_declaration_list be [definition]:predicate_top in [expr]:expression_top_with_opt_desc end
{-> New expression.let_expression([identifiers.expression], definition.predicate, expr.expression)} |
{string_set} string {-> New expression.string_set()};
if_elseif_expression {-> expression} =
elsif [condition]:predicate_top then [expr]:expression_top_with_opt_desc {-> New expression.if_elsif_expr(condition.predicate, expr.expression)};
expression_list {-> expression*} =
[first]:expression_top [rest]:expression_list_tail* {-> [first.expression, rest.expression]};
expression_list_tail {-> expression} =
comma [expr]:expression_top {-> expr.expression};
// used for partition(First[, Rest])
comma_expression_list {-> expression*} =
comma expression_list {-> [expression_list.expression]};
expression_list_in_par {-> expression*} =
[first]:expression_in_par [rest]:expression_list_in_par_tail* {-> [first.expression, rest.expression]};
expression_list_in_par_tail {-> expression} =
comma [expr]:expression_in_par {-> expr.expression};
couple2 {-> expression} =
left_par [first]:expression_in_par comma [rest]:expression_list_in_par right_par {-> New expression.couple([first.expression, rest.expression])}; // Klammern notwendig
comprehension_set_identifiers_with_parentheses {-> expression*} =
{single} left_par [identifier]:expression_in_par right_par {-> [identifier.expression]} |
{multi} [identifiers]:couple2 {-> [identifiers.expression]}; // will be unpacked by CoupleToIdentifierTransformation
/* Substitutions */
substitution_l0 {-> substitution} =
{invalid} substitution_l2 semicolon {-> New substitution.invalid(semicolon)} |
{next_level} substitution_l1 {-> substitution_l1.substitution};
substitution_l1 {-> substitution} =
{sequence} [first]:substitution_l2 semicolon [second]:substitution_l2 [rest]:sequence_subst_tail? {-> New substitution.sequence([first.substitution, second.substitution, rest.substitution])} |
{next_level} [sub]:substitution_l2 {-> sub.substitution};
sequence_subst_tail {-> substitution*} =
{single} semicolon [substitution]:substitution_l2 {-> [substitution.substitution]} |
{multi} semicolon [substitution]:substitution_l2 [rest]:sequence_subst_tail {-> [substitution.substitution, rest.substitution]} |
{invalid} semicolon {-> [New substitution.invalid(semicolon)]};
substitution_l2 {-> substitution} =
{parallel} [first]:substitution_l3 double_vertical_bar [second]:substitution_l3 [rest]:parallel_subst_tail? {-> New substitution.parallel([first.substitution, second.substitution, rest.substitution])} |
{next_level} [sub]:substitution_l3 {-> sub.substitution};
parallel_subst_tail {-> substitution*} =
{single} double_vertical_bar [substitution]:substitution_l3 {-> [substitution.substitution]} |
{multi} double_vertical_bar [substitution]:substitution_l3 [rest]:parallel_subst_tail {-> [substitution.substitution, rest.substitution]};
substitution_l3 {-> substitution} =
{block} begin [substitution]:substitution_l0 end
{-> New substitution.block(substitution.substitution)} |
{skip} skip {-> New substitution.skip()} |
{assign} [lhs_expression]:assign_list assign [rhs_expressions]:expression_list
{-> New substitution.assign([lhs_expression.expression], [rhs_expressions.expression])} |
{precondition} pre [predicate]:predicate_top then [substitution]:substitution_l0 end
{-> New substitution.precondition(predicate.predicate, substitution.substitution)} |
{assertion} assert [predicate]:predicate_top then [substitution]:substitution_l0 end
{-> New substitution.assertion(predicate.predicate, substitution.substitution)} |
{witness_then} witness_kw [predicate]:predicate_top then [substitution]:substitution_l0 end
{-> New substitution.witness_then(predicate.predicate, substitution.substitution)} |
{choice} choice [first]:substitution_l0 [rest]:choice_or* end
{-> New substitution.choice([first.substitution, rest.substitution])} |
{if} if [condition]:predicate_top then [then_subst]:substitution_l0 [elsifs]:if_elsif* [else]:if_else? end
{-> New substitution.if(condition.predicate, then_subst.substitution, [elsifs.substitution], else.substitution)} |
{select} select [condition]:predicate_top then [then_subst]:substitution_l0 [whens]:select_when* [else]:select_else? end
{-> New substitution.select(condition.predicate, then_subst.substitution, [whens.substitution], else.substitution)} |
{case} case [case_expr]:expression_in_par of either [either_expr]:expression_list then [either_subst]:substitution_l0 [or_substitutions]:case_or* [else]:case_else? [end1]:end [end2]:end
{-> New substitution.case(case_expr.expression, [either_expr.expression], either_subst.substitution, [or_substitutions.substitution], else.substitution)} |
{any} any [identifiers]:identifier_declaration_list where [where_pred]:predicate_top then [then_subst]:substitution_l0 end
{-> New substitution.any([identifiers.expression], where_pred.predicate, then_subst.substitution)} |
// According to the Atelier-B reference manual,
// the LHS of "becomes element of" and "becomes such that" substitutions can only contain (possibly dotted) identifiers.
// assign_list allows a bit more than that (namely function calls and record fields),
// but we cannot use a different production here,
// because it would cause reduce/reduce conflicts with assignment substitutions.
// Instead, IdentListCheck later enforces that only identifiers are used.
// TODO Could/should we allow function calls and record fields here as an extension?
{becomes_element_of} [identifiers]:assign_list double_colon [set]:expression_top
{-> New substitution.becomes_element_of([identifiers.expression], set.expression)} |
{becomes_such} [identifiers]:assign_list element_of left_par [predicate]:predicate_top right_par
{-> New substitution.becomes_such([identifiers.expression], predicate.predicate)} |
{var} var [identifiers]:identifier_declaration_list in [substitution]:substitution_l0 end
{-> New substitution.var([identifiers.expression], substitution.substitution)} |
// Ambiguous call: either an operation call without return values
// or a definition call of a definition of type ExprOrSubst
// (i. e. it was uncertain whether the RHS is an expression or a substitution).
// In both cases, the call may have arguments (parsed as a function call expression)
// or it may have no arguments (parsed as an identifier expression).
// The OpSubstitutions visitor will transform the resulting operation_or_definition_call node
// into an operation_call or definition substitution as appropriate.
//
// Definition calls of a definition of type Substitution
// (i. e. the RHS is unambiguously a substitution)
// are *not* handled by this alternative.
// The PreParser transforms the definition call identifier into a def_literal_substitution token,
// which will be handled by a different alternative that directly produces a definition substitution.
//
// Unrelated to this ambiguity, the call must be parsed as identifier_or_function_expression
// to avoid shift/reduce conflicts with operation calls *with* return values:
// without unlimited lookahead, it's impossible to tell whether "f(a,b,c,d,...)"
// is part of a return value assignment ("f(a,b,c,d,...) <-- op(x,y,z)")
// or an operation call ("f(a,b,c,d,...); skip").
{operation_or_definition_call} [op]:identifier_or_function_expression
{-> New substitution.operation_or_definition_call(op.expression)} | // check in semantic check if expression is a definition
// Unambiguous call: the '<--' syntax for return values is only used for operation calls.
// (Definition call substitutions cannot have return values.)
{operation_call_with_return_values} [return_values]:assign_list output_parameters [op_name]:composed_identifier [parameters]:op_params?
{-> New substitution.operation_call([return_values.expression], [op_name.identifier_literal], [parameters.expression])} |
{while} while [condition]:predicate_top do [do_subst]:substitution_l0 invariant [invariant_pred]:predicate_top variant [variant_expr]:expression_in_par end
{-> New substitution.while(condition.predicate, do_subst.substitution, invariant_pred.predicate, variant_expr.expression)} |
{let} let [identifiers]:identifier_declaration_list be [predicate]:predicate_top in [substitution]:substitution_l0 end
{-> New substitution.let([identifiers.expression], predicate.predicate, substitution.substitution)} |
{definition} [def_literal]:def_literal_substitution [parameters]:def_call_params?
{-> New substitution.definition(def_literal, [parameters.expression])} |
// extensions for rules
{for_loop} kw_for [identifiers]:identifier_declaration_list in [set]:expression_in_par do [do_subst]:substitution_l0 end
{-> New substitution.for_loop([identifiers.expression], set.expression, do_subst.substitution)} |
{forall_sub_message} kw_rule_for_all [identifiers]:identifier_declaration_list where [where_pred]:predicate_top
kw_expect [expect_pred]:predicate_top [error_type]:error_type?
[on_success]:on_success? kw_counterexample [message]:expression_top_with_opt_desc end
{-> New substitution.forall_sub_message([identifiers.expression], where_pred.predicate, expect_pred.predicate, error_type.integer_literal, on_success.expression, message.expression)} |
{rule_fail_sub} kw_rule_fail [identifiers]:identifier_declaration_list? [when_pred]:when_predicate?
[error_type]:error_type? kw_counterexample [message]:expression_top_with_opt_desc end
{-> New substitution.rule_fail_sub([identifiers.expression], when_pred.predicate, error_type.integer_literal, message.expression)} |
{substitution_operator} [name]:kw_substitution_operator [arguments]:op_params?
{-> New substitution.operator(name, [arguments.expression])} |
{define} kw_define [name]:identifier_literal kw_type [type]:expression_in_par
[dummy]:dummy_value? kw_value [value]:expression_in_par end
{-> New substitution.define(name, type.expression, dummy.expression, value.expression)};
when_predicate {-> predicate} = when [pred]:predicate_top {-> pred.predicate};
message {-> expression} = left_par [expr]:expression_in_par right_par {-> expr.expression};
dummy_value {-> expression} = kw_dummy_value [expr]:expression_in_par {-> expr.expression};
error_type {-> integer_literal} = kw_rule_error_type [id]:integer_literal {-> id};
on_success {-> expression} = kw_on_success [expr]:expression_top_with_opt_desc {-> expr.expression};
choice_or {-> substitution} =
or [substitution]:substitution_l0 {-> New substitution.choice_or(substitution.substitution)};
if_elsif {-> substitution} =
elsif [condition]:predicate_top then [subst]:substitution_l0 {-> New substitution.if_elsif(condition.predicate, subst.substitution)};
if_else {-> substitution} =
else [subst]:substitution_l0 {-> subst.substitution};
select_when {-> substitution} =
when [condition]:predicate_top then [subst]:substitution_l0 {-> New substitution.select_when(condition.predicate, subst.substitution)};
select_else {-> substitution} =
else [subst]:substitution_l0 {-> subst.substitution};
case_or {-> substitution} =
or [expressions]:expression_list then [subst]:substitution_l0 {-> New substitution.case_or([expressions.expression], subst.substitution)};
case_else {-> substitution} =
else [subst]:substitution_l0 {-> subst.substitution};
op_params {-> expression*} =
left_par [parameters]:expression_list right_par {-> [parameters.expression]};
/* Basics */
composed_identifier {-> identifier_literal*} =
{single} [name]:identifier_literal {-> [name]} |
{multi} [rest]:composed_identifier dot [first]:identifier_literal {-> [rest.identifier_literal, first]};
// To do: maybe the only place where we do not want to also admit the second kind of dot '·' (generated by Rodin for quantifiers)
identifier_declaration_list {-> expression*} =
{single} [identifier]:identifier_declaration {-> [identifier.expression]} |
{multi} [rest]:identifier_declaration_list comma [identifier]:identifier_declaration {-> [rest.expression, identifier.expression]};
/* a,b,f(1),g(1)(2) := ... */
assign_list {-> expression*} =
{single} [name]:assignment_target {-> [name.expression]} |
{multi} [rest]:assign_list comma [name]:assignment_target {-> [rest.expression, name.expression]};
assignment_target {-> expression} =
{record} [record]:assignment_target single_quotation [name]:identifier_literal {-> New expression.record_field(record.expression, name)} |
{next_level} [expr]:identifier_or_function_expression {-> expr.expression};
identifier_or_function_expression {-> expression} =
{identifier} [name]:composed_identifier {-> New expression.identifier([name.identifier_literal])} |
{function} [name]:identifier_or_function_expression [parameters]:op_params {-> New expression.function(name.expression, [parameters.expression])};
quantified_variables_list {-> expression*} =
{parentheses} left_par [id]:identifier_declaration_list right_par {-> [id.expression]} |
{no_parentheses} [id]:identifier_declaration_list {-> [id.expression]};
identifier_declaration {-> expression} =
{description} [identifier]:identifier_literal [description]:description_pragma {-> New expression.description(description.description_pragma, New expression.identifier([identifier]))} |
{identifier} [identifier]:identifier_literal {-> New expression.identifier([identifier])};
def_call_params {-> expression*} = left_par [params]:expression_list right_par {-> [params.expression]};
/* Patterns for opertions */
operation_pattern {-> parse_unit }=
[op_name]:composed_identifier [parameters]:op_pattern_params? {-> New parse_unit.oppattern([op_name.identifier_literal], [parameters.argpattern])};
op_pattern_params {-> argpattern*} =
left_par [parameters]:oppattern_list right_par {-> [parameters.argpattern]} ;
oppattern_list {-> argpattern*} =
{single} [arg]:op_pattern_param {-> [arg.argpattern]} |
{multiple} [rest]:oppattern_list comma [last]:op_pattern_param {-> [rest.argpattern, last.argpattern]};
op_pattern_param {-> argpattern} =
{def} [expression]:expression_in_par {-> New argpattern.def(expression.expression)} |
{undef} underscore {-> New argpattern.undef()};
/*******************************************************************
* Abstract Syntax Tree *
*******************************************************************/
Abstract Syntax Tree
parse_unit =
{generated} parse_unit |
{package} [package]:pragma_id_or_string [imports]:import_package* parse_unit |
{abstract_machine} [variant]:machine_variant [header]:machine_header [machine_clauses]:machine_clause* |
{refinement_machine} [header]:machine_header [ref_machine]:identifier_literal [machine_clauses]:machine_clause* |
{implementation_machine} [header]:machine_header [ref_machine]:identifier_literal [machine_clauses]:machine_clause* |
{definition_file} [definitions_clauses]:machine_clause |
{predicate} predicate |
{expression} expression |
{substitution} substitution |
{machine_clause} machine_clause |
{event_b_context} [name]:identifier_literal [context_clauses]:context_clause* |
{event_b_model} [name]:identifier_literal [model_clauses]:model_clause* |
{oppattern} [name]:identifier_literal* [parameters]:argpattern* |
{parse_unit_definition} definition;
import_package = [package]:pragma_id_or_string; // importing a package or machine using import pragma (e.g. /*@import-package "foo.bar" */ )
argpattern = {undef} | {def} expression;
/* csppattern = argtype argpattern; */
/* argtype = {join} | {in} | {out}; */
machine_variant = {machine} | {model} | {system};
machine_header =
[name]:identifier_literal* [parameters]:expression*;
context_clause =
{extends} [extends]:identifier_literal* |
{sets} set* |
{constants} [identifiers]:expression* |
{abstract_constants} [identifiers]:expression* |
{axioms} [predicates]:predicate* |
{theorems} [predicates]:predicate*;
model_clause =
{refines} [refines]:identifier_literal |
{sees} [sees]:identifier_literal* |
{variables} [identifiers]:expression* |
{invariant} [predicates]:predicate* |
{theorems} [predicates]:predicate* |
{variant} [variant]:expression |
{events} event*;
machine_clause =
{definitions} [definitions]:definition* |
{sees} [machine_names]:machine_reference_no_params* |
{promotes} [operation_names]:operation_reference* |
{uses} [machine_names]:machine_reference_no_params* |
{includes} [machine_references]:machine_reference* |
{extends} [machine_references]:machine_reference* |
{imports} [machine_references]:machine_reference* |
{sets} [set_definitions]:set* |
{freetypes} [freetypes]:freetype* |
{variables} [identifiers]:expression* |
{concrete_variables} [identifiers]:expression* |
{abstract_constants} [identifiers]:expression* |
{constants} [identifiers]:expression* |
{properties} [predicates]:predicate |
{constraints} [predicates]:predicate |
{initialisation} [substitutions]:substitution |
{invariant} [predicates]:predicate |
{assertions} [predicates]:predicate* |
{values} [entries]:values_entry* |
{local_operations} [operations]:operation* |
{operations} [operations]:operation* |
{references} [machine_references]:machine_reference* |
{invalid_operations_clause} semicolon |
{expressions} [expressions]:expression_definition* |
{predicates} [predicates]:predicate_definition*;
machine_reference =
[machine_name]:identifier_literal* [parameters]:expression* |
{file} [reference]:machine_reference [file]:pragma_id_or_string;
machine_reference_no_params =
[machine_name]:identifier_literal* |
{file} [reference]:machine_reference_no_params [file]:pragma_id_or_string;
operation_reference = [operation_name]:identifier_literal*;
description_pragma = [parts]:pragma_free_text*;
expression_definition = [name]:identifier_literal [parameters]:expression* [rhs]:expression;
predicate_definition = [name]:identifier_literal [parameters]:expression* [rhs]:predicate;
definition =
{predicate_definition} [name]:def_literal_predicate [parameters]:expression* [rhs]:predicate |
{substitution_definition} [name]:def_literal_substitution [parameters]:expression* [rhs]:substitution |
{expression_definition} [name]:identifier_literal [parameters]:expression* [rhs]:expression |
{file_definition} [filename]:string_literal;
set =
{description} [description]:description_pragma set |
{deferred_set} [identifier]:identifier_literal* |
{enumerated_set} [identifier]:identifier_literal* [elements]:expression* |
{enumerated_set_via_def} [identifier]:identifier_literal* [elements_def]:identifier_literal*; // covers: SETS Id = ED; DEFINITIONS ED == {a,b,c}
freetype = [name]:identifier_literal [parameters]:expression* [constructors]:freetype_constructor+;
freetype_constructor =
{constructor} [name]:identifier_literal [argument]:expression |
{element} [name]:identifier_literal;
values_entry = [identifier]:identifier_literal* [value]:expression;
operation =
[return_values]:expression* [op_name]:identifier_literal* [parameters]:expression* [operation_body]:substitution |
{missing_semicolon} operation |
{description} [description]:description_pragma [operation]:operation |
{refined} [return_values]:expression* [op_name]:identifier_literal* [parameters]:expression* [ref_kw]:identifier_literal [ab_op_name]:identifier_literal [operation_body]:substitution |
{rule} [rule_name]:identifier_literal [attributes]:operation_attribute* [rule_body]:substitution |
{computation} [name]:identifier_literal [attributes]:operation_attribute* [body]:substitution |
{function} [return_values]:expression* [name]:identifier_literal [parameters]:expression* [attributes]:operation_attribute* [body]:substitution;
operation_attribute =
[name]: kw_attribute_identifier [arguments]:expression* |
{predicate_attribute} [name]:kw_predicate_attribute [predicate]:predicate;
event =
[event_name]:identifier_literal [status]:eventstatus [refines]:identifier_literal*
[variables]:expression* [guards]:predicate* [theorems]:predicate* [assignments]:substitution* [witness]:witness*
|
{description} [description]:description_pragma [event]:event;
witness = [name]:identifier_literal [predicate]:predicate;
eventstatus = {ordinary} | {anticipated} | {convergent};
/* Predicates */
predicate =
{description} [description]:description_pragma [predicate]:predicate |
{label} [name]:pragma_id_or_string [predicate]:predicate |
{substitution} [substitution]:substitution [predicate]:predicate |
{conjunct} [left]:predicate [right]:predicate |
{negation} [predicate]:predicate |
{disjunct} [left]:predicate [right]:predicate |
{implication} [left]:predicate [right]:predicate |
{equivalence} [left]:predicate [right]:predicate |
{forall} [identifiers]:expression* [implication]:predicate |
{exists} [identifiers]:expression* [predicate]:predicate |
{equal} [left]:expression [right]:expression |
{not_equal} [left]:expression [right]:expression |
{member} [left]:expression [right]:expression |
{not_member} [left]:expression [right]:expression |
{subset} [left]:expression [right]:expression |
{subset_strict} [left]:expression [right]:expression |
{not_subset} [left]:expression [right]:expression |
{not_subset_strict} [left]:expression [right]:expression |
{less_equal} [left]:expression [right]:expression |
{less} [left]:expression [right]:expression |
{greater_equal} [left]:expression [right]:expression |
{greater} [left]:expression [right]:expression |
{truth} |
{falsity} |
{finite} [set]:expression |
{partition} [set]:expression [elements]:expression* | /* Event-B only predicate */
{definition} [def_literal]:def_literal_predicate [parameters]:expression* |
{let_predicate} [identifiers]:expression* [assignment]:predicate [pred]:predicate |
{if_elsif_predicate} [condition]:predicate [then]:predicate |
{if_predicate} [condition]:predicate [then]:predicate [elsifs]:predicate* [else]:predicate |
{extended_pred} [identifier]:identifier_literal [expressions]:expression* [predicates]:predicate* | /* Event-B only predicate - theory plugin */
{operator} [name]:kw_predicate_operator [identifiers]:expression*; // extension for rules
/* Expressions */
expression =
{description} [description]:description_pragma [expression]:expression |
{identifier} [identifier]:identifier_literal* |
{primed_identifier} [identifier]:identifier_literal* |
{string} [content]:string_literal |
{multiline_string} [content]:multiline_string_content |
{multiline_template} [content]:multiline_template_content |
{boolean_true} |
{boolean_false} |
{integer} [literal]:integer_literal |
{real} [literal]:real_literal |
{hex_integer} [literal]:hex_literal |
{max_int} |
{min_int} |
{empty_set} |
{integer_set} |
{real_set} |
{float_set} |
{natural_set} |
{natural1_set} |
{nat_set} |
{nat1_set} |
{int_set} |
{bool_set} |
{string_set} |
{convert_bool} [predicate]:predicate |
{add} [left]:expression [right]:expression |
{minus} [left]:expression [right]:expression | // only used by EventB translator
{minus_or_set_subtract} [left]:expression [right]:expression | // used by this parser 'cause we cannot decide which one it is
{unary_minus} [expression]:expression |
{multiplication} [left]:expression [right]:expression | // only used by EventB translator
{cartesian_product} [left]:expression [right]:expression | // only used by EventB translator
{mult_or_cart} [left]:expression [right]:expression | // used by this parser 'cause we cannot decide which one it is
{div} [left]:expression [right]:expression |
{floored_div} [left]:expression [right]:expression | /* has no concrete syntax, generated for example by TLA translation */
{if_elsif_expr} [condition]:predicate [then]:expression |
{if_then_else} [condition]:predicate [then]:expression [elsifs]:expression* [else]:expression |
{let_expression} [identifiers]:expression* [assignment]:predicate [expr]:expression |
{modulo} [left]:expression [right]:expression |
{power_of} [left]:expression [right]:expression |
{successor} |
{predecessor} |
{max} [expression]:expression |
{min} [expression]:expression |
{card} [expression]:expression |
{convert_int_floor} [expression]:expression |
{convert_int_ceiling} [expression]:expression |
{convert_real} [expression]:expression |
{general_sum} [identifiers]:expression* [predicates]:predicate [expression]:expression |
{general_product} [identifiers]:expression* [predicates]:predicate [expression]:expression |
{couple} [list]:expression* |
{comprehension_set} [identifiers]:expression* [predicates]:predicate |
{symbolic_comprehension_set} [identifiers]:expression* [predicates]:predicate |
{event_b_comprehension_set} [identifiers]:expression* [expression]:expression [predicates]:predicate | // EventB style
{symbolic_event_b_comprehension_set} [identifiers]:expression* [expression]:expression [predicates]:predicate |
{pow_subset} [expression]:expression |
{pow1_subset} [expression]:expression |
{fin_subset} [expression]:expression |
{fin1_subset} [expression]:expression |
{set_extension} [expressions]:expression* |
{interval} [left_border]:expression [right_border]:expression |
{union} [left]:expression [right]:expression |
{intersection} [left]:expression [right]:expression |
{set_subtraction} [left]:expression [right]:expression |
{general_union} [expression]:expression |
{general_intersection} [expression]:expression |
{quantified_union} [identifiers]:expression* [predicates]:predicate [expression]:expression |
{symbolic_quantified_union} [identifiers]:expression* [predicates]:predicate [expression]:expression |
{quantified_intersection} [identifiers]:expression* [predicates]:predicate [expression]:expression |
{relations} [left]:expression [right]:expression |
{identity} [expression]:expression |
{event_b_identity} | // EventB v 2.0 language only
{reverse} [expression]:expression |
{first_projection} [exp1]:expression [exp2]:expression |
{event_b_first_projection} [expression]:expression | // EventB only
{event_b_first_projection_v2} | // EventB v 2.0 language only
{second_projection} [exp1]:expression [exp2]:expression |
{event_b_second_projection} [expression]:expression | // EventB only
{event_b_second_projection_v2} | // EventB v 2.0 language only
{composition} [left]:expression [right]:expression |
{symbolic_composition} [left]:expression [right]:expression |
{ring} [left]:expression [right]:expression | // EventB only
{direct_product} [left]:expression [right]:expression |
{parallel_product} [left]:expression [right]:expression |
{iteration} [left]:expression [right]:expression |
{reflexive_closure} [expression]:expression |
{closure} [expression]:expression |
{domain} [expression]:expression |
{range} [expression]:expression |
{image} [left]:expression [right]:expression |
{domain_restriction} [left]:expression [right]:expression |
{domain_subtraction} [left]:expression [right]:expression |
{range_restriction} [left]:expression [right]:expression |
{range_subtraction} [left]:expression [right]:expression |
{overwrite} [left]:expression [right]:expression |
{partial_function} [left]:expression [right]:expression |
{total_function} [left]:expression [right]:expression |
{partial_injection} [left]:expression [right]:expression |
{total_injection} [left]:expression [right]:expression |
{partial_surjection} [left]:expression [right]:expression |
{total_surjection} [left]:expression [right]:expression |
{partial_bijection} [left]:expression [right]:expression |
{total_bijection} [left]:expression [right]:expression |
{total_relation} [left]:expression [right]:expression | // EventB only
{surjection_relation} [left]:expression [right]:expression | // EventB only
{total_surjection_relation} [left]:expression [right]:expression | // EventB only
{lambda} [identifiers]:expression* [predicate]:predicate [expression]:expression |
{symbolic_lambda} [identifiers]:expression* [predicate]:predicate [expression]:expression |
{trans_function} [expression]:expression |
{trans_relation} [expression]:expression |
{seq} [expression]:expression |
{seq1} [expression]:expression |
{iseq} [expression]:expression |
{iseq1} [expression]:expression |
{perm} [expression]:expression |
{empty_sequence} |
{sequence_extension} [expression]:expression* |
{size} [expression]:expression |
{first} [expression]:expression |
{last} [expression]:expression |
{front} [expression]:expression |
{tail} [expression]:expression |
{rev} [expression]:expression |
{concat} [left]:expression [right]:expression |
{insert_front} [left]:expression [right]:expression |
{insert_tail} [left]:expression [right]:expression |
{restrict_front} [left]:expression [right]:expression |
{restrict_tail} [left]:expression [right]:expression |
{general_concat} [expression]:expression |
{definition} [def_literal]:identifier_literal [parameters]:expression* |
{function} [identifier]:expression [parameters]:expression* |
{tree} [expression]:expression |
{btree} [expression]:expression |
{const} [expression1]:expression [expression2]:expression |
{top} [expression]:expression |
{sons} [expression]:expression |
{prefix} [expression]:expression |
{postfix} [expression]:expression |
{sizet} [expression]:expression |
{mirror} [expression]:expression |
{rank} [expression1]:expression [expression2]:expression |
{father} [expression1]:expression [expression2]:expression |
{son} [expression1]:expression [expression2]:expression [expression3]:expression |
{subtree} [expression1]:expression [expression2]:expression |
{arity} [expression1]:expression [expression2]:expression |
{bin} [expression1]:expression [expression2]:expression? [expression3]:expression? |
{left} [expression]:expression |
{right} [expression]:expression |
{infix} [expression]:expression |
{struct} [entries]:rec_entry* |
{rec} [entries]:rec_entry* |
{record_field} [record]:expression [identifier]:identifier_literal |
{extended_expr} [identifier]:identifier_literal [expressions]:expression* [predicates]:predicate* | /* Event-B only expression - theory plugin */
{typeof} [expression]:expression [type]:expression | /* Corresponds to oftype operator in Event-B, was only generated by the translation process */
{operation_call} [operation]:identifier_literal* [parameters]:expression* |
{operator} [name]:kw_expression_operator [identifiers]:expression*; // extension for rules
rec_entry = [identifier]:identifier_literal [value]:expression;
/* Substitutions */
substitution =
{block} [substitution]:substitution |
{skip} |
{assign} [lhs_expression]:expression* [rhs_expressions]:expression* |
{precondition} [predicate]:predicate [substitution]:substitution |
{assertion} [predicate]:predicate [substitution]:substitution |
{witness_then} [predicate]:predicate [substitution]:substitution |
{choice} [substitutions]:substitution* |
{choice_or} [substitution]:substitution |
{if} [condition]:predicate [then]:substitution [elsif_substitutions]:substitution* [else]:substitution? |
{if_elsif} [condition]:predicate [then_substitution]:substitution |
{select} [condition]:predicate [then]:substitution [when_substitutions]:substitution* [else]:substitution? |
{select_when} [condition]:predicate [substitution]:substitution |
{case} expression [either_expr]:expression* [either_subst]:substitution [or_substitutions]:substitution* [else]:substitution? |
{case_or} [expressions]:expression* [substitution]:substitution |
{any} [identifiers]:expression* [where]:predicate [then]:substitution |
{let} [identifiers]:expression* [predicate]:predicate [substitution]:substitution |
{becomes_element_of} [identifiers]:expression* [set]:expression|
{becomes_such} [identifiers]:expression* [predicate]:predicate |
{var} [identifiers]:expression* [substitution]:substitution |
{sequence} [substitutions]:substitution* |
{operation_or_definition_call} [expression]:expression |
{operation_call} [result_identifiers]:expression* [operation]:identifier_literal* [parameters]:expression* |
{while} [condition]:predicate [do_subst]:substitution [invariant]:predicate [variant]:expression |
{parallel} [substitutions]:substitution* |
{definition} [def_literal]:def_literal_substitution [parameters]:expression* |
{invalid} semicolon |
{forall_sub_message} [identifiers]:expression* [where]:predicate [expect]:predicate [error_type]:integer_literal? [on_success]:expression? [message]:expression | // extension for rules
{rule_fail_sub} [identifiers]:expression* [when]:predicate? [error_type]:integer_literal? [message]:expression | // extension for rules
{for_loop} [identifiers]:expression* [set]:expression [do_subst]:substitution | // extension for rules
{operator} [name]:kw_substitution_operator [arguments]:expression* | // extension for rules
{define} [name]:identifier_literal [type]:expression [dummy_value]:expression? [value]:expression; // extension for rules
© 2015 - 2024 Weber Informatics LLC | Privacy Policy