FreeBASIC grammar
 
Grammar Notation

Format of a production
left hand side: right hand side;

: should be read as 'is defined as'.

The right hand side of a production is terminated by a ;.

A word in italics represent the name of a production (the left
hand side of the production).

Few operators are used to describe the FreeBASIC grammar.

operatormeaning
.any character
*0 or more (repetition)
+1 or more (repetition)
?optional (choice)
()grouping
|separator (separates alternatives)
semicolonend of production


Any symbol that appears on the right hand side of a production
that is not an operator and does not appear in italics
represents itself and appears bold.
A symbol at the right hand side of a rule can refer to a production.
Such references are in italics.

For navigational purposes a reference is a link to the production
being referenced.

When reading the grammar be aware that FreeBASIC is a case insensitive
language.

The grammar presented is not an exact statement of the FreeBASIC language.

Go straight to:
program
expression

Tokens

white: \t |
any_char:   any valid character;
eol:    \n|\r|\n\r;
statement_separator: ( : | eol )+;
dot:         .;
sign:        +|-;
alpha:      a|b|c|d|e|f|g|h|i|j|k|l|m|n|p|q|r|s|t|v|w|x|y|z;
digit:       0|1|2|3|4|5|6|7|8|9;
hexdigit:   a|b|c|d|e|f|digit;
octdigit:   0|1|2|3|4|5|6|7;
bindigit:   0|1;
alphadigit:  alpha| digit;
integer_suffix:     %|&|l|u|ul|ll|ull;
floating_point_suffix:     !|#|f;
suffix:      integer_suffix|floating_point_suffix|$;
expchar:  d|e;
operator
: = | < | > |<> |+ | - | * | @
& | -> | / | \ | ^ | andalso
orelse | and | or | xor | eqv | imp
+= | -= | *= | /= | \= | ^= | &= |
and= | or= | xor= | eqv= | imp=
new | delete | delete[] | cast | procptr
varptr | strptr | sizeof | [] | ()
;

binary_operator
: = | < | > |<> |+ | - |
& | -> | / | \ | ^
+= | -= | *= | /= | \= | ^= | &= |
and= | or= | xor= | eqv= | imp=
andalso | orelse
;

identifier
:  (alpha)(alphadigit|_)*
nbsp _(alphadigit|_)+
;

literal
integer_literal
decimal_integer: digit+;
hexadecimal integer: &hhexdigit+;
octal_integer: &ooctdigit+;
binary_integer: &bbindigit+;

floating_literal
: digit+(dot(digit+)?)?(exp_char?(sign?digit+)?)?suffix?
nbsp(dot(digit+)?)?(exp_char?(sign?digit+)?)?suffix?
;

string_literal
escape_sequence
simple_escape_sequence
: \a|\b|\f|\l|\n|\r|\t|\v|\\|\'|\"
;

unicode_escape_sequence
decimal_escape_sequence
hexadecimal_escape_sequence
octal_escape_sequence
binary_escape_sequence
Comment

