Skip to content

Instantly share code, notes, and snippets.

@gingerBill
Last active September 22, 2023 00:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save gingerBill/f7a9091a92d46895789a9ce633da25f7 to your computer and use it in GitHub Desktop.
Save gingerBill/f7a9091a92d46895789a9ce633da25f7 to your computer and use it in GitHub Desktop.
Odin EBNF (Work In Progress)
/* characters */
newline = /* the Unicode code point U+000A */ .
unicode_char = /* an arbitrary Unicode codepoint except newline */ .
unicode_letter = /* a Unicode code point categorized as "Letter" */ .
unicode_digit = /* a Unicode code point categorized as "Number, decimal digit" */ .
letter = unicode_letter | "_" .
decimal_digit = "0" ... "9" .
binary_digit = "0" | "1" .
octal_digit = "0" ... "7" .
dozenal_digit = "0" ... "9" | "A" | "B" | "a" | "b" .
hex_digit = "0" ... "9" | "A" ... "F" | "a" ... "f" .
/* basic tokens */
identifier = letter { letter | unicode_digit } .
OptionalNewline = [ newline ] .
int_lit = decimal_lit | binary_lit | octal_lit | dozenal_lit | hex_lit .
decimal_lit = ["Od"] "0" | ( "1" ... "9" ) [ [ "_" ] decimal_digits ] .
binary_lit = "Ob" [ "_" ] binary_digits .
octal_lit = "Oo" [ "_" ] octal_digits .
dozenal_lit = "Oz" [ "_" ] dozenal_digits .
hex_lit = "Ox" [ "_" ] hex_digits .
float_lit = decimal_float_lit | hex_float_lit .
decimal_float_lit = decimal_digits "." [ decimal_digits ] [ decimal_exponent ] |
decimal_digits decimal_exponent |
"." decimal_digits [ decimal_exponent ] .
decimal_exponent = ( "e" | "E" ) [ "+" | "-" ] decimal_digits .
hex_float_lit = "0h" [ "_" ] hex_digits .
imaginary_lit = (decimal_digits | int_lit | float_lit ) ( "i" | "j" | "k" ) .
rune_lit = "'" ( unicode_value | byte_value ) "'" .
unicode_value = unicode_char | little_u_value | big_u_value | escaped_char .
byte_value = octal_byte_value | hex_byte_value .
octal_byte_value = `\` octal_digit octal_digit octal_digit .
hex_byte_value = `\` "x" hex_digit hex_digit .
little_u_value = `\` "u" hex_digit hex_digit hex_digit hex_digit .
big_u_value = `\` "U" hex_digit hex_digit hex_digit hex_digit
hex_digit hex_digit hex_digit hex_digit .
escaped_char = `\` ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | `\` | "'" | `"` ) .
string_lit = raw_string_lit | interpreted_string_lit .
raw_string_lit = "`" { unicode_char | newline } "`" .
interpreted_string_lit = `"` { unicode_value | byte_value } `"` .
/* Types */
IdentifierList = identifier { "," identifier } .
PolyNameList = PolyName { "," PolyName } .
PolyName = "$" identifier .
Type = TypeName | TypeKinds | PolyType | Expression | (" Type ")" .
TypeName = identifier | QualifiedIdent | "typeid" .
PolyType = PolyName [ "/" Type ] .
TypeKinds = DistinctType | HelperType |
PointerType | MultiPointerType | ArrayType |
SliceType | DynamicArrayType | MapType | MatrixType
StructType | UnionType |
EnumType | BitSetType | SimdVectorType | SoaArrayType |
SoaPointerType | ProcedureType .
DistinctType = "distinct" Type .
HelperType = "#" "type" Type .
PointerType = "^" Type .
MultiPointerType = "[" "^" "]" Type .
ArrayType = "[" Expression "]" Type . /* enumerated arrays too have the same form */
SliceType = "[" "]" Type .
DynamicArrayType = "[" "dynamic" "]" Type .
MapType = "map" "[" Type "]" Type .
MatrixType = "matrix" "[" Expression "," Expression "]" Type .
StructType = "struct" [ "(" Parameters ")" [ WhereClauses ] ] { StructDirective } OptionalNewline "{"
[ StructField { "," StructField } [ "," ] ] "}" .
UnionType = "union" [ "(" Parameters ")" [ WhereClauses ] ] { UnionDirective } OptionalNewline "{"
[ Type { "," Type } [ "," ] ] "}" .
StructDirective = "#" ( ( "align" Expression ) | "packed" | "raw_union" ) .
UnionDirective = "#" ( ( "align" Expression ) | "no_nil" | "shared_nil" ) .
StructField = [ "using" ] IdentifierList ":" Type [ string_lit ] .
WhereClauses = OptionalNewline "where" Expression { "," Expression } .
EnumType = "enum" [ Type ] OptionalNewline "{"
[ EnumField { "," EnumField } [ "," ] ] "}" .
EnumField = identifier [ "=" Expression ] .
BitSetType = "bit_set" "[" Type | RangeExpr [ ";" Type ] "]" .
SimdVectorType = "#" "simd" ArrayType .
SoaArrayType = "#" "soa" (ArrayType | SliceType | DynamicArrayType) .
SoaPointerType = "#" "soa" "^" (SoaArrayType | Type) .
ProcedureType = "proc" Signature .
Signature = Parameters [ "->" Result ] .
Result = "!" | Parameters | Type .
Parameters = "(" [ ParameterList [ "," ] ] ")" .
ParametersList = ParameterDecl { "," ParameterDecl } .
ParameterDecl = { ParameterDeclDirective } ParameterDeclList .
ParameterDeclList =
[ ( IdentifierList | PolyNameList ) ":" ] [ ".." ] Type ) |
( ( Identifier | PolyName ) ":" [ Type] "=" ParameterValue ) .
ParameterDeclDirective = "using" | "auto_cast" | Directive .
ParameterValue = "#" "caller_location" | Expression .
/* Declarations and scope */
Declaration = ValueDecl | ForeignBlock .
TopLevelDecl = Declaration | ImportDecl | ForeignImportDecl | TopLevelWhenDecl.
ValueDecl = VarValueDecl | ConstValueDecl .
VarValueDecl = { Attribute } [ "using" ] IdentifierList ":" (
Type |
[ Type ] "=" ExpressionList
) .
ConstValueDecl = { Attribute } IdentifierList ":" [ Type ] ":" ExpressionList .
ForeignBlock = { Attribute } "foreign" [ Identifier ] "{" { ValueDecl ";" } "}" .
ImportDecl = "import" [ Identifier ] ImportPath .
ImportPath = string_lit .
ForeignImportDecl = { Attribute } "foreign" import" [ Identifier ] ForeignImportPath .
ForeignImportPath = string_lit | ( OptionalNewline "{" StringLitList [ "," ] "}" ) .
StringLitList = string_lit { "," string_lit } .
TopLevelWhenDecl = "when" Expression TopLevelWhenBlock [ "else" ( TopLevelWhenDecl | TopLevelWhenBlock ) ] .
TopLevelWhenBlock = OptionalNewline "{" { TopLevelDecl ";" } "}" ."
Attribute = "@" Identifier | "(" AttributeFieldList ")" .
AttributeFieldList = AttributeField { "," AttributeField } [ "," ] .
AttributeField = Identifier [ "=" Expression ] .
SourceFile = PackageClause ";" { TopLevelDecl ";" } .
PackageClause = "package" Identifier .
/* Statements */
Statement = Declaration | SimpleStmt | DirectiveStmt |
Block | IfStmt | WhenStmt | ReturnStmt |
ForStmt | RangeStmt | SwitchStmt | TypeSwitchStmt |
DeferStmt | UsingStmt | BranchStmt | LabeledStmt .
StatementList = { Statement ";" } .
SimpleStmt = EmptyStmt | ExpressionStmt | Assignment .
EmptyStmt = .
ExpressionStmt = Expression .
Assignment = LhsExpressionList "=" ExpressionList .
DirectiveStmt = Directive Statement .
Directive = "#" identifier .
Block = "{" StatementList "}" .
ControlFlowBlock = ( OptionalNewline Block) | "do" Statement .
InitStmt = SimpleStmt | ValueDecl .
IfStmt = "if" [ InitStmt ";" ] Expression ControlFlowBlock [ "else" ( IfStmt | ControlFlowBlock ) ] .
WhenStmt = "when" Expression ControlFlowBlock [ "else" ( WhenStatement | ControlFlowBlock ) ] .
ReturnStmt = "return" [ ExpressionList ] .
ForStmt = [ Directive ] "for" [ Condition | ForClause ] ControlFlowBlock .
Condition = LhsExpression .
ForClause = [ InitStmt ] ";" [ Condition ] ";" [ PostStmt ] .
PostStmt = SimpleStmt .
RangeStmt = [ Directive ] "for" RangeClause ControlFlowBlock .
RangeClause = [ RangeClauseIdentifierList ] "in" RangeParameter .
RangeClauseIdentifierList = Identifier [ "," Identifier ] .
RangeParameter = Condition | RangeExpr .
SwitchStmt = [ Directive ] "switch" [ InitStmt ";" ] [ Condition ] OptionalNewline "{" { ExprCaseClause } "}" .
ExprCaseClause = ExprSwitchCase ":" StatementList .
ExprSwitchCase = "case" [ ExpressionOrRangeList ] .
TypeSwitchStmt = [ Directive ] "switch" [ identifier ] "in" Condition OptionalNewline "{" { TypeCaseClause } "}" .
TypeCaseClause = TypeSwitchCase ":" StatementList .
TypeSwitchCase = "case" [ ExpressionList ] .
DeferStmt = "defer" Statement .
UsingStmt = "using" ExpressionList .
BranchStmt = "fallthrough" | ( ( "break" | "continue" ) [ Label ] ) .
LabeledStmt = identifier ";" ( Block | IfStmt | ForStmt | RangeStmt | SwitchStmt | TypeSwitchStmt ) .
/* Expressions */
Expression = LhsExpression | RhsExpression .
LhsExpression = Operand | AtomExpr | AtomExpr | LhsBinaryExpr | ParenExpr .
RhsExpression = LhsExpression | CompoundLit | BinaryExpr | TernaryExpr .
ExpressionList = Expression { "," Expression } .
ExpressionOrRangeList = ( Expression | RangeExpr ) { "," ( Expression | RangeExpr ) } .
LhsExpressionList = LhsExpression { "," LhsExpression } .
RangeExpr = ( Expression ( "..<" | "..=" ) Expression ) .
Operand =
identifer |
"---" |
"context" |
int_lit | float_lit | imaginary_lit | rune_lit | string_lit |
DirectiveExpr |
ParenExpr |
Type |
BareCompoundLit |
ProcedureLit .
DirectiveExpr = Directive Expression .
ParenExpr = "(" (LhsExpression|RhsExpression) ")" .
TypedCompoundLit = CompoundTypeLit OptionalNewline BareCompoundLit .
BareCompoundLit = "{" [ CompoundFieldList ] "}" .
CompoundFieldList = CompoundField { "," CompoundField } [ "," ] .
CompoundField = ( Expression | RangeExpr ) [ "=" Expression ] .
CompoundTypeLit =
Ident | SelectorExpr |
ArrayType | SliceType | DynamicArrayType |
StructType |
UnionType |
EnumType |
MapType |
BitSetType |
MatrixType |
CallExpr .
ProcedureLit = ProcedureType [ WhereClauses ] ( "---" | Block ) .
CallExpr = Expr "(" [ Arguments ] ")" .
Arguments = Argument { "," Argument } "," .
Argument = [ ( identifier "=") | ".." ] Expression .
AtomExpr =
CallExpr |
SelectorExpr | TypeAssertion |
IndexExpr | MatrixIndexExpr | SliceExpr |
DereferenceExpr |
OrReturnExpr |
TypedCompoundLit .
SelectorExpr = Expression ( "." | "->" ) identifier .
TypeAssertion = Expression "." ( "?" | ( "(" Type ")" ) ) .
IndexExpr = Expression "[" Expression "]" .
MatrixIndexExpr = Expression "[" Expression "," Expression "]" .
SliceExpr = Expression "[" [ Expression ] ":" [ Expression ] "]" .
DereferenceExpr = Expression "^" .
OrReturnExpr = Expression "or_return" .
UnaryExpr =
CastExpr |
AutoCastExpr |
UnaryArithmeticExpr |
AddressOfExpr |
ImplicitSelectorExpr .
CastExpr = ( "cast" | "transmute" ) Expression .
AutoCastExpr = "auto_cast" Expression .
UnaryArithmeticExpr = ( "+" | "-" | "~" | "!" ) Expression .
AddressOfExpr = "&" Expression .
ImplicitSelectorExpr = "." identifier .
/* These don't take into account precendence rules */
BinaryExpr = Expression BinaryOp Expression .
LhsBinaryExpr = Expression LhsBinaryOp Expression .
TernaryExpr = TenaryIfExpr | TernaryWhenExpr .
TernaryIfExpr =
( Condition "?" Expression ":" Expression ) |
( Expression "if" Condition "else" Expression ) .
TernaryWhenExpr = Expression "when" Condition "else" Expression .
LhsBinaryOp =
"or_else" |
"||" |
"&&" |
"==" | "!=" | "<" | ">" | "<=" | ">=" |
"+" | "-" | "|" | "~" |
"*" | "/" | "%" | "%%" | "&" | "&~" | "<<" | ">>" .
BinaryOp = LhsBinaryOp | "in" | "not_in" .
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment