GDScript grammar

EBNF, for reference purposes. Note not generated from a grammar definition. Inconsistencies here likely mean an error in this grammar, not a bug in GDScript.

  1. (* GDScript EBNF grammar. Uppercase words are terminals generated by the tokenizer. INDENT/DEDENT are not generated by the tokenizer yet, but they are added here for reading convenience. Naturally, this only cover syntax. Semantics can't be inferred from this description.*)program = [ inheritance NEWLINE ] [ className ] { topLevelDecl } ;inheritance = "extends" ( IDENTIFIER | STRING ) { "." IDENTIFIER } ;className = "class_name" IDENTIFIER [ "," STRING ] NEWLINE ;topLevelDecl = classVarDecl | constDecl | signalDecl | enumDecl | methodDecl | constructorDecl | innerClass | "tool" ;classVarDecl = [ "onready" ] [ export ] "var" IDENTIFIER [ ":" typeHint ] [ "=" expression ] [ setget ] NEWLINE ;setget = "setget" [ IDENTIFIER ] [ "," IDENTIFIER] ;export = "export" [ "(" [ BUILTINTYPE | IDENTIFIER { "," literal } ] ")" ] ;typeHint = BUILTINTYPE | IDENTIFIER ;constDecl = "const" IDENTIFIER [ ":" typeHint ] "=" expression NEWLINE ;signalDecl = "signal" IDENTIFIER [ signalParList ] NEWLINE ;signalParList = "(" [ IDENTIFIER { "," IDENTIFIER } ] ")" ;enumDecl = "enum" [ IDENTIFIER ] "{" [ IDENTIFIER [ "=" INTEGER ] { "," IDENTIFIER [ "=" INTEGER ] } [ "," ] ] "}" NEWLINE ;methodDecl = [ rpc ] [ "static" ] "func" IDENTIFIER "(" [ parList ] ")" [ "->" typeHint] ":" stmtOrSuite ;parList = parameter { "," parameter } ;parameter = [ "var" ] IDENTIFIER [ ":" typeHint ] [ "=" expression ] ;rpc = "remote" | "master" | "puppet" | "remotesync" | "mastersync" | "puppetsync";constructorDecl = "func" IDENTIFIER "(" [ parList ] ")" [ "." "(" [ argList ] ")" ] ":" stmtOrSuite ;argList = expression { "," expression } ;innerClass = "class" IDENTIFIER [ inheritance ] ":" NEWLINE INDENT [ inheritance NEWLINE ] topLevelDecl { topLevelDecl } DEDENT ;stmtOrSuite = stmt | NEWLINE INDENT suite DEDENT ;suite = stmt { stmt };stmt = varDeclStmt | ifStmt | forStmt | whileStmt | matchStmt | flowStmt | assignmentStmt | exprStmt | assertStmt | yieldStmt | preloadStmt | "breakpoint" stmtEnd | "pass" stmtEnd ;stmtEnd = NEWLINE | ";" ;ifStmt = "if" expression ":" stmtOrSuite { "elif" expression ":" stmtOrSuite } [ "else" ":" stmtOrSuite ] ;whileStmt = "while" expression ":" stmtOrSuite;forStmt = "for" IDENTIFIER "in" expression ":" stmtOrSuite ;matchStmt = "match" expression ":" NEWLINE INDENT matchBlock DEDENT;matchBlock = patternList ":" stmtOrSuite { patternList ":" stmtOrSuite };patternList = pattern { "," pattern } ;(* Note: you can't have a binding in a pattern list, but to not complicate thegrammar more it won't be restricted syntactically *)pattern = literal | BUILTINTYPE | CONSTANT | "_" | bindingPattern | arrayPattern | dictPattern ;bindingPattern = "var" IDENTIFIER ;arrayPattern = "[" [ pattern { "," pattern } [ ".." ] ] "]" ;dictPattern = "{" [ keyValuePattern ] { "," keyValuePattern } [ ".." ] "}" ;keyValuePattern = STRING [ ":" pattern ] ;flowStmt = "continue" stmtEnd | "break" stmtEnd | "return" [ expression ] stmtEnd ;assignmentStmt = subscription "=" expression stmtEnd;varDeclStmt = "var" IDENTIFIER [ "=" expression ] stmtEnd;assertStmt = "assert" "(" expression [ "," STRING ] ")" stmtEnd ;yieldStmt = "yield" "(" [ expression "," expression ] ")" ;preloadStmt = "preload" "(" CONSTANT ")" ;(* This expression grammar encodes precedence. Items later in the list havehigher precedence than the ones before. *)exprStmt = expression stmtEnd ;expression = cast [ "[" expression "]" ] ;cast = ternaryExpr [ "as" typeHint ];ternaryExpr = logicOr [ "if" logicOr "else" logicOr ] ;logicOr = logicAnd { ( "or" | "||" ) logicAnd } ;logicAnd = logicNot { ( "and" | "&&" ) logicNot };logicNot = ( "!" | "not" ) logicNot | in;in = comparison { "in" comparison };comparison = bitOr { ( "<" | ">" | "<=" | ">=" | "==" | "!=" ) bitOr } ;bitOr = bitXor { "|" bitXor } ;bitXor = bitAnd { "^" bitAnd } ;bitAnd = bitShift { "&" bitShift } ;bitShift = minus { ( "<<" | ">>" ) minus } ;minus = plus { "-" plus } ;plus = factor { "+" factor } ;factor = sign { ( "*" | "/" | "%" ) sign } ;sign = ( "-" | "+" ) sign | bitNot ;bitNot = "~" bitNot | is ;is = call [ "is" ( IDENTIFIER | BUILTINTYPE ) ] ;call = attribute [ "(" [ argList ] ")" ];attribute = subscription { "." IDENTIFIER } ;subscription = primary [ "[" expression "]" ] ;primary = "true" | "false" | "null" | "self" | literal | arrayDecl | dictDecl | "(" expression ")" ;literal = STRING | NUMBER | IDENTIFIER | BUILTINTYPE | "PI" | "TAU" | "NAN" | "INF" ;arrayDecl = "[" [ expression { "," expression } "," ] "]" ;dictDecl = "{" [ keyValue { "," keyValue } "," ] "}" ;keyValue = expression ":" expression | IDENTIFIER "=" expression ;