gdscript_grammar.rst 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. .. _doc_gdscript_grammar:
  2. GDScript grammar
  3. ================
  4. This is the formal grammar of GDScript written in `EBNF <https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form>`_,
  5. for reference purposes.
  6. .. note:: This grammar is descriptive only, derived from the reference
  7. documentation and current implementation. The GDScript parser is
  8. **not** generated from a grammar definition. Inconsistencies here
  9. likely mean an error in this grammar, not a bug in GDScript.
  10. .. code-block:: ebnf
  11. (* GDScript EBNF grammar.
  12. Uppercase words are terminals generated by the tokenizer.
  13. INDENT/DEDENT are not generated by the tokenizer yet, but they are added
  14. here for reading convenience.
  15. Naturally, this only cover syntax. Semantics can't be inferred from this
  16. description.
  17. *)
  18. program = [ inheritance NEWLINE ] [ className ] { topLevelDecl } ;
  19. inheritance = "extends" ( IDENTIFIER | STRING ) { "." IDENTIFIER } ;
  20. className = "class_name" IDENTIFIER [ "," STRING ] NEWLINE ;
  21. topLevelDecl
  22. = classVarDecl
  23. | constDecl
  24. | signalDecl
  25. | enumDecl
  26. | methodDecl
  27. | constructorDecl
  28. | innerClass
  29. | "tool"
  30. ;
  31. classVarDecl = [ "onready" ] [ export ] "var" IDENTIFIER [ ":" typeHint ]
  32. [ "=" expression ] [ setget ] NEWLINE ;
  33. setget = "setget" [ IDENTIFIER ] [ "," IDENTIFIER] ;
  34. export = "export" [ "(" [ BUILTINTYPE | IDENTIFIER { "," literal } ] ")" ] ;
  35. typeHint = BUILTINTYPE | IDENTIFIER ;
  36. constDecl = "const" IDENTIFIER [ ":" typeHint ] "=" expression NEWLINE ;
  37. signalDecl = "signal" IDENTIFIER [ signalParList ] NEWLINE ;
  38. signalParList = "(" [ IDENTIFIER { "," IDENTIFIER } ] ")" ;
  39. enumDecl = "enum" [ IDENTIFIER ] "{" [ IDENTIFIER [ "=" INTEGER ]
  40. { "," IDENTIFIER [ "=" INTEGER ] } [ "," ] ] "}" NEWLINE ;
  41. methodDecl = [ rpc ] [ "static" ] "func" IDENTIFIER "(" [ parList ] ")"
  42. [ "->" typeHint] ":" stmtOrSuite ;
  43. parList = parameter { "," parameter } ;
  44. parameter = [ "var" ] IDENTIFIER [ ":" typeHint ] [ "=" expression ] ;
  45. rpc = "remote" | "master" | "puppet"
  46. | "remotesync" | "mastersync" | "puppetsync";
  47. constructorDecl = "func" IDENTIFIER "(" [ parList ] ")"
  48. [ "." "(" [ argList ] ")" ] ":" stmtOrSuite ;
  49. argList = expression { "," expression } ;
  50. innerClass = "class" IDENTIFIER [ inheritance ] ":" NEWLINE
  51. INDENT [ inheritance NEWLINE ] topLevelDecl { topLevelDecl } DEDENT ;
  52. stmtOrSuite = stmt | NEWLINE INDENT suite DEDENT ;
  53. suite = stmt { stmt };
  54. stmt
  55. = varDeclStmt
  56. | ifStmt
  57. | forStmt
  58. | whileStmt
  59. | matchStmt
  60. | flowStmt
  61. | assignmentStmt
  62. | exprStmt
  63. | assertStmt
  64. | yieldStmt
  65. | preloadStmt
  66. | "breakpoint" stmtEnd
  67. | "pass" stmtEnd
  68. ;
  69. stmtEnd = NEWLINE | ";" ;
  70. ifStmt = "if" expression ":" stmtOrSuite { "elif" expression ":" stmtOrSuite }
  71. [ "else" ":" stmtOrSuite ] ;
  72. whileStmt = "while" expression ":" stmtOrSuite;
  73. forStmt = "for" IDENTIFIER "in" expression ":" stmtOrSuite ;
  74. matchStmt = "match" expression ":" NEWLINE INDENT matchBlock DEDENT;
  75. matchBlock = patternList ":" stmtOrSuite { patternList ":" stmtOrSuite };
  76. patternList = pattern { "," pattern } ;
  77. (* Note: you can't have a binding in a pattern list, but to not complicate the
  78. grammar more it won't be restricted syntactically *)
  79. pattern = literal | BUILTINTYPE | CONSTANT | "_" | bindingPattern
  80. | arrayPattern | dictPattern ;
  81. bindingPattern = "var" IDENTIFIER ;
  82. arrayPattern = "[" [ pattern { "," pattern } [ ".." ] ] "]" ;
  83. dictPattern = "{" [ keyValuePattern ] { "," keyValuePattern } [ ".." ] "}" ;
  84. keyValuePattern = STRING [ ":" pattern ] ;
  85. flowStmt
  86. = "continue" stmtEnd
  87. | "break" stmtEnd
  88. | "return" [ expression ] stmtEnd
  89. ;
  90. assignmentStmt = subscription "=" expression stmtEnd;
  91. varDeclStmt = "var" IDENTIFIER [ "=" expression ] stmtEnd;
  92. assertStmt = "assert" "(" expression [ "," STRING ] ")" stmtEnd ;
  93. yieldStmt = "yield" "(" [ expression "," expression ] ")" ;
  94. preloadStmt = "preload" "(" CONSTANT ")" ;
  95. (* This expression grammar encodes precedence. Items later in the list have
  96. higher precedence than the ones before. *)
  97. exprStmt = expression stmtEnd ;
  98. expression = cast [ "[" expression "]" ] ;
  99. cast = ternaryExpr [ "as" typeHint ];
  100. ternaryExpr = logicOr [ "if" logicOr "else" logicOr ] ;
  101. logicOr = logicAnd { ( "or" | "||" ) logicAnd } ;
  102. logicAnd = logicNot { ( "and" | "&&" ) logicNot };
  103. logicNot = ( "!" | "not" ) logicNot | in;
  104. in = comparison { "in" comparison };
  105. comparison = bitOr { ( "<" | ">" | "<=" | ">=" | "==" | "!=" ) bitOr } ;
  106. bitOr = bitXor { "|" bitXor } ;
  107. bitXor = bitAnd { "^" bitAnd } ;
  108. bitAnd = bitShift { "&" bitShift } ;
  109. bitShift = minus { ( "<<" | ">>" ) minus } ;
  110. minus = plus { "-" plus } ;
  111. plus = factor { "+" factor } ;
  112. factor = sign { ( "*" | "/" | "%" ) sign } ;
  113. sign = ( "-" | "+" ) sign | bitNot ;
  114. bitNot = "~" bitNot | is ;
  115. is = call [ "is" ( IDENTIFIER | BUILTINTYPE ) ] ;
  116. call = attribute [ "(" [ argList ] ")" ];
  117. attribute = subscription { "." IDENTIFIER } ;
  118. subscription = primary [ "[" expression "]" ] ;
  119. primary = "true" | "false" | "null" | "self" | literal | arrayDecl
  120. | dictDecl | "(" expression ")" ;
  121. literal = STRING | NUMBER | IDENTIFIER | BUILTINTYPE
  122. | "PI" | "TAU" | "NAN" | "INF" ;
  123. arrayDecl = "[" [ expression { "," expression } "," ] "]" ;
  124. dictDecl = "{" [ keyValue { "," keyValue } "," ] "}" ;
  125. keyValue
  126. = expression ":" expression
  127. | IDENTIFIER "=" expression
  128. ;