ONE-xicons
© Copyright 2022 Werk II Medien- und Informationsgesellschaft mbH. Alle Rechte vorbehalten.

cScript Grammar

Here you can find a complete description of the cScript grammar in EBNF.

EBNF

Individual elements of an EBNF (Extended Backus-Naur Form) diagram should be interpreted as follows:

Additionally, each definition is given in text form. Jede Beschreibung ist zusätzlich in Textschreibweise angegeben using the following notation:

prog

cScript programs begin with optional definitions of function variables, followed by any number of include statements. After the includes, any number of global declarations may follow.

The entry point of execution is always the function int main (). The main function needs to be a part of all cScript programs..

pragma include dcl ; func prog ::= pragma* include* ( dcl ';' | func )* no references

This is the shortest possible cScript program:

int main ()
{
	return 0;
}

pragma

Definitions of function variables. These are only supported from priint:comet Plugíns version 4.1 and up. In earlier versions, they may therefore lead to errors during script execution.

#pragma var functionVariable pragma ::= '#pragma var' functionVariable referenced by: prog

functionVariable

## UnsignedInt " Ident // UnquotedString " possibleValue functionVariable ::= '##' UnsignedInt | '"' Ident ( '//' UnquotedString )? '"' possibleValue+ referenced by: pragma

possibleValue

## UnsignedInt " UnquotedString // UnquotedString " possibleValue ::= '##' UnsignedInt | '"' UnquotedString ( '//' UnquotedString )? '"' referenced by: functionVariable

include

Includes are cScript text fragments that are inserted into the source code before program execution. All includes are replaced by their respective text values, in the order they appear in the source code. If the included text contains more includes, these are also replaced. Multiple insertions of the same include are automatically avoided. You can find our more about includes here.

#include "internal/frameinfos.h" "internal/panels.h" "internal/products.h" "internal/publications.h" "internal/tables.h" "internal/text.h" "internal/textattributes.h" "internal/types.h" pool_include path include ::= '#include' ( '"internal/frameinfos.h"'   | '"internal/panels.h"'   | '"internal/products.h"'   | '"internal/publications.h"'   | '"internal/tables.h"'   | '"internal/text.h"'   | '"internal/textattributes.h"'   | '"internal/types.h"'   | pool_include   | path ) referenced by: prog

pool_include

The non-terminal 'TABLE' represents a string describing the text source of the include in the data pool, read more about this here.

" < pool_type > [ pool_type ] . pool_type _ / TABLE " pool_include ::= '"' ( '<' pool_type '>' | '[' pool_type ']' | '.' pool_type '_' ) '/' TABLE '"' referenced by: include

pool_type

xml sql soap pool_type ::= 'xml' | 'sql' | 'soap' referenced by: pool_include

path

String path ::= String referenced by: include

dcl

Variable declarations. Unless you obtain the value of a pointer variable (*) from a function, such variables first have to be allocated using a suitable function, and freed when leaving their scope. Leaked variables are automatically freed at the end of the script's runtime, not at the end of their scope. Please keep in mind:

From a technical point of view, arrays ([]) are pointerss as well, but its memory is managed automatically. Therefor you should never allocate or free these variables!

Array contents are not initialized automatically!

dtype var_decl , char string_decl , dcl ::= dtype var_decl ( ',' var_decl )* | 'char' string_decl ( ',' string_decl )* referenced by: func_def prog

Some examples of variable declarations:

float square (float f) { return f * f;}

int 	i1		= 12, i2, nn [12];		// The 12 values of nn are uninitialized!
float 	p1		= mm2pt (1.0);			// non-constant initial value
float 	p2		= square (4.0);			// non-constant initial value from custom function
char *	s1		= "abc";				// constant value! May not be modified!
char  	s2[]	= "def";				// constant value! May not be modified!
char  	s4 [4], *s5 = alloc (512);		// do NOT free s4! free s5 with release (s5)
Table	T		= table::alloc ();		// free with table::release (T)

dtype

The data types float and int are 64 bit values in cScript. There are a number of additional data types - you can find a complete list here. These data types exist to improve readability. Internally, they are all defined as int*. Variables of these types are initialized to 0 upon declaration. Variables of types other than int and float have to be allocated before use!

int float cscript/index.html#Typedefs dtype ::= 'int' | 'float' | 'cscript/index.html#Typedefs' referenced by: dcl func param

var_decl

* Ident [ Integer ] Ident = expr * Ident = expr var_decl ::= '*'* Ident ( '[' Integer ']' )? | Ident '=' expr | '*' Ident '=' expr referenced by: dcl

string_decl

* Ident [ Integer ] * Ident = string_expr Ident [ ] = string_expr string_decl ::= '*'* Ident ( '[' Integer ']' )? | '*' Ident '=' string_expr | Ident '[' ']' '=' string_expr referenced by: dcl

func

dtype * func_def char * func_def func ::= dtype '*'* func_def | 'char' '*'+ func_def referenced by: prog

func_def

Ident ( params ) { dcl ; stmt return ; } func_def ::= Ident '(' params ')' '{' ( dcl ';' )* stmt* return ';' '}' referenced by: func

params

param , params ::= ( param ( ',' param )* )? referenced by: func_def

param

dtype * Ident char * Ident param ::= dtype '*'* Ident | 'char' '*'+ Ident referenced by: params

stmt

Expressions in conditions (if, while, for) are always calculated completely! Tests like

if (str && *str)

used for non-empty char * strings in C or C ++ will lead to errors and must be replaced by something like this:

if (str)
{
    if (*str)
    {
    }
}

{ stmt } if ( expr ) stmt else stmt while ( expr ) stmt for ( assg ; expr ; assg ) stmt break ; return ; assg ; Ident ( expr , ) ; ; stmt ::= 'if' '(' expr ')' stmt ( 'else' stmt )+ | 'while' '(' expr ')' stmt | 'for' '(' assg+ ';' expr+ ';' assg+ ')' stmt | 'break' ';' | return ';' | assg ';' | Ident '(' ( expr ( ',' expr )* )? ')' ';' | '{' stmt* '}' | ';' referenced by: func_def stmt

return

return expr return ::= 'return' expr referenced by: func_def stmt

assg

* Ident [ int_expr ] = expr assg ::= '*'+ Ident ( '[' int_expr ']' )+ '=' expr referenced by: stmt

expr

int_expr float_expr string_expr Ident Ident [ int_expr ] Ident ( expr , ) ( expr ) expr ::= int_expr | float_expr | string_expr | Ident | Ident '[' int_expr ']' | Ident '(' ( expr ( ',' expr )* )? ')' | '(' expr ')' referenced by: assg expr return stmt var_decl

int_expr

Integer - int_expr & Ident ( int ) float_expr int_expr binop int_expr int_expr relop int_expr int_expr logical_op int_expr int_expr ::= Integer | '-' int_expr | '&' Ident | '(' 'int' ')' float_expr | int_expr binop int_expr | int_expr relop int_expr | int_expr logical_op int_expr referenced by: assg expr float_expr int_expr

float_expr

ccScript does not perform automatic type conversions! Be sure to pass a floating point number to places that expect a float! For example, 1401 is an integer, and the appropriate floting point number is 1401. or 1401.0.

Float - float_expr ( float ) int_expr float_expr relop float_expr
float_expr ::= Float | '-' float_expr | '(' 'float' ')' int_expr | float_expr relop float_expr referenced by: expr float_expr int_expr

string_expr

String string_expr ::= String referenced by: expr string_decl

binop

Expressions are evaluated back to front!

Because they are calculated from the back to the front, the red-marked terms seem to give wrong results. With parentheses you get the expected results.

x = 3 - 1 + 2;      // evaluates to 0, not 4
  = 3 - 1 + 2
  = 3 - 3
  = 0


x = (3 - 1) + 2;    // evaluates to 4
  = 2 + 2
  = 4

x = 20 / 10 * 2;    // evaluates to 1, not 4
  = 20 / 10 * 2
  = 20 / 20
  = 1


x = (20 / 10) * 2;  // evaluates to 4
  = 2 * 2
  = 4

+ * / binop ::= '+' | '–' | '*' | '/' referenced by: int_expr

relop

== != <= < >= > relop ::= '==' | '!=' | '<=' | '<' | '>=' | '>' referenced by: float_expr int_expr

logical_op

&& || logical_op ::= '&&' | '||' referenced by: int_expr

Ident

Letter Letter Decimal _ Ident ::= Letter ( Letter | Decimal | '_' )* referenced by: assg expr func_def functionVariable int_expr param stmt string_decl var_decl

UnsignedInt

Decimal UnsignedInt ::= Decimal+ referenced by: functionVariable possibleValue

Integer

- Decimal 0x 0X Hex Integer ::= '-'? ( Decimal+ | ( '0x' | '0X' ) Hex+ ) referenced by: int_expr string_decl var_decl

Float

ccScript does not perform automatic type conversions! Be sure to pass a floating point number to places that expect a float! For example, 1401 is an integer, and the appropriate floting point number is 1401. or 1401.0.

- Decimal . Decimal
Float ::= '-'? Decimal* '.' Decimal+ referenced by: float_expr

String

" UnquotedString " String ::= '"' UnquotedString '"' referenced by: path string_expr

UnquotedString

[^"\] "" \x \X Hex Hex \ any ascii char UnquotedString ::= ( [^"\] | '""' | ( '\x' | '\X' ) Hex Hex | '\' 'any ascii char' )* referenced by: String functionVariable possibleValue

Hex

Decimal [a-f] [A-F] Hex ::= Decimal | [a-fA-F] referenced by: Integer UnquotedString

Decimal

[0-9] Decimal ::= [0-9] referenced by: Float Hex Ident Integer UnsignedInt

Letter

[a-z] [A-Z] Letter ::= [a-zA-Z] referenced by: Ident   ... generated by Railroad Diagram Generator R R