The BNF - definition of MLL (MyLittleLang)


# (c) Harald Glab-Plhak, 2026
program
    ::= statement* EOF
statement
    ::= declaration ";"
      | assignment ";"
      | input ";"
      | output ";"
      | gotoStatement ";"
      | brainfuckStatement ";"
      | breakStatement ";"
      | whileStatement
      | ifStatement
      | labelStatement
declaration
    ::= "dcl" type IDENTIFIER sizedDimension*
# The number of sized dimensions after the identifier must equal the number
# of [] suffixes in type.  Sizes are positive compile-time integer literals.
type
    ::= baseType arraySuffix*
baseType
    ::= "string"
      | "number"
      | "integer"
      | "long"
      | "float"
      | "double"
arraySuffix
    ::= "[" "]"
sizedDimension
    ::= "[" INTEGER_LITERAL "]"
assignment
    ::= reference "=" expression
input
    ::= "in" reference
output
    ::= "out" expression
reference
    ::= IDENTIFIER indexSuffix*
indexSuffix
    ::= "[" INTEGER_LITERAL "]"
labelStatement
    ::= IDENTIFIER ":"
      | "label" IDENTIFIER ":"
gotoStatement
    ::= "goto" IDENTIFIER
brainfuckStatement
    ::= "brainfuck" STRING_LITERAL
breakStatement
    ::= "break"
whileStatement
    ::= "while" expression "do" ";"
        statement*
        "end" ";"
ifStatement
    ::= "if" expression "then" ";"
        statement*
        ("else" ";" statement*)?
        "end" ";"
expression
    ::= comparison
comparison
    ::= additive
        (("==" | "!=" | "<" | "<=" | ">" | ">=") additive)?
additive
    ::= multiplicative (("+" | "-") multiplicative)*
multiplicative
    ::= power (("*" | "/") power)*
power
    ::= postfix ("^" power)?
postfix
    ::= primary postfixOperation*
postfixOperation
    ::= "." "concat" "(" expression ")"
      | "." "toNumeric" ("(" ")")?
primary
    ::= literal
      | ("+" | "-") literal
      | reference
      | "(" expression ")"
literal
    ::= INTEGER_LITERAL
      | DECIMAL_FLOAT_LITERAL
      | HEX_FLOAT_LITERAL
      | STRING_LITERAL
DECIMAL_FLOAT_LITERAL
    ::= decimalFraction decimalExponent? FLOAT_SUFFIX?
      | DIGIT+ decimalExponent FLOAT_SUFFIX?
      | DIGIT+ FLOAT_SUFFIX
decimalFraction
    ::= DIGIT* "." DIGIT+
      | DIGIT+ "." DIGIT*
decimalExponent
    ::= ("e" | "E") SIGN? DIGIT+
HEX_FLOAT_LITERAL
    ::= ("0x" | "0X") hexSignificand binaryExponent FLOAT_SUFFIX?
hexSignificand
    ::= HEX_DIGIT+ ("." HEX_DIGIT*)?
      | "." HEX_DIGIT+
binaryExponent
    ::= ("p" | "P") SIGN? DIGIT+
# f/F selects binary32; no suffix selects binary64. l/L is tokenized so the
# compiler can issue a precise unsupported-long-double diagnostic.
FLOAT_SUFFIX
    ::= "f" | "F" | "l" | "L"
SIGN
    ::= "+" | "-"
STRING_LITERAL
    ::= '"' stringCharacter* '"'
stringCharacter
    ::= anySourceByteExceptQuoteBackslashOrNewline
      | simpleEscape
      | octalEscape
      | hexadecimalEscape
simpleEscape
    ::= "\\'" | '\\"' | "\\?" | "\\\\"
      | "\\a" | "\\b" | "\\f" | "\\n"
      | "\\r" | "\\t" | "\\v"
octalEscape
    ::= "\\" OCTAL_DIGIT OCTAL_DIGIT? OCTAL_DIGIT?
hexadecimalEscape
    ::= "\\x" HEX_DIGIT+
IDENTIFIER
    ::= LETTER (LETTER | DIGIT | "_")*
INTEGER_LITERAL
    ::= DIGIT+
LETTER
    ::= "A"..."Z" | "a"..."z" | "_"
DIGIT
    ::= "0"..."9"
OCTAL_DIGIT
    ::= "0"..."7"
HEX_DIGIT
    ::= DIGIT | "A"..."F" | "a"..."f"
(c) Harald Glab-Plhak, 2026