Skip to content

Latest commit

 

History

History
421 lines (292 loc) · 13.9 KB

File metadata and controls

421 lines (292 loc) · 13.9 KB

Flat Modelica grammar

The starting point for this Flat Modelica grammar is the ANTLR grammar for Modelica as proposed by this ModelicaSpecification PR.

The intention is to develop the Flat Modelica grammar as a modification (mainly consisting of restrictions) of the full Modelica grammar, and to make the differences clearly visible in this document. Hence, rather than just erasing the parts of the Modelica grammar that shouldn't be brought to Flat Modelica, these parts will be marked with a strikeout.

The start rule of the Flat Modelica grammar below is flat-modelica.

B1 Lexical conventions

Each grammar rule is written as a block quote. Regular expressions for tokens are written as inline code, literal tokens are written in upright boldface (this is useful for avoiding the use of regular expressions when doing so would require protection of active characters), production rule names are written in italics, while parsing constructs are written in plain text.

Parsing constructs:

  • x | y — alternatives; either x or y
  • x y — sequencing; x followed by y
  • x* — zero or more repetitions
  • x+ — one or more repetitions
  • x? — zero or one repetitions
  • EOF — end of file
  • (…) — parentheses for grouping

Repetition posfix operators have higher precedence than sequencing, which in turn has higher precedence than alternatives.

To avoid risk of confusion with the parentheses parsing construct ( a | b ), literal parentheses are written in regular expression form, [(] a | b [)], rather than in upright boldface, ( a | b ).

There are no empty productions. Hence, where there is no risk of ambiguity, the left side of an alternative is allowed to be ommitted, meaning the same as just having the right side alternative. For example, ( | a | b ) is the same as ( a | b ).

Whitespace and comments

WS → ( [ ] | \t | NL )+

LINE-COMMENT//[^\r\n]* (NL | EOF)

ML-COMMENT/[*]([^*]|([*][^/]))*[*]/

NL\r\n | \n | \r

Lexical units except for keywords

IDENTNONDIGIT ( DIGIT | NONDIGIT )* | Q-IDENT

NONDIGIT_ | [a-z] | [A-Z]

STRING" ( S-CHAR | S-ESCAPE )* "

The S-CHAR accepts Unicode other than " and \:

