GUI Scripting: BNF

From The DarkMod Wiki
Revision as of 17:55, 4 November 2022 by Geep (talk | contribs) (Add category tag)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

This page is part of a series. See GUI Scripting Language for overview.

Introduction

Here is a draft definition of the TDM/idTech4 GUI Scripting Language, in informal Backus-Naur Form (BNF). As there was no existing such definition found, this was created from scratch for the TDM wiki, so undoubtably will need improvment. It reflects the overall flow of the language, not the details of the parser code and its class structure. The BNF here (with minor extensions) is probably more readable if less precise than other metalanguages like ABNF. If you need to generate a parser or a syntax-coloring editor, this is a starting point for you to evolve further.

Notation

In standard BNF:

  • <...> indicates a non-terminal node. By convention, a <human-readable-name> is lower case with dashes.
  • ::= indicates node assignment/expansion
  • | indicates alternatives, e.g., OR
  • a terminal node is just given as text (unquoted, unlike ABNF). This includes punctuation like double-quotes, commas, curly brackets.
  • terminals are assumed to be case-insensitive.
  • optional white space (space, tab, CRLF) between nodes is assumed to be allowed. Exceptions are merely noted informally.
  • the assumption is made that C-style preprocessing directive and comments with // and /*...*/ have already been resolved by the lexer, so can be ignored in the BNF.

Extensions here are:

  • <...>* indicates 0 or more repetitions, <...>+ indicates 1 or more repetitions.
  • <ALL-UPPER-CASE> means it's not going to be defined; infer its meaning from the name and assume it's like most C-style languages.
  • The formatting on the wiki page is broken into multiple lines. Assume a node definition is terminated by a "blank" line.

Comments about Structure

  • White space must not be inserted (i.e., use string concatentation) in these cases:
    • <gui-parameter> ::= "gui::" <IDENTIFIER>
    • <file-scope-variable> ::= <guidef-name> "::" <IDENTIFIER>
  • Potential differentiation of bool, int, and enum datatypes were all collapsed into float non-terminals.
  • Valid ranges of floats, including as vector components, are not being defined.
  • Structuring within string values is not being defined.
  • Restrictions on "set" command to exclude non-settable properties are subsummed within REGISTER non-terminals.
  • Math operators and their precedents is likely the same as C (but not tested). Grouping parentheses are available. All this is swept into <FLOAT-EXPRESSION>.
  • <gui-script> is the root.

Definition

<gui-script> ::= <windowdef-declarator>

<windowdef-declarator> ::= windowDef <guidef-name> { <windowdef-body> }

<guidef-name> ::= <IDENTIFIER>

<windowdef-body> ::=
  <common-property-init>+ | <user-var-declarator>* | <child-guidef-declarator>* | <event-handler-declarator>*

<common-property-init> ::=
  <common-property-float-init> | <common-property-vect4-init> | <common-property-vect2-init> | <common-property-string-init>

<common-property-float-init> ::=
  <common-property-name-float> <float-value>

<common-property-name-float> ::=
  bordersize | forceaspectheight | forceaspectwidth | invertrect | matscalex | matscaley | menugui | modal
  | naturalmatscale | noclip | nocursor | noevents | notime | nowrap | rotate | shadow | showtime | showcoords
  | textalign | textalignx | textaligny | textscale | visible | wantenter

<float-value> ::=
  <FLOAT-LITERAL> | <FLOAT-EXPRESSION> | <identifier-type>

<identifier-type> ::=
  <gui-parameter> | <file-scope-variable> | <IDENTIFIER>

<file-scope-variable> ::=
  <guidef-name> "::" <IDENTIFIER>

<gui-parameter> ::=
  "gui::" <IDENTIFIER>

<common-property-vect4-init> ::=
  <common-property-name-vect4> <vect4-property-value>

<vect4-property-value ::=
  <float-value> , <float-value> , <float-value> , <float-value>

<common-property-name-vect4> ::=
  backcolor | bordercolor | forecolor | matcolor | rect

<common-property-vect2-init> ::=
  <common-property-name-vect2> <vect2-property-value>

<vect2-property-value> ::=
  <float-value> , <float-value>

<common-property-name-vect2> ::= shear

<common-property-string-init> ::=
  <common-property-name-string> <string-value>

<common-property-name-string> ::=
  background | comment | font | name | play | text

<string-value> ::=
  <DOUBLE-QUOTED-STRING-LITERAL> | <identifier-type>

<child-guidef-declarator> ::=
  <binddef-declarator> | <choicedef-declarator> | <editdef-declarator> | <listdef-declarator>
  | <renderdef-declarator> | <sliderdef-declarator> | <windowdef-declarator>


<binddef-declarator> ::=
  bindDef <guidef-name> { <binddef-body> }

<choicedef-declarator> ::=
  choiceDef <guidef-name> { <choicedef-body> }

<editdef-declarator> ::=
  editDef <guidef-name> { <editdef-body> }

<listdef-declarator> ::=
  listDef <guidef-name> { <listdef-body> }

<renderdef-declarator> ::=
  renderDef <guidef-name> { <renderdef-body> }

<sliderdef-declarator> ::=
  sliderDef <guidef-name> { <sliderdef-body> }

 
<binddef-body> ::=
  <windowdef-body> | <binddef-property-init>*

<binddef-property-init> ::=
  bind <string-value>


<choicedef-body> ::=
  <windowdef-body> | <choicedef-property-init>*

<choicedef-property-init> ::=
  <choicedef-property-float-init> | <choicedef-property-string-init>

<choicedef-property-float-init> ::=
  <choicedef-property-name-float> <float-value>

<choicedef-property-name-float> ::=
  choicetype | liveupdate

<choicedef-property-string-init> ::=
  <choicedef-property-name-string> <string-value>

<choicedef-property-name-string> ::=
  cvar | choicevar | gui | updategroup


<editdef-body> ::=
  <windowdef-body> | <editdef-property-init>*

<editdef-property-init> ::=
  <editdef-property-float-init> | <editdef-property-string-init>

<editdef-property-float-init> ::=
  <editdef-property-name-float> <float-value>

<editdef-property-name-float> ::=
  forcescroll | liveupdate | numeric | password | readonly | wrap

<editdef-property-string-init> ::=
  <editdef-property-name-string> <string-value>

<editdef-property-name-string> ::=
  cvargroup | source

<listdef-body> ::=
   <windowdef-body> | <listdef-property-init>*

<listdef-property-init> ::=
  <listdef-property-float-init> | <listdef-property-string-init> | <listdef-property-comma-separated-values-init>

<listdef-property-float-init> ::=
  <listdef-property-name-float> <float-value>

<listdef-property-name-float> ::=
  horizontal | multiplesel

<listdef-property-string-init> ::=
  <listdef-property-name-string> <string-value>

<listdef-property-name-string> ::= name

<listdef-property-comma-separated-values-init> ::=
  <listdef-property-name-comma-separated-values> " <comma-list>* <float-value> "

<comma-list> ::= <float-value> ,

<listdef-property-name-comma-separated-values> ::=
  tabaligns | tabiconsizes | tabiconvoffset | tabstops | tabtypes


<renderdef-body> ::=
  <windowdef-body> | <renderdef-property-init>*

<renderdef-property-init> ::=
  <renderdef-property-float-init> | <renderdef-property-string-init>

<renderdef-property-float-init> ::=
  <renderdef-property-name-float> <float-value>

<renderdef-property-name-float> ::=
  needsrender | noshadows

<renderdef-property-vect4-init> ::=
  <renderdef-property-name-vect4> <vect4-property-values>

<renderdef-property-name-vect4> ::=
  lightcolor | lightorigin | modelorigin | modelrotate | viewoffset

<renderdef-property-string-init> ::=
  <renderdef-property-name-string> <string-value>

<renderdef-property-name-string> ::= 
  anim | animclass | model


<sliderdef-body> ::=
  <windowdef-body> | <sliderdef-property-init>*

<sliderdef-property-init> ::=
  <sliderdef-property-float-init> | <sliderdef-property-string-init>

<sliderdef-property-float-init> ::=
  <sliderdef-property-name-float> <float-value>

<sliderdef-property-name-float> ::=
  liveupdate | low | high | scrollbar | step | stepsize | vertical | verticalflip

<sliderdef-property-string-init> ::=
  <sliderdef-property-name-string> <string-value>

<sliderdef-property-name-string> ::=
  cvar | cvargroup | thumbshader

<user-var-declarator> ::=
  float <IDENTIFIER> 0 | float <IDENTIFIER> ; | definefloat <IDENTIFIER> 0 | definefloat <IDENTIFIER> ;
  | definevec4 <IDENTIFIER> ;

<event-handler-declarator> ::=
  <event-handler-type> <IDENTIFIER> { <event-body> }

<event-handler-type> ::=
  onTime <FLOAT-LITERAL> | onNamedEvent <DOUBLE-QUOTED-STRING-LITERAL>
  | onAction | onActionRelease | onActivate | onDeactivate | onEnter | onEnterRelease
  | onEsc | onEvent | onMouseEnter | onMouseExit | onTrigger

<event-body> ::= <event-command>*

<event-command> ::= <command> ;

<command> ::=
  <if-command> | <reset-cinematics-command> | <reset-time-command> | <set-command>
  | <set-focus-command> | <show-cursor-command>| <transition-command>

<if-phrase> ::=
  if ( <IF-CONDITION> ) { <event-command>* }

<else-if-branch> ::=
  else <if-phrase>

<if-command> ::=
  <if-phrase>
  | <if-phrase> <else-if-branch>* else { <event-command>* }

<reset-cinematics-command> ::== resetcinematics

<reset-time-command ::=
  resetTime <FLOAT-LITERAL> | resetTime " <FLOAT-LITERAL> "
  | resetTime " <guidef-name> " <FLOAT-LITERAL> | resetTime " <guidef-name> "  " <FLOAT-LITERAL> "

<assign-to-float-variable> ::=
  <PROPERTY-REGISTER-NAME-FLOAT> | <USER-VARIABLE-NAME-FLOAT>
  | <FILE-SCOPE-REGISTER-NAME-FLOAT> | <FILE-SCOPE-USER-VARIABLE-NAME-FLOAT>
  | <GUI-PARAMETER-NAME-FLOAT>

<assign-from-float-variable> ::=
  <PROPERTY-NAME-FLOAT> | <USER-VARIABLE-NAME-FLOAT>
  | <FILE-SCOPE-PROPERTY-NAME-FLOAT> | <FILE-SCOPE-USER-VARIABLE-NAME-FLOAT>
  | <GUI-PARAMETER-NAME-FLOAT>

<assign-to-vect4-variable> ::=
  <PROPERTY-REGISTER-NAME-VECT4> | <USER-VARIABLE-NAME-VECT4>
  | <FILE-SCOPE-REGISTER-NAME-VECT4> | <FILE-SCOPE-USER-VARIABLE-NAME-VECT4>

<assign-from-vect4-variable> ::=
  <PROPERTY-NAME-VECT4> | <USER-VARIABLE-NAME-VECT4>
  | <FILE-SCOPE-PROPERTY-NAME-VECT4> | <FILE-SCOPE-USER-VARIABLE-NAME-VECT4>

<assign-to-string-variable> ::=
  <PROPERTY-REGISTER-NAME-STRING> | <FILE-SCOPE-REGISTER-NAME-STRING> | <GUI-PARAMETER-NAME-STRING>

<assign-from-string-variable> ::=
  <PROPERTY-NAME-STRING> | <FILE-SCOPE-PROPERTY-NAME-STRING> | <GUI-PARAMETER-NAME-STRING>

<set-command> ::=
  set " <assign-to-float-variable> " " <FLOAT-LITERAL> "
  | set " <assign-to-float-variable> " "$ <assign-from-float-variable> " 
  | set " <assign-to-vect4-variable> " " <FLOAT-LITERAL> <FLOAT-LITERAL> <FLOAT-LITERAL> <FLOAT-LITERAL> "
  | set " <assign-to-vect4-variable> " "$ <assign-from-vect4-variable> "
  | set " <assign-to-string-variable> " <DOUBLE-QUOTED-STRING-LITERAL>
  | set " <assign-to-string-variable> " "$ <assign-from-string-variable> "
  | set "cmd" " <STRING-LITERAL> "

<set-focus-command> ::=
  setfocus " <guidef-name> "

<show-cursor-command> ::=
  showcursor " <FLOAT-LITERAL "

<float-literal-quotes-optional> ::=
  <FLOAT-LITERAL> | " <FLOAT-LITERAL> "

<transition-command> ::=
  <transition-command-required> | <transition-command-required> <float-literal-quotes-optional> <float-literal-quotes-optional>

<transition-command-required> :==
  transition " <assign-to-float-variable> " " <FLOAT-LITERAL> " " <FLOAT-LITERAL> " <float-literal-quotes-optional>
  | transition " <assign-to-vect4-variable> " " <FLOAT-LITERAL> <FLOAT-LITERAL> <FLOAT-LITERAL> <FLOAT-LITERAL> " <float-literal-quotes- optional>