aufbau 0.1.2

Generalized prefix parsing for a class of context-dependent languages
Documentation
// TypeScript syntax subset
// Focus: declarations, function syntax, blocks, if/else, arrays, unions

Identifier ::= /[a-zA-Z_][a-zA-Z0-9_]*/
TypeName ::= 'string' | 'number' | 'boolean' | 'void'

BaseType ::= TypeName | '(' Type ')'
ArrayType ::= BaseType '[' ']'
UnionTail ::= '|' TypePart
TypePart ::= ArrayType | BaseType
Type ::= TypePart UnionTail?

String ::= /"[^"]*"/
Number ::= /[0-9]+(\.[0-9]+)?/
Boolean ::= 'true' | 'false'

Variable(var) ::= Identifier[x]

ArrayRest ::= ',' Expression
ArrayLiteral(array) ::= '[' ']' | '[' Expression ']'

Primary ::= Variable
         | String
         | Number
         | Boolean
         | ArrayLiteral
         | '(' Expression ')'

CallArgRest ::= ',' Expression
CallArgs(args) ::= Expression CallArgRest?
Call(call) ::= Primary[func] '(' ')' | Primary[func] '(' CallArgs[args] ')'

Expression ::= Call
             | Primary

Parameter(param) ::= Identifier[name] ':' Type[τ]
ParamRest ::= ',' Parameter
ParameterList(params) ::= Parameter ParamRest? | ε

ExprOpt ::= Expression?
ReturnStmt(ret) ::= 'return' ExprOpt[value] ';'
ExprStmt(stmt) ::= Expression ';'
VarDecl(decl) ::= 'let' Identifier[name] ':' Type[τ] '=' Expression[value] ';'
ConstDecl(const_decl) ::= 'const' Identifier[name] ':' Type[τ] '=' Expression[value] ';'

Block(block) ::= '{' Statement '}'
IfStmt(if_else) ::= 'if' '(' Expression[cond] ')' Block[then_block] 'else' Block[else_block]
FunctionDecl(function) ::= 'function' Identifier[name] '(' ParameterList[params] ')' ':' Type[ret] Block[body]

Statement ::= FunctionDecl | VarDecl | ConstDecl | ReturnStmt | IfStmt | ExprStmt
Program(program) ::= Statement

start ::= Program