S-CHARNL | [^\r\n\\"]

DIGIT[0-9]

Q-IDENT' ( Q-CHAR | S-ESCAPE ) ( Q-CHAR | S-ESCAPE | " )* '

Q-CHARNONDIGIT | DIGIT | [-!#$%&()*>+,./:;<>=?>@[]{}|~ ^]

S-ESCAPE\\['"?\\abfnrtv]

UNSIGNED-INTEGERDIGIT+

EXPONENT → ( e | E ) ( [+] | - )? DIGIT+

UNSIGNED-NUMBERDIGIT+ ( [.] (DIGIT)* )? ( EXPONENT )?

Start rule

flat-modelica
VERSION-HEADER
package IDENT
   ( class-definition ;
   | global-constant ;
   )*
   model long-class-specifier ;
end IDENT ;

Here, the VERSION-HEADER is a Flat Modelica variant of the not yet standardized language version header for Modelica proposed in MCP-0015:

VERSION-HEADER^\U+FEFF?//![ ]flat[ ][0-9]+[.][0-9]+[r.][0-9]+$

The \U+FEFF? at the very beginning is an optional byte order mark.

The IDENT in the flat-modelica rule must be the same identifier as in the long-class-specifier following model.

As an example of the flat-modelica rule, this is a minimal valid Flat Modelica source:

//! flat 3.5.0
package _F
  model _F
  end _F;
end _F;

B22 Class definition

class-definitionencapsulated? class-prefixes class-specifier

class-prefixes
partial?
  (
  | type
  | operator? record
  | ( ( pure constant? ) | impure )? operator? function
| class
| model
| block
| expandable? connector
| package
| operator
  )

class-specifierlong-class-specifier | short-class-specifier | der-class-specifier

long-class-specifier
  → IDENT string-comment composition end IDENT
| extends IDENT class-modification? string-comment composition end IDENT

short-class-specifier
IDENT =
  ( base-prefix? type-specifier array-subscripts? class-modification?
  | enumeration [(] ( enum-list? | : ) [)]
  )
comment

der-class-specifierIDENT = der [(] type-specifier , IDENT ( , IDENT )* [)] comment

base-prefixinput | output

enum-listenumeration-literal ( , enumeration-literal )*

enumeration-literalIDENT comment

composition
  (generic-element ;)*
( public (generic-element ;)*
| protected (generic-element ;)*
  | equation ( equation ; )*
  | initial equation ( initial-equation ; )*
  | initial? algorithm ( statement ; )*
  )*
  ( external language-specification?
   external-function-call? annotation-comment? ;
  )?
  ( annotation-comment ; )?

language-specificationSTRING

external-function-call → ( component-reference = )? IDENT [(] expression-list? [)]

generic-elementimport-clause | extends-clause | normal-element | parameter-equation

normal-element
redeclare?
final?
inner? outer?
  ( class-definition
  | component-clause
| replaceable ( class-definition | component-clause ) ( constraining-clause comment )?
  )

parameter-equation
parameter equation guess-value =
  ( expression | prioritize-expression )
comment

guess-valueguess [(] component-reference [)]

import-clause
import
  ( IDENT = name
  | name ( [.] ( [*] | { import-list } ) | [.][*] )?
  )
comment

import-listIDENT ( , IDENT )*

B23 Extends

extends-clauseextends type-specifier class-modification? annotation-comment?

constraining-clauseconstrainedby type-specifier class-modification?

B24 Component clause

component-clausetype-prefix type-specifier array-subscripts? component-list

global-constantconstant type-specifier array-subscripts? declaration comment

type-prefix
  ( flow | stream )?
  ( discrete | parameter | constant )?
  ( input | output )?

component-listcomponent-declaration ( , component-declaration )*

component-declarationdeclaration condition-attribute? comment

condition-attributeif expression

declarationIDENT array-subscripts? modification?

B25 Modification

modification
  → class-modification ( = expression )?
  | = expression
  | := expression

class-modification[(] argument-list? [)]

argument-listargument ( , argument )*

argument
  → element-modification-or-replaceable
| element-redeclaration

element-modification-or-replaceable
each?
final?
  ( element-modification
| element-replaceable
  )

element-modificationname modification? string-comment

element-redeclaration
redeclare each? final?
  ( short-class-definition
  | component-clause1
  | element-replaceable
  )

element-replaceable
replaceable
  ( short-class-definition
  | component-clause1
  )
constraining-clause?

component-clause1type-prefix type-specifier component-declaration1

component-declaration1declaration comment

short-class-definitionclass-prefixes short-class-specifier

B26 Equations

equation
  ( simple-expression ( = expression )?
  | if-equation
  | for-equation
| connect-clause
  | when-equation
  )
comment

initial-equationequation | prioritize-equation

statement
  ( component-reference ( := expression | function-call-args )
  | [(] output-expression-list [)] := component-reference function-call-args
  | break
  | return
  | if-statement
  | for-statement
  | while-statement
  | when-statement
  )
comment

if-equation
if expression then
   ( equation ; )*
  ( elseif expression then
   ( equation ; )*
  )*
  ( else
   ( equation ; )*
  )?
end if

if-statement
if expression then
   ( statement ; )*
  ( elseif expression then
   ( statement ; )*
  )*
  ( else
   ( statement ; )*
  )?
end if

for-equation
for for-index loop
   ( equation ; )*
end for

for-statement
for for-index loop
   ( statement ; )*
end for

for-indicesfor-index ( , for-index )*

for-indexIDENT in expression

while-statement
while expression loop
   ( statement ; )*
end while

when-equation
when expression then
   ( equation ; )*
  ( elsewhen expression then
   ( equation ; )*
  )*
end when

when-statement
when expression then
   ( statement ; )*
  ( elsewhen expression then
   ( statement ; )*
  )*
end when

connect-clauseconnect [(] component-reference , component-reference [)]

prioritize-equationprioritize [(] component-reference , priority [)]

prioritize-expressionprioritize [(] expression , priority [)]

priorityexpression

Expressions

expressionsimple-expression | if-expression

if-expression
if expression then expression
  ( elseif expression then expression )*
else expression

simple-expressionlogical-expression ( : logical-expression ( : logical-expression )? )?

logical-expressionlogical-term ( or logical-term )*

logical-termlogical-factor ( and logical-factor )*

logical-factornot? relation

relationarithmetic-expression ( relational-operator arithmetic-expression )?

relational-operator< | <= | > | >= | == | <>

arithmetic-expressionadd-operator? term ( add-operator term )*

add-operator+ | - | .+ | .-

termfactor ( mul-operator factor )*

mul-operator → ** * ** | ** / ** | ** .* ** | ** ./ **

factorprimary ( (^ | .^) primary )?

primary
  → UNSIGNED-NUMBER
  | STRING
  | false
  | true
  | ( der | initial | pure ) function-call-args
  | component-reference function-call-args?
  | [(] output-expression-list [)] array-subscripts?
  | [[] expression-list ( ; expression-list )* []]
  | { array-arguments }
  | end

type-specifier.? name

nameIDENT ( . IDENT )*

component-reference.? IDENT array-subscripts? ( . IDENT array-subscripts? )*

function-call-args[(] function-arguments? [)]

function-arguments
  → expression ( , function-arguments-non-first | for for-index )?
  | function-partial-application ( , function-arguments-non-first )?
  | named-arguments

function-arguments-non-first
  → function-argument ( , function-arguments-non-first )?
  | named-arguments

array-argumentsexpression ( ( , expression )* | for for-index )

named-argumentsnamed-argument ( , named-argument )*

named-argumentIDENT = function-argument

function-argument
  → function-partial-application
  | expression

function-partial-applicationfunction type-specifier [(] named-arguments? [)]

output-expression-listexpression? ( , expression? )*

expression-listexpression ( , expression )*

array-subscripts[ subscript ( , subscript )* ]

subscript: | expression

commentstring-comment annotation-comment?

string-comment → ( STRING ( + STRING )* )?

annotation-commentannotation class-modification