blech-lang / blech

Blech is a language for developing reactive, real-time critical embedded software.
Apache License 2.0
64 stars 5 forks source link

Grammar railroad diagram #10

Open mingodad opened 1 year ago

mingodad commented 1 year ago

Using this tool https://www.bottlecaps.de/convert/ to convert https://github.com/blech-lang/blech/blob/main/src/Frontend/Parser.fsy and manually adding the tokens from https://github.com/blech-lang/blech/blob/main/src/Frontend/BlechLexer.fsl we can have a nice navigable railroad diagram (https://en.wikipedia.org/wiki/Syntax_diagram).

Copy and paste the EBNF shown bellow at https://www.bottlecaps.de/rr/ui on the tab Edit Grammar then click the tab View Diagram.

/* converted on Thu Sep 8, 2022, 10:21 (UTC+02) by bison-to-w3c v0.59 which is Copyright (c) 2011-2022 by Gunther Rademacher <grd@gmx.net> */
//From https://github.com/blech-lang/blech/blob/main/src/Frontend/Parser.fsy
Compilation
         ::= ( Module | Signature | Program | error ) EOF

Name     ::= ID
PointedName
         ::= Name ( POINT Name )*
UnitExpr ::= NATCONST
           | PointedName
           | UnitExpr ( ( MUL | DIV ) UnitExpr | EXP NATCONST )
           | LPAREN UnitExpr RPAREN
Unit     ::= OptAnnotations UNIT ( Name ( ASSIGN UnitExpr )? | ErrorBeforeEOL EOL )
OptUnitDef
         ::= ( LBRACKET UnitExpr RBRACKET )?
Type     ::= Datatype
           | SecondClassType
Datatype ::= PointedName
           | LogicalDatatype
           | NumberDatatype
           | ArrayDatatype
LogicalDatatype
         ::= BOOL
           | BITS8
           | BITS16
           | BITS32
           | BITS64
NumberDatatype
         ::= ( FLOAT32 | FLOAT64 | NAT8 | NAT16 | NAT32 | NAT64 | INT8 | INT16 | INT32 | INT64 ) OptUnitDef
ArrayDatatype
         ::= LBRACKET Expr RBRACKET Datatype
SecondClassType
         ::= SignalType
           | SliceType
SignalType
         ::= Datatype? SIGNAL
SliceType
         ::= LBRACKET RBRACKET Datatype
OptRef   ::= REF?
TypeAnnotation
         ::= COLON Type
OptTypeAnnotation
         ::= TypeAnnotation?
OptModifiers
         ::= ( REF | ERROR )?
TypeAliasDecl
         ::= OptAnnotations OptModifiers TYPEALIAS ( Name ASSIGN Type | ErrorBeforeEOL EOL )
OpaqueTypeDecl
         ::= OptAnnotations OptModifiers TYPE ( Name | ErrorBeforeEOL EOL )
OptExtension
         ::= ( EXTENSION ExtensionMembers )?
OptExtensionDecl
         ::= ( EXTENSION ExtensionMemberDecls )?
StructDecl
         ::= OptAnnotations OptModifiers STRUCT ( Name DynamicMembers OptExtensionDecl | error ) END
StructDef
         ::= OptAnnotations OptModifiers STRUCT ( Name DynamicMembers OptExtension | error ) END
VariableQualifier
         ::= LET
           | VAR
ConstantQualifier
         ::= CONST
           | PARAM
EnumDecl ::= OptAnnotations OptModifiers ENUM ( Name OptRawType EnumTagList OptExtensionDecl | error ) END
EnumDef  ::= OptAnnotations OptModifiers ENUM ( Name OptRawType EnumTagList OptExtension | error ) END
OptRawType
         ::= ( COLON Datatype )?
EnumTagList
         ::= EnumTag+
EnumTag  ::= Name OptRawValue OptDefault OptSemicolon
OptRawValue
         ::= ( ASSIGN Expr )?
OptDefault
         ::= DEFAULT?
Location ::= ( PREV | NEXT )? Access
AssignLocation
         ::= Location
           | WILDCARD
Access   ::= Name ( POINT ( Name | LBRACKET Expr RBRACKET ) | LBRACKET Expr RBRACKET )*
Literal  ::= TRUE
           | FALSE
           | BINCONST
           | OCTCONST
           | HEXCONST
           | NumberLiteral
NumberLiteral
         ::= ( NATCONST | FLOATCONST | HEXFLOATCONST ) OptUnitDef
Initialisation
         ::= SliceInitialiser
           | BraceInitialiser
SliceInitialiser
         ::= LBRACKET OptExpr COMMA OptExpr RBRACKET Location
OptExpr  ::= Expr?
BraceInitialiser
         ::= LBRACE ( ( ArrayFieldExpr ( FieldSep ArrayFieldExpr )* | StructFieldExpr ( FieldSep StructFieldExpr )* ) OptFieldSep | error )? RBRACE
StructFieldExpr
         ::= Name ASSIGN Expr
ArrayFieldExpr
         ::= ( LBRACKET Expr RBRACKET ASSIGN )? Expr
OptFieldSep
         ::= FieldSep?
FieldSep ::= COMMA
Expr     ::= Expr ( ( AND | OR | ADD | SUB | MUL | DIV | MOD | EXP | EQU | IEQ | LES | GRT | LEQ | GEQ | IDEQU | IDIEQ | BAND | BOR | BXOR | SHR | SHL | SSHR | ROTL | ROTR ) Expr | ( COLON | AS | ASBANG ) Datatype )
           | PrimaryExpr
           | ( IF Expr THEN | TRY ) Expr ELSE Expr
PrimaryExpr
         ::= ( NOT | SUB | BNOT | LEN | CAP ) Expr
           | Location ( Inputs OptOutputs )?
           | LPAREN Expr RPAREN
           | Literal
           | ERROR
           | Initialisation
OptLocationList
         ::= ( Location ( COMMA Location )* )?
OptExprList
         ::= ( Expr ( COMMA Expr )* )?
ConditionSeq
         ::= Condition ( COMMA Condition )*
Condition
         ::= Expr
           | SignalBinding
VerificationCondition
         ::= ( ASSUME | ASSERT ) ( ConditionSeq STRING? | ErrorBeforeEOL EOL )
LocalVariable
         ::= OptAnnotations ( VariableQualifier OptRef Name ( TypeAnnotation | OptTypeAnnotation ASSIGN Expr ) | EXTERN VariableQualifier OptRef Name TypeAnnotation )
LocalConstant
         ::= OptAnnotations ( EXTERN ConstantQualifier OptRef Name TypeAnnotation | ConstantQualifier OptRef Name OptTypeAnnotation ASSIGN Expr )
ForLoops ::= FOR ( FreshLocation ( ASSIGN Expr COMMA ( Expr COMMA )? | IN | OF ) Expr DO Block | error ) END
FreshLocation
         ::= VariableQualifier Name OptTypeAnnotation
FunctionCall
         ::= Location ( OptPartial Inputs OptOutputs | ErrorBeforeEOL EOL )
ValueReceiver
         ::= AssignLocation
           | FreshLocation
ActivityCall
         ::= OptNext RUN ( ( ValueReceiver ASSIGN )? Location OptPartial Inputs OptOutputs | ErrorBeforeEOL EOL )
EmitStatement
         ::= EMIT ValueReceiver ( ASSIGN Expr )?
Block    ::= ( Stmt | Pragma | SEMICOLON )* OptReturn
Stmt     ::= ELLIPSIS
           | VerificationCondition
           | LocalVariable
           | LocalConstant
           | AssignLocation ASSIGN Expr
           | AWAIT ( ConditionSeq | PAST Expr )
           | EmitStatement
           | FunctionCall
           | ActivityCall
           | ( IF ( ConditionSeq THEN Block ( ELSEIF ConditionSeq THEN Block )* ( ELSE Block )? | error ) | WHILE ( ConditionSeq REPEAT Block | error ) | COBEGIN OptWeak ( Block ( WITH OptWeak Block )+ | error ) | DO ( Block | error ) | REPEAT ( Block ( UNTIL ConditionSeq )? | error ) | WHEN ( ConditionSeq Preemption Block ( THEN Block )? | error ) | TRY ( Block ( ELSE Block ( THEN Block )? )? | error ) ) END
           | ForLoops
Preemption
         ::= ABORT
           | RESET
           | SUSPEND
Inputs   ::= LPAREN OptExprList RPAREN
OptOutputs
         ::= ( LPAREN OptLocationList RPAREN )?
OptReturn
         ::= ( ( RETURN ( OptNext RUN Location OptPartial Inputs OptOutputs | OptExpr ) | THROW OptExpr ) OptSemicolon )?
SignalBinding
         ::= FreshLocation ASSIGN Expr
OptNext  ::= NEXT?
OptSemicolon
         ::= SEMICOLON?
OptWeak  ::= WEAK?
OptSingletonDef
         ::= SINGLETON?
OptSingletonDecl
         ::= SingletonDecl?
SingletonDecl
         ::= SINGLETON OptSingletonUsage
OptSingletonUsage
         ::= ( LBRACKET PointedName ( COMMA PointedName )* RBRACKET )?
OptPartial
         ::= QUEST?
Subprogram
         ::= OptAnnotations OptSingletonDecl FunOrAct ( Name OptPartial InputParameters OptOutputParameters OptReturns OptThrows Block | error ) END
ExternalFunction
         ::= OptAnnotations EXTERN OptSingletonDecl FUNCTION ( Name InputParameters OptOutputParameters OptReturns | ErrorBeforeEOL )
OpaqueSingleton
         ::= OptAnnotations SingletonDecl Name
Prototype
         ::= OptAnnotations OptSingletonDecl FunOrAct ( Name InputParameters OptOutputParameters OptReturns | ErrorBeforeEOL )
FunOrAct ::= FUNCTION
           | ACTIVITY
InputParameters
         ::= LPAREN ( InputParameter ( COMMA InputParameter )* | error )? RPAREN
OptOutputParameters
         ::= ( LPAREN ( OutputParameter ( COMMA OutputParameter )* | error )? RPAREN )?
OptReturns
         ::= ( RETURNS OptRef OptSharing Type )?
OptThrows
         ::= ( THROWS Datatype )?
InputParameter
         ::= OptRef Name OptSharing COLON Type
OutputParameter
         ::= Name OptSharing COLON Type
OptSharing
         ::= ( SHARES Name ( COMMA Name )* )?
Constant ::= OptAnnotations ConstantQualifier ( OptRef Name OptTypeAnnotation ASSIGN Expr | ErrorBeforeEOL EOL )
ExternalConstant
         ::= OptAnnotations EXTERN ConstantQualifier ( OptRef Name TypeAnnotation | ErrorBeforeEOL EOL )
Variable ::= OptAnnotations VariableQualifier ( OptRef Name ( TypeAnnotation | OptTypeAnnotation ASSIGN Expr ) | ErrorBeforeEOL EOL )
ExternalVariable
         ::= OptAnnotations EXTERN VariableQualifier ( OptRef Name TypeAnnotation | ErrorBeforeEOL EOL )
ModuleMember
         ::= Unit
           | EnumDef
           | StructDef
           | OpaqueSingleton
           | ExtensionMember
           | Extension
           | Pragma
ExtensionMember
         ::= Subprogram
           | ExternalFunction
           | Constant
           | ExternalConstant
           | TypeAliasDecl
DynamicMember
         ::= Variable
ModuleMembers
         ::= ( ModuleMember | SEMICOLON )*
ExtensionMembers
         ::= ( ExtensionMember | Pragma | SEMICOLON )*
DynamicMembers
         ::= ( DynamicMember | Pragma | SEMICOLON )*
Extension
         ::= EXTENSION Name ExtensionMembers END
ModuleHead
         ::= INTERNAL? MODULE
ModuleSpec
         ::= OptAnnotations ModuleHead ( Exposing | ErrorBeforeEOL EOL )
Exposing ::= ( EXPOSES ( Name ( COMMA Name )* | ErrorBeforeEOL EOL ) )?
ModulePath
         ::= STRING
Import   ::= IMPORT ( INTERNAL? NameOrWildcard ModulePath Exposing | ErrorBeforeEOL EOL )
NameOrWildcard
         ::= Name
           | WILDCARD
ImportList
         ::= ( Import | SEMICOLON )*
Module   ::= ImportList ModuleSpec ModuleMembers
Program  ::= ImportList ModuleMember ModuleMembers
SignatureHead
         ::= INTERNAL? SIGNATURE
SignatureSpec
         ::= OptAnnotations SignatureHead
SignatureMember
         ::= Unit
           | EnumDecl
           | StructDecl
           | OpaqueTypeDecl
           | OpaqueSingleton
           | ExtensionMemberDecl
           | ExtensionDecl
ExtensionDecl
         ::= EXTENSION Name ExtensionMemberDecls END
ExtensionMemberDecl
         ::= Prototype
           | ExternalFunction
           | Constant
           | ExternalConstant
           | TypeAliasDecl
ExtensionMemberDecls
         ::= ( ExtensionMemberDecl | Pragma | SEMICOLON )*
Signature
         ::= ImportList SignatureSpec ( SignatureMember | Pragma | SEMICOLON )*
ErrorBeforeEOL
         ::= error
Pragma   ::= ATAT LBRACKET Attribute RBRACKET
OptAnnotations
         ::= Annotation*
Annotation
         ::= AT LBRACKET Attribute RBRACKET
           | LINEDOC
           | BLOCKDOC
Attribute
         ::= Identifier ( ASSIGN AttributeLiteral | LPAREN ( Attribute COMMA )* Attribute? RPAREN )?
Identifier
         ::= STRING
           | ID
AttributeLiteral
         ::= STRING
           | MULTILINESTRING
           | TRUE
           | FALSE
           | BINCONST
           | OCTCONST
           | HEXCONST
           | OptSub ( NATCONST | FLOATCONST | HEXFLOATCONST )
OptSub   ::= SUB?

//Tokens
//From https://github.com/blech-lang/blech/blob/main/src/Frontend/BlechLexer.fsl
//| \("[^"]+"\)\s+{ \(\w+\).+  -> \2 ::= \1
/*
| "/*"                  { commentDepth <- 1
                              commentStart <- Some (getRange lexbuf)
                              SkipBlockComment lexbuf }

| "//"                  { SkipLineComment lexbuf }

(* --- strings --- *)

| '"'                   { startString lexbuf
              CollectSingleLineString lexbuf }

| triplequotes          { startString lexbuf
              CollectMultiLineString lexbuf }

(* ---- doc comments ---- *)

| "///"                 { tokenBuilder.Init (getRange lexbuf)
              CollectLineDoc lexbuf }

| "/**"                 { tokenBuilder.Init (getRange lexbuf)
              CollectBlockDoc lexbuf }
*/
/* ---- file system: reserved directory name for blech transpilations ---- */
BLECH ::= "blech"

/* ---- module system ---- */
MODULE ::= "module"
IMPORT ::= "import"
EXPOSES ::= "exposes"
SIGNATURE ::= "signature"
INTERNAL ::= "internal"

/* --- extensions --- */

EXTENSION ::= "extension"

/* ---- predefined types ---- */

BOOL ::= "bool"

BITS8 ::= "bits8"
BITS16 ::= "bits16"
BITS32 ::= "bits32"
BITS64 ::= "bits64"

NAT8 ::= "nat8"
NAT16 ::= "nat16"
NAT32 ::= "nat32"
NAT64 ::= "nat64"

INT8 ::= "int8"
INT16 ::= "int16"
INT32 ::= "int32"
INT64 ::= "int64"

FLOAT32 ::= "float32"
FLOAT64 ::= "float64"

/* --- user-defined types --- */

TYPEALIAS ::= "typealias"
TYPE ::= "type"
ENUM ::= "enum"
STRUCT ::= "struct"

/* --- signals --- */
SIGNAL ::= "signal"

/* --------- units of measure --------- */
UNIT ::= "unit"

/* --- clocks --- */
/*CLOCK ::= "clock"
COUNT ::= "count"
UP ::= "up"
DOWN ::= "down"
OFF ::= "off"
JOIN ::= "join"
MEET ::= "meet"
TICK ::= "tick"
ON ::= "on"
*/