comment
: ( ' | rem) (($directive) | (any_char_but_eol*))
;
multiline_nested_comment
: /' ( . | multiline_nested_comment)* '/;

Toplevel

program
: line* EOF?
;
line
label
: identifier :
;

statement
(declaration | procedure_call_or_assign | compound_statement | quirk_statement | assembler_block | assignment )?
(statement_separator statement)*
;

declaration
procedure_call_or_assign
: call identifier ((procedure_parameter_list))?
identifier procedure_parameter_list?
(identifier | function | operator | property) = expression
;

compound_statement
namespace_statement
: namespace identifier (alias string_literal)? (declaration | namespace_statement)* end namespace
;

scope_statement: scope statement_separator statement* end scope
;

if_statement
short_if_statement
else statement_separator statement*
(eol| end if | endif)
;

long_if_statement
statement*
elseif_block*
(else statement_separator statement*)?
(end if|endif)
;

elseif_block
for_statement
(statement|exit for(, for)* | continue for (, for)*)* next identifier (, identifier)* statement_separator
;

do_statement
: do (until|while) expression (statement|exit do (, do)* | continue do (, do)*)* loop
do (statement|exit do (, do)* | continue do (, do)*)* loop (until|while) expression statement_separator
;

while_statement
(statement | exit while (, while)* | continue while (, while)*)*
wend
;

select_statement
: select case (as const) expression case_statement* case else statement_separator statement* end select
;
case_statement
case_expression
: expression | expression to expression | is (> | < | >= | <= | = | <>) expression;

assembler_block
: asm comment? (asm_code comment? eol)+ end asm
;

assignment
variable
const_declaration
: const (as symbol_type)? const_assign (, const_assign)*
;

type_or_union_declaration
type_declaration
union_declaration
: union identifier (alias string_literal)? (field = expression)? (comment)? statement_separator
union_member_declaration+
end union
;

type_member_declaration
: ( (union|type) comment? statement_separator element_declaration+
end (union|type)
)
element_declaration
as as_element_declaration
;


variable_declaration
: (redim preserve?|dim|common) shared? symbol_type
extern import? symbol_type alias string_literal
static symbol_type
;

symbol_type
: const? unsigned?
(
scalar
string (* integer_literal)?
wstring (* integer_literal)?
user_defined_type
function (( parameters )) (as symbol_type)
sub (( parameters ))
)(const? (ptr|pointer))*
;

scalar
: byte
ubyte
short
ushort
integer
uinteger
longint
ulongint
long
ulong
single
double
;

parameters
parameter
: (byval|byref)? (identifier (( ))?)? as symbol_type (= literal)?
;


user_defined_type
procedure_declaration
procedure_parameter_list
procedure_parameter
: byval? (identifier(( ))? | expression )
;


expressions

expression
boolean_expression
: logical_expression( ( andalso | orelse ) logical_expression)*
;

logical_expression
: logical_or_expression ( (xor | eqv | imp) logical_or_expression )*
;

logical_or_expression
logical_and_expression
relational_expression
concatenation_expression
add_expression
shift_expression
: mod_expression ( (shl | shr) mod_expression )*
;

mod_expression
integer_division_expression
multiplication_expression
exponentiation_expression
prefix_expression
highest_precedence_expression
address_of_expression
: varptr ( highest_precedence_expression )
procptr ( identifier (())? )
@ (identifier (())? | highest_precedence_expression)
sadd|strptr ( expression )
;

dereference_expression
casting_expression
: cast ( symbol_type , expression )
;


quirk_function
quirk_function_name
: mkd | mki | mkl | mklongint | mkshort
cvd | cvi | cvl | cvlongint | cvs | cvshort
asc | chr | instr | instrev | lcase | left | len | lset | ltrim | mid | right | rset | rtrim | space | string | ucase | wchr | wstr | wstring
abs | sgn | fix | frac | len | sizeof,sin | asin | cos | acos | tan | atn | sqr | log | exp | atan2 | int
peek
lbound | ubound
seek | input | open | close | get | put | name
err
iif
va_first
cbyte | cshort | cint | clng | clngint | cubyte | cushort | cuint | culng | culngint | csng | cdbl | csign | cunsg
type
view | width | color | screen
;



quirk_statement
jump_statement
: goto identifier
;

print_statement
: (print | ?) (# expression ,)? (using expression ;)? (expression? ; | , )*;

data_statement
: restore identifier
read variable (, variable)*
data literal (, literal)*
;

array_statement
: erase variable (, variable)*
;

line_input_statement
: line input ;? (# expression| expression?) (, | ; )? variable?
;

input_statement
: input ;? ((# expression| string_literal) (, | ;))? variable (, variable)*
;

poke_statement
file_statement
: close (#? expression) (, #? expression)*
;

write_statement
: write (# expression)? (expression? , )*
;

error_statement
: error expression
err = expression
;

on_statement
: on local? (error | expression) goto identifier
;

view_statement
: view (print (expression to expression)?)
;

mid_statement
lrset_statement
width_statement
: width expression , expression
width lprint expression
width (# expression| expression), expression
;

color_statement
: color expression , expression
;

gfx_statement
: pset ( expression , )? step? ( expression , expression ) (, expression )?
line ( expression , )? step? (( expression , expression ) )? - step? ( expression , expression ) (, expression? (, string_literal? (, expression )?)?)?
circle ( expression , )? step? ( expression , expression ) , expression ((, expression? (, expression? (, expression? (, expression (, expression)? )? )?)?)?)?
paint ( expression , )? step? ( expression , expression ) (, expression? (, expression? ) )
draw ( expression , )? expression
view (screen? ( expression , expression ) - ( expression , expression ) (, expression? (, expression)?)? )?
palette get? ((using variable) | (expression , expression (, expression , expression)?)?)
put ( expression , )? step? ( expression , expression ) , ( ( expression , expression ) - ( expression , expression ) ,)? variable (, expression (, expression)?)?
get ( expression , )? step? ( expression , expression ) - step? ( expression , expression ) , variable
screen (integer_literal | ((expression (((, expression)? , expression)? expression)? , expression))
screenres expression , expression (((, expression)? , expression)? , expression)?
;