-
Notifications
You must be signed in to change notification settings - Fork 10
Grammar
Positron edited this page Aug 4, 2017
·
13 revisions
The grammar of the BCS language is shown below. For the common user, this information might not be very useful. This information is targeted more towards compiler and tool writers, or for the curious user.
The (empty)
terminal indicates that the rule is optional. //
denotes the start of a one-line comment.
module: module-body module-body: module-item-list (empty) module-item-list: module-item module-item-list module-item module-item: pseudo-directive namespace-member // The names of pseudo directives are context-sensitive keywords. pseudo-directive: # include string # import string # library string # linklibrary string # define identifier expression // The zcommon.acs file #defines `true` and `false`. In BCS, `true` and // `false` are keywords, so a syntax error will be generated when #including // the zcommon.acs file. To support the inclusion of the zcommon.acs file, // ignore the #defines of `true` and `false`. # define true 1 # define false 0 # libdefine identifier expression # encryptstrings # nocompact # wadauthor # nowadauthor # region # endregion namespace: namespace-header { namespace-member-list } namespace-header { } namespace-header: namespace-visibility strict namespace namespace-visibility strict namespace namespace-name namespace-visibility namespace namespace-name private namespace namespace-visibility: private (empty) namespace-name: identifier namespace-name . identifier namespace-member-list: namespace-member namespace-member-list namespace-member namespace-member: namespace using declaration script special ; using: using path ; // Makes every object in the namespace available. using path : import-list ; path: upmost // Upmost namespace. namespace // Current namespace. identifier path . identifier import-list: import-item import-list , import-item import-item: enum import-name enum import-name = import-name struct import-name struct import-name = import-name type-name type-name = type-name identifier identifier = identifier import-name: identifier type-name declaration: specifier-declaration object-declaration specifier-declaration: specifier-visibility enumeration ; specifier-visibility structure ; specifier-visibility type-alias ; specifier-visibility: private (empty) enumeration: enum enumeration-name enumeration-base enumeration-body enumeration-name: identifier type-name (empty) enumeration-base: : enumeration-base-type (empty) enumeration-base-type: int fixed bool str enumeration-body: { enumerator-list } { enumerator-list , } enumerator-list: enumerator enumerator-list , enumerator enumerator: identifier identifier = expression structure: struct structure-name { structure-member-list } structure-name: identifier (empty) structure-member-list: structure-member structure-member-list structure-member structure-member: extended-specifier reference structure-member-instance-list ; structure-member-instance-list: structure-member-instance structure-member-instance-list , structure-member-instance structure-member-instance: identifier identifier dimension-list object-declaration: visibility variable visibility function visibility: private extern static (empty) variable: storage extended-specifier reference instance-list ; auto auto-instance-list ; storage: world global (empty) storage-index: decimal-number : (empty) auto: auto auto enum extended-specifier: enumeration structure specifier specifier: raw int fixed bool str void enum path struct path type-name reference: reference-structure reference-structure reference-list reference-list (empty) reference-structure: reference-storage reference-marker reference-storage: reference-storage-name reference-storage-name : decimal-number (empty) reference-storage-name: world global reference-marker: & ? reference-list: reference-item reference-item reference-list reference-item: reference-storage dimension-list reference-marker ( parameter-list-declaration ) reference-marker instance-list: instance instance-list , instance instance: instance-name instance-name = initializer instance-name dimension-list instance-name dimension-list = initializer instance-name: storage-index identifier auto-instance-list: auto-instance auto-instance-list auto-instance auto-instance: identifier = initializer dimension-list: [ expression ] [ ] dimension-list [ expression ] dimension-list [ ] initializer: expression braced-initializer braced-initializer: { initializer-list } { initializer-list , } initializer-list: initializer initializer-list , initializer function: function-keyword function-return identifier ( parameter-list-declaration ) function-body function-keyword: function (empty) function-return: extended-specifier reference auto parameter-list-declaration: parameter-list void (empty) parameter-list: parameter parameter-list , parameter parameter: specifier parameter-name parameter-initializer parameter-name: identifier (empty) function-body: block-statement ; type-alias: typedef extended-specifier reference type-alias-instance-list typedef function-keyword function-return type-name ( parameter-list-declaration ) type-alias-instance-list: type-alias-instance type-alias-instance-list , type-alias-instance type-alias-instance: type-name dimension-list type-name script: script script-tag script-parameter-parentheses script-type script-flag statement script-tag: << 0 >> // When reading the script number, function calls are not parsed because // they conflict with the start of the parameter list. expression script-parameter-parentheses: ( script-parameter-list ) ( void ) ( ) (empty) script-parameter-list: script-parameter script-parameter-list , script-parameter script-parameter: script-parameter-type identifier script-parameter-type script-parameter-type: raw int // The script types are context-sensitive keywords. script-type: bluereturn death disconnect enter event kill lightning open pickup redreturn reopen respawn return unloading whitereturn (empty) // The script flags are context-sensitive keywords. script-flag: script-flag net script-flag clientside (empty) special: special special-list ; special-list: special-item special-list , special-item special-item: special-sign decimal-number : identifier ( special-parameter-list ) special-return special-sign: - // If '-' is specified, the item is an extension function. Otherwise, the // item is an action-special. (empty) special-parameter-list: special-parameter-list-minmax special-parameter-list-type (empty) special-parameter-list-minmax: decimal-number // Maximum parameters. decimal-number , decimal-number // Minimum parameters, ',', // maximum parameters. special-parameter-list-type: // Required parameters, ';', optional parameters. special-parameter-list ; special-parameter-list ; special-parameter-list special-parameter-list: special-parameter-type special-parameter-list , special-parameter-type special-parameter-type: raw int fixed bool str special-return: : special-return-type (empty) special-return-type: raw int fixed bool str void statement: local-declaration local-using block-statement if-statement switch-statement case-label while-statement do-statement for-statement foreach-statement jump-statement script-jump-statement return-statement goto-statement label palette-translation assert buildmsg inline-assembly empty-statement expression-statement statement-list: statement statement-list statement local-declaration: let declaration local-using: let using let: let (empty) block-statement: { statement-list } { } if-statement: if ( expression ) statement if ( expression ) statement else statement condition: condition-variable expression condition-variable: let specifier identifier = initializer let auto identifier = initializer heavy-condition: condition-variable condition-variable ; expression expression switch-statement: switch ( heavy-condition ) statement case-label: case expression : default : while-statement: while ( condition ) statement until ( condition ) statement do-statement: do statement while ( expression ) ; do statement until ( expression ) ; for-statement: for ( for-initialization for-condition for-post ) statement for-initialization: let variable expression-list ; ; for-condition: condition ; ; for-post: expression-list (empty) foreach-statement: foreach ( foreach-item expression ) statement foreach-item: foreach-variable ; foreach-variable ; foreach-variable ; foreach-variable , identifier ; foreach-variable: let specifier identifier let auto identifier jump-statement: break ; continue ; script-jump-statement: terminate ; suspend ; restart ; return-statement: return ; return expression ; return buildmsg goto-statement: goto identifier ; label: identifier : palette-translation: createtranslation ( expression ) createtranslation ( expression , palette-range-list ) palette-range-list: palette-range palette-range-list , palette-range palette-range: // NOTE: Assignment is not parsed in the second expression because it will // conflict with the following assignment token. expression : expression = palette-range-value palette-range-value: expression : expression palette-range-rgb % palette-range-rgb # [ expression , expression , expression ] @ expression [ expression , expression , expression ] palette-range-rgb: [ expression , expression , expression ] : [ expression , expression , expression ] assert: assert ( expression ) ; assert ( expression , string ) ; static assert ( expression ) ; static assert ( expression , string ) ; buildmsg: buildmsg ( expression ) block-statement // The newline character becomes significant for inline-assembly. // It is the terminating token of a line of inline-assembly code. inline-assembly: > inline-assembly-opcode newline > inline-assembly-opcode inline-assembly-argument-list newline inline-assembly-opcode: identifier terminate restart suspend goto inline-assembly-argument-list: expression inline-assembly-argument-list , expression inline-assembly-argument: number identifier string ( expression ) empty-statement: ; expression-statement: expression-list ; expression-list: expression expression-list , expression expression: assignment assignment: conditional conditional = assignment conditional += assignment conditional -= assignment conditional *= assignment conditional /= assignment conditional %= assignment conditional <<= assignment conditional >>= assignment conditional &= assignment conditional ^= assignment conditional |= assignment conditional: logical-or logical-or ? expression : conditional logical-or ? : conditional logical-or: logical-and logical-or || logical-and logical-and: bitwise-or logical-and && bitwise-or bitwise-or: bitwise-xor bitwise-or | bitwise-xor bitwise-xor: bitwise-and bitwise-xor ^ bitwise-and bitwise-and: equality bitwise-and & equality equal: less-than equal == less-than equal != less-than less-than: bitwise-shift less-than < bitwise-shift less-than <= bitwise-shift less-than > bitwise-shift less-than >= bitwise-shift bitwise-shift: addition bitwise-shift << addition bitwise-shift >> addition addition: multiplication addition + multiplication addition - multiplication multiplication: prefix multiplication * prefix multiplication / prefix multiplication % prefix prefix: suffix ++ prefix -- prefix - prefix + prefix ! prefix ~ prefix suffix: primary suffix ++ suffix -- suffix [ expression ] suffix call suffix . identifier suffix ! ! call: ( ) ( expression-list ) ( format-item-list ) ( format-item-list ; expression-list ) format-item-list: format-item format-item-list , format-item format-item: format-cast : expression format-item-array format-cast: // Valid value: [abcdfiklnsx] identifier format-item-array: a : expression a : ( expression ) a : ( expression , expression ) a : ( expression , expression , expression ) primary: strcpy memcpy conversion parentheses identifier number string character upmost namespace true false null strcpy: strcpy strcpy-call strcpy-call: ( strcpy-source-argument , expression ) ( strcpy-source-argument , expression , expression ) strcpy-source-argument: format-item-array expression memcpy: memcpy strcpy-call conversion: int ( expression ) fixed ( expression ) bool ( expression ) str ( expression ) parentheses: cast compound-literal function-literal ( expression ) cast: ( raw ) prefix ( int ) prefix ( fixed ) prefix ( bool ) prefix ( str ) prefix compound-literal: ( compound-literal-static specifier ) braced-initializer ( compound-literal-static specifier dimension-list ) braced-initializer ( compound-literal-static specifier dimension-list ) string compound-literal-static: static (empty) function-literal: ( function-literal-header ) block-statement function-literal-header: function-literal-static function-keyword function-literal-return ( parameter-list-declaration ) function-literal-static: static (empty) function-literal-return: specifier auto identifier: [a-zA-Z_][a-zA-Z0-9_]* type-name: (([a-zA-Z_][a-zA-Z0-9_]*)?[a-z_])?T number: binary-number octal-number decimal-number hexadecimal-number fixed-point-number radix-number binary-number: 0[bB][0-1]+([']?[0-1]+)* octal-number: 0[oO][0-7]+([']?[0-7]+)* decimal-number: [0-9]+([']?[0-9]+)* hexadecimal-number: 0[xX]([']?[0-9a-fA-F])* fractional-number: [0-9]+([']?[0-9]+)*[.]([0-9]+([']?[0-9]+)*)? radix-number: [0-9]+([']?[0-9]+)*[_rR]([']?[0-9a-zA-Z]+)* string: "([^\\"]|\\.)*" character: '.' ' character-escape-sequence ' character-escape-sequence: \\a \\b \\n \\t \\v \\f \\r \\' \\\\ \\[oO][0-7]+ \\[xX][0-9a-fA-F]+ newline: // Newline character comment: [/][/][^\n]+ // Single-line comment. [/][*]([^*]*[*]+)+[/] // Multi-line comment. (empty): // The rule is optional.
Certain identifiers are reserved by the language and are used in specific ways. They cannot be used as names for your own objects. These identifiers are:
assert
auto
bool
break
buildmsg
case
const
continue
createtranslation
default
do
else
enum
extern
false
fixed
for
foreach
function
global
goto
if
int
let
memcpy
namespace
null
private
raw
restart
return
script
special
static
str
strcpy
strict
struct
suspend
switch
terminate
true
typedef
until
upmost
using
void
while
world
The following identifiers are keywords only in specific places:
bluereturn
clientside
death
define
disconnect
encryptstrings
endregion
enter
event
import
include
kill
libdefine
library
lightning
linklibrary
net
nocompact
nowadauthor
open
pickup
redreturn
region
reopen
respawn
unloading
wadauthor
whitereturn
Some identifiers that are known to have a special meaning in ACS and BCS can also be used as normal identifiers. You can use these identifiers as names for your objects. These identifiers are:
acs_executewait
acs_namedexecutewait
bluereturn
clientside
death
define
disconnect
encryptstrings
endregion
enter
event
hudmessage
hudmessagebold
import
include
kill
libdefine
library
lightning
linklibrary
log
net
nocompact
nowadauthor
open
pickup
print
printbold
redreturn
region
reopen
respawn
strparam
unloading
wadauthor
whitereturn