Skip to content

Instantly share code, notes, and snippets.

@gingerBill
Last active March 17, 2021 04:37
Show Gist options
  • Save gingerBill/d4b2a4d813d18eaa6f28a2eb6c7a112a to your computer and use it in GitHub Desktop.
Save gingerBill/d4b2a4d813d18eaa6f28a2eb6c7a112a to your computer and use it in GitHub Desktop.
Odin EBNF
/*
Production = production_name "=" [ Expression ] "." .
Expression = Alternative { "|" Alternative } .
Alternative = Term { Term } .
Term = production_name | token [ "…" token ] | Group | Option | Repetition .
Group = "(" Expression ")" .
Option = "[" Expression "]" .
Repetition = "{" Expression "}" .
| alternation
() grouping
[] option (0 or 1 times)
{} repetition (0 to n times)
*/
/* Characters */
newline = /* the Unicode code point U+000A */ .
unicode_char = /* an arbitrary Unicode code point except newline */ .
unicode_letter = /* a Unicode code point classified as "Letter" */ .
unicode_digit = /* a Unicode code point classified as "Number, decimal digit" */ .
/* Letters and Digits */
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" .
identifier = letter { letter | unicode_digit } .
/* Integer Literals */
int_lit = decimal_lit | binary_lit | octal_lit | dozenal_lit | hex_lit .
decimal_lit = ["0" "d"] decimal_digits [ ["_"] decimal_digits ] .
binary_lit = "0" "b" ["_"] binary_digits .
octal_lit = "0" "o" ["_"] octal_digits .
dozenal_lit = "0" "z" ["_"] dozenal_digits .
hex_lit = "0" "x" ["_"] hex_digits .
decimal_digits = decimal_digit { "_" decimal_digit } .
binary_digits = binary_digit { "_" binary_digit } .
octal_digits = octal_digit { "_" octal_digit } .
dozenal_digits = dozenal_digit { "_" dozenal_digit } .
hex_digits = hex_digit { "_" hex_digit } .
/* Floating-point literals */
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 = "0" "h" hex_digits .
/* Imaginary literals */
imaginary_lit = (decimal_digits | int_lit | float_lit) ("i" | "j" | "k") .
/* Rune literals */
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" | "e" | "f" | "n" | "r" | "t" | "v" | `\` | "'" | `"` ) .
/* String literals */
string_lit = raw_string_lit | interpreted_string_lit .
raw_string_lit = "`" { unicode_char | newline } "`" .
interpreted_string_lit = `"` { unicode_value | byte_value } `"` .
/* Syntax */
SourceFile = PackageDecl ";" { TopLevelDecl ";" } .
PackageDecl = "package" PackageName .
PackageName = identifier .
Attribute = "@" identifier | "@" Arguments .
TopLevelDecl = ( { Attribute } (ImportDecl | ValueDecl | ForeignBlockDecl | ForeignImportDecl) ) |
ConstAssertPanic .
ValueDecl = ConstDecl | VarDecl .
ConstAssertPanic = "#" ( "assert" | "panic" ) Arguments .
ImportDecl = "import" [ PackageName ] ImportPath .
ImportPath = string_lit .
ForeignImportDecl = "foreign" "import" [ PackageName ] (ImportPath | ForeignImportPaths ) .
ForeignImportPaths = "{" [ ForeignImportPathList [ "," ] ] "}" .
ForeignImportPathList = ImportPath { "," ImportPath } .
IdentifierList = identifier { "," identifier } .
ExpressionList = Expression { "," Expression } .
ConstExpression = Expression | ProcedureGroup | "distinct" Type | "(" ConstExpression ")" .
ConstExpressionList = ConstExpression { "," ConstExpression } .
ConstDecl = IdentifierList ":" [ Type ] ":" ConstExpressionList .
VarDecl = IdentifierList ":" [ Type ] [ "=" ExpressionList ].
ForeignBlockDecl = "foreign" [ identifier ] "{" { { Attribute } ValueDecl } "}" .
ProcedureGroup = "proc" "{" ExpressionList [ "," ] "}" .
/* Types */
PolymorphicName = "$" identifier .
PolymorphicNameList = PolymorphicName { "," PolymorphicName } .
Type = TypeName | TypeLit | "(" Type ")" | HelperType | Expression .
TypeName = identifier | PolymorphicName .
TypeLit = "typeid" |
ArrayType | SliceType | DynamicArrayType | MapType |
StructType | UnionType | EnumType | BitFieldType |
PointerType | ProcedureType |
BitSetType |
OpaqueType |
SimdVectorType |
RelativePointerType | RelativeSliceType .
HelperType = "#" "type" Type .
TypeOrWithSpecialization = Type | ( ("typeid" | PolymorphicName) "/" TypeOrWithSpecialization ) .
ArrayLength = Expression .
EnumeratedArrayType = Type .
ElementType = Type .
ArrayType = [ "#" "partial" ] "[" ( ArrayLength | EnumeratedArrayType ) "]" ElementType .
SliceType = "[" "]" Type .
DynamicArrayType = "[" "dynamic" "]" Type .
MapType = "map" "[" Type "]" Type .
PointerType = "^" Type .
BitSetKeyType = Type | ( Expression range_op Expression ) .
BitSetType = "bit_set" "[" BitSetKeyType [ ";" Type ] "]" .
OpaqueType = "opaque" Type .
SimdVectorType = "#" "simd" ArrayType .
RelativePointerType = "#" "relative" "(" Type [ "," ] ")" PointerType .
RelativeSliceType = "#" "relative" "(" Type [ "," ] ")" SliceType .
WhereClause = "where" ExpressionList .
PolymorphicParameter = (IdentifierList | PolymorphicNameList) [":"] TypeOrWithSpecialization .
PolymorphicParameterList = "(" PolymorphicParameter { "," PolymorphicParameter } [ "," ] ")" .
StructTypeTags = [ ( "#" "align" Expression ) | ("#" "packed") | ("#" "raw_union") ] .
UnionTypeTags = [ ( "#" "align" Expression ) | ("#" "no_nil") |("#" "maybe") ] .
BitFieldTags = [ ( "#" "align" Expression ) ] .
StructFieldDecl = ( [ ("using") ] IdentifierList ":" Type ) .
StructFieldList = StructFieldDecl { "," StructFieldDecl } .
Element = identifier [ "=" Expression ] .
ElementList = Element { "," Element } .
StructType = "struct" [PolymorphicParameterList] [StructTypeTags] [WhereClause] "{" StructFieldList [ "," ] "}" .
UnionType = "union" [PolymorphicParameterList] [UnionTypeTags] [WhereClause] "{" ExpressionList [ "," ] "}" .
EnumType = "enum" [ Type ] "{" ElementList [ "," ] "}" .
BitFieldField = IdentifierList ":" Expression .
BitFieldFieldList = BitFieldField { "," BitFieldField } .
BitFieldFields = [ BitFieldFieldList [ "," ] ] .
BitFieldType = "bit_field" (BitFieldTags) "{" BitFieldFields "}" .
ProcedureTags = "#" "optional_ok" .
ProcedureType = "proc" Signature .
Signature = Parameters | [ "->" Result ] [ ProcedureTags ] .
Result = PlainParameters | Type .
Parameters = "(" [ ParameterList [","] ] ")" .
ParameterList = ParameterDecl { "," ParameterDecl } .
ParameterPrefixes = "using" | ("#" "no_alias") | ("#" "c_vararg") | "auto_cast" | ("#" "const") .
ParameterDecl = [ [ParameterPrefixes] (IdentifierList | PolymorphicNameList) [ [":"] ".." TypeOrWithSpecialization ] ] .
PlainParameters = "(" [ PlainParameterList [","] ] ")" .
PlainParameterList = PlainParameterDecl { "," PlainParameterDecl } .
PlainParameterDecl = [ (IdentifierList | PolymorphicNameList) [ [":"] ".." TypeOrWithSpecialization ] ] .
/* Expressions */
ProcedureLitTags = "#" ("bounds_check" | "no_bounds_check") .
ProcedureLit = "proc" Signature [ProcedureLitTags] ProcedureBody .
ProcedureBody = Block .
/* Statements */
Block = "{" StatementList "}" .
StatementList = { Statement ";" } .
Statement =
LabeledStmt | SimpleStmt | ReturnStmt | BreakStmt | ContinueStmt | FallthroughStmt |
Block | IfStmt | SwitchStmt | ForStmt | InlineRangeStmt | WhenStmt | DeferStmt | UsingStmt |
TagStmt | DeclStmt .
Label = identifier .
LabeledStmt = Label ":" (Block | IfStmt | SwitchStmt | ForStmt | InlineRangeStmt ) .
ReturnStmt = "return" ExpressionList .
BreakStmt = "break" [Label] .
ContinueStmt = "continue" [Label] .
FallthroughStmt = "fallthrough" .
StmtBody = Block | ("do" Statement) .
IfStmt = "if" [ SimpleStmt ";" ] Expression StmtBody [ "else" ( IfStmt | StmtBody ) ] .
WhenStmt = "when" Expression StmtBody [ "else" ( WhenStmt | StmtBody ) ] .
SwitchStmt = [ "#" "partial" ] ExprSwitchStmt | TypeSwitchStmt .
ExprSwitchStmt = "switch" [ SimpleStmt ";" ] [ Expression] "{" { ExprCaseClause } "}" .
ExprCaseClause = ExprSwitchCase ":" StatementList .
CaseExpression = Expression [ range_op Expression ] .
CaseExpressionList = CaseExpression { "," CaseExpression } .
ExprSwitchCase = "case" [CaseExpressionList] .
TypeSwitchStmt = "switch" identifier "in" Expression "{" { TypeCaseClause } "}" .
TypeCaseClause = TypeSwitchCase ":" StatementList .
TypeSwitchCase = "case" TypeList .
TypeList = Type { "," Type } .
ForStmt = "for" [ Condition | ForClause | RangeClause ] StmtBody .
InlineRangeStmt = "inline" "for" RangeClause StmtBody .
Condition = Expression .
ForClause = [ InitStmt ] ";" [ Condition ] ";" [ PostStmt ] .
InitStmt = SimpleStmt .
PostStmt = SimpleStmt .
RangeExpression = Expression [ range_op Expression ] .
RangeClause = [ IdentifierList ] "in" RangeExpression .
DeferStmt = "defer" Statement .
UsingStmt = "using" ExpressionList .
DeclStmt = { Attribute } ValueDecl .
SimpleStmt = EmptyStmt | ExpressionStmt | Assignment | ValueDecl .
EmptyStmt = .
ExpressionStmt = Expression .
Assignment = ExpressionList assign_op ExpressionList .
TagStmtName = "bounds_check" | "no_bounds_check" .
TagStmt = "#" TagStmtName Statement .
assign_op = [ add_op | mul_op ] "=" .
Expression = UnaryExpr | BinaryExpr | TernaryExpr .
BinaryExpr = Expression binary_op Expression .
TernaryExpr = QuestionTernaryExpr | IfTernaryExpr | WhenTernaryExpr .
QuestionTernaryExpr = Condition "?" Expression ":" Expression .
IfTernaryExpr = Expression "if" Condition "else" Expression .
WhenTernaryExpr = Expression "when" Condition "else" Expression .
UnaryExpr =
AtomExpr |
unary_op UnaryExpr |
inline_op CallExpr |
CastExpr UnaryExpr .
binary_op = "||" | "&&" | rel_op | add_op | mul_op | contain_op .
range_op = ".." | "..<" .
rel_op = "==" | "!=" | "<" | "<=" | ">" | ">=" .
contain_op = "in" | "not_in" .
add_op = "+" | "-" | "|" | "~" .
mul_op = "*" | "/" | "%" | "%%" | "<<" | ">>" | "&" | "&~" .
unary_op = "+" | "-" | "!" | "&" | "~" | "auto_cast" .
inline_op = "inline" | "no_inline" .
CastExpr = ("cast" | "transmute") "(" Type ")" .
AtomExpr =
Operand |
TypeConversion |
AtomExpr Selector |
AtomExpr ArrowSelector |
AtomExpr Index |
AtomExpr Slice |
AtomExpr TypeAssertion |
AtomExpr AutoTypeAssertion |
CallExpr |
AtomExpr Dereference .
CallExpr = AtomExpr Arguments | "(" CallExpr ")" .
Dereference = "^" .
Selector = "." identifier .
ArrowSelector = "->" identifier .
Index = "[" Expression "]" .
Slice = "[" [ Expression ] ":" [ Expression ] "]" .
TypeAssertion = "." "(" Type ")" .
AutoTypeAssertion = "." "?" .
ArgumentElement = (".." identifier) | ( identifier [ "=" [".."] Expression ] ) .
ArgumentElementList = ArgumentElement { "," ArgumentElement } .
Arguments = "(" [ ArgumentElementList [ "," ] ] ")" .
TypeConversion = Type "(" Expression [ "," ] ")" .
TagExprName = "file" | "line" | "procedure" | "caller_location" .
TagExprNameWithExpr = "bounds_check" | "no_bounds_check" | "partial" .
TagExprNameWithArguments = "location" | "load" | "assert" | "defined" | "config" .
TagExpr =
"#" TagExprName |
"#" TagExprNameWithExpr Expression |
"#" TagExprNameWithArguments Arguments .
ImplicitSelectorExpression = "." identifier .
Operand =
Literal |
OperandName |
"(" Expression ")" |
TagExpr |
InlineAsmExpr |
ImplicitSelectorExpression .
Literal = BasicLit | CompoundLit | ProcedureLit .
BasicLit = int_lit | float_lit | imaginary_lit | rune_lit | string_lit .
OperandName = identifier .
CompoundLit = LiteralType LiteralValue .
LiteralType =
StructType | UnionType | EnumType |
ArrayType | "[" "?" "]" ElementType |
SliceType | DynamicArrayType |
MapType |
BitFieldType |
BitSetType |
TypeName | CallExpr .
LiteralValue = "{" [ ElementList [ "," ] ] "}" .
AsmTags = "#" "side_effects" | "#" "align_stack" | "#" "att" | "#" "intel" .
InlineAsmExpr = "asm" Signature [ AsmTags ] "{" string_lit "," string_lit [ "," ] "}" .
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment