:article_outdated: True .. _doc_gdscript_grammar: GDScript grammar ================ This is the formal grammar of GDScript written in `EBNF `_, for reference purposes. .. note:: This grammar is descriptive only, derived from the reference documentation and current implementation. The GDScript parser is **not** generated from a grammar definition. Inconsistencies here likely mean an error in this grammar, not a bug in GDScript. .. code-block:: ebnf (* 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 the grammar 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 have higher 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 ] ")" ]) | "." IDENTIFIER "(" [ argList ] ")" | "$" ( STRING | IDENTIFIER { '/' IDENTIFIER } ); 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 ;