/* --------- actions --------- */

EMIT ::= "emit"
PAST ::= "past"
ASSIGN ::= "="
ASSUME ::= "assume"
ASSERT ::= "assert"

/* --------- types, activties, functions --------- */

ACTIVITY ::= "activity"
FUNCTION ::= "function"
VAR ::= "var"
LET ::= "let"
REF ::= "ref"

SINGLETON ::= "singleton"
PARAM ::= "param"
CONST ::= "const"

SHARES ::= "shares"

/* ----- FFI ------ */
EXTERN ::= "extern"

/* --------- Blech statements --------- */

ABORT ::= "abort"
AWAIT ::= "await"
COBEGIN ::= "cobegin"
DEFAULT ::= "default"
DO ::= "do"
ELSE ::= "else"
ELSEIF ::= "elseif"
END ::= "end"
FOR ::= "for"
IF ::= "if"
IN ::= "in"
OF ::= "of"
PRINT ::= "print"
REPEAT ::= "repeat"
RUN ::= "run"
RESET ::= "reset"
RETURN ::= "return"
RETURNS ::= "returns"
SUSPEND ::= "suspend"
THEN ::= "then"
UNTIL ::= "until"
WEAK ::= "weak"
WHEN ::= "when"
WHILE ::= "while"
WITH ::= "with"
TRY ::= "try"
THROW ::= "throw"
THROWS ::= "throws"

/* ----- error handling -----*/
ERROR ::= "error"

/* --------- expressions and operators --------- */

TRUE ::= "true"
FALSE ::= "false"

/* logical operators */
NOT ::= "not"
AND ::= "and"
OR ::= "or"

/* arithmetic operators */
ADD ::= "+"
SUB ::= "-"
MUL ::= "*"
DIV ::= "/"
MOD ::= "%"
EXP ::= "**"

/* bitwise operators */
BAND ::= "&"
BOR ::= "|"
BXOR ::= "^"
BNOT ::= "~"
SHL ::= "<<"
SHR ::= ">>"

/* advanced bitwise operators */
SSHR ::= "+>>"
ROTL ::= "<<>"
ROTR ::= "<>>"

/* relational operators */
EQU ::= "=="
IEQ ::= "!="
LES ::= "<"
LEQ ::= "<="
GRT ::= ">"
GEQ ::= ">="

/* identity operators */
IDEQU ::= "==="
IDIEQ ::= "!=="

/* static cast */
AS ::= "as"

/* forced cast */
ASBANG ::= "as!"

/* annotations */
AT ::= "@"
ATAT ::= "@@"

/* length operators on arrays and slices */
LEN ::= "#"
CAP ::= "##"

/* -------------- Access operators ------------*/
PREV ::= "prev"
NEXT ::= "next"

/* --------- delimiters and punctuations --------- */

LBRACE ::= "{"
RBRACE ::= "}"
LBRACKET ::= "["
RBRACKET ::= "]"
LPAREN ::= "("
RPAREN ::= ")"
ELLIPSIS ::= "..."
POINT ::= "."
COLON ::= ":"
COMMA ::= ","
SEMICOLON ::= ";"
QUEST ::= "?"

/* --------- literals --------- */
/*
| binliteral            { BINCONST  (getLexemeAndRange lexbuf) }

| octliteral            { OCTCONST (getLexemeAndRange lexbuf) }

| hexliteral            { HEXCONST (getLexemeAndRange lexbuf) }

| natliteral            { NATCONST (getLexemeAndRange lexbuf) }

| floatliteral          { FLOATCONST (getLexemeAndRange lexbuf) }

| hexfloatliteral       { HEXFLOATCONST (getLexemeAndRange lexbuf) }

| identifier            { ID (getLexemeAndRange lexbuf) }

| wildcard              { WILDCARD (getLexemeAndRange lexbuf) }
*/
/* --------- end of file and invalid source code characters  --------- */
/*
| eof                   { EOF (getRange lexbuf) }

| _                     { unknownToken lexbuf;
              Token lexbuf }
*/