This chapter contains a schematic specification of the language syntax
of ANA. All valid ANA code can be expressed in terms of the following
specification. The specification consists of a number of rules. The
word on the left-hand side of the first colon of each rule indicates the
name of the rule, and the text following the colon specify the valid
forms of the rule, separated by vertical bars (|). Lower-case words
indicate names of other rules. Upper-case words indicate key ANA syntax
words (such as FOR and ELSE) or names of types of
expressions that can appear at those points (such as FILENAME or
NUMBER), or the expression (empty) which means no input,
or C_ID, which stands for a common identifier (one starting with
an alphabetic character), or S_ID, which stands for a special
identifier (one starting with one character out of ! $ #). Other
characters are expected in the input at the indicated positions. By
starting at the very first rule (the one named lines) and
successively replacing rule names by one of their valid forms you can
end up with any valid piece of ANA code. However, not all possible
output of this set of rules yields valid ANA code: whether some code is
valid depends also on the classes and contents of the variables and
expressions, which is not taken into account in these rules.
lines:
next_line | lines next_line
next_line:
statement | NEWLINE
statement:
assignment | routine_execution | routine_definition
| selection | loop | RETURN opt_arg |
begingroup statement_list endgroup | BREAK |
CONTINUE | @FILENAME | @@FILENAME |
RETALL | RUN , var | RUN var
opt_arg:
(empty) | , expr
begingroup:
BEGIN | {
endgroup:
END | }
assignment:
lhs = expr | lhs op_assign
expr
tag_list:
STRUCTTAG | tag_list STRUCTTAG
member_spec:
( subsc_list ) | tag_list |
member_spec ( subsc_list ) |
member_spec tag_list
lhs:
var member_spec | var
var:
C_ID | S_ID
struct_list:
struct_element | struct_list ,
struct_element
struct_element:
C_ID : expr | expr
expr:
NUMBER | STRING | lhs | var (
) | expr member_spec | & var |
( range ) | { struct_list }
| { } | | ( expr ) | [
expr_list ] | expr + expr |
expr - expr | expr * expr |
expr / expr | expr % expr |
expr ^ expr | expr > expr |
expr < expr | expr EQ expr |
expr NE expr | expr GE expr |
expr GT expr | expr LT expr |
expr LE expr | expr AND expr |
expr OR expr | expr XOR expr |
expr & expr | expr | expr |
expr ANDIF expr | expr ORIF
expr | - expr | + expr
expr_list:
expr | expr_list , expr
range:
expr : expr | expr : *
- expr | expr : * | * -
expr : expr | * - expr
: * - expr | * - expr
: * | * - expr | *
subsc:
range | range : + | range :
> expr | + | > expr | expr
: > expr | expr : +
subsc_or_key:
subsc | expr | key
subsc_list:
subsc_or_key | subsc_list , subsc_or_key
op_assign:
+= | -= | *= | /=
routine_execution:
C_ID s_arglist
s_arglist:
(empty) | , arglist
arglist:
arg | arglist , arg
key_param:
C_ID
key:
key_param = expr | / key_param
arg:
expr | key
routine_definition:
SUBR C_ID s_paramlist statement_list
endsubr | FUNC C_ID f_paramlist
statement_list endfunc | BLOCK C_ID
statement_list endblock
endsubr:
ENDSUBR | END
endfunc:
ENDFUNC | END
endblock:
ENDBLOCK | END
paramlist2:
paramlist | paramlist , ELLIPSIS
s_paramlist:
(empty) | , paramlist2
sf_paramlist:
s_paramlist | f_paramlist
paramlist:
C_ID | paramlist , C_ID
statement_list:
statement | statement_list statement
f_paramlist:
( ) | ( paramlist2 ) |
s_paramlist
selection:
IF expr opt_then statement opt_else |
CASE case_list opt_else ENDCASE |
NCASE expr statement_list opt_else
ENDCASE
opt_then:
(empty) | THEN
opt_else:
(empty) | ELSE statement
opt_case_else:
(empty) | ELSE statement | ELSE :
statement
case_list:
expr : statement | case_list expr
: statement
loop:
FOR C_ID = expr , expr
opt_step opt_do statement | REPEAT
statement UNTIL expr | DO statement
WHILE expr | WHILE expr opt_do
statement
opt_step:
(empty) | , expr
opt_do:
(empty) | DO