prog:     stmts;
prog: [ vars ] funs;

        
vars: 'var' names ';';

        
names: Name [{ ',' Name }];

        
funs: { fun };

        
fun: head [ 'begin' stmts 'end' ] ';';

        
head: 'function' Name;
stmts:    stmt [{ ';' stmt }];
stmts: stmt [{ ';' stmt }];
stmt:     assign | print | loop | select;
stmt: assign | print | return | loop | select;
assign:   Name '=' sum;
assign: Name [ '=' sum ];
print:    'print' sums;
print: 'print' sums;
sums:     sum [{ ',' sum }];
sums: sum [{ ',' sum }];

        
return: 'return' [ sum ];
loop:     While cmp Do stmts 'od';
loop: While cmp Do stmts 'od';
While:    'while';
While: 'while';
Do:       'do';
Do: 'do';
select:   'if' cmp Then stmts [ Else stmts ] 'fi';
select: 'if' cmp Then stmts [ Else stmts ] 'fi';
Then:     'then';
Then: 'then';
Else:     'else';
Else: 'else';
cmp:      sum rel;
cmp: sum rel;
rel:      eq | ne | gt | ge | lt | le;
rel: eq | ne | gt | ge | lt | le;
eq:       '=' sum;
eq: '=' sum;
ne:       '<>' sum;
ne: '<>' sum;
gt:       '>' sum;
gt: '>' sum;
ge:       '>=' sum;
ge: '>=' sum;
lt:       '<' sum;
lt: '<' sum;
le:       '<=' sum;
le: '<=' sum;
sum:      product [{ add | subtract }];
sum: product [{ add | subtract }];
add:      '+' product;
add: '+' product;
subtract: '-' product;
subtract: '-' product;
product:  signed [{ multiply | divide }];
product: signed [{ multiply | divide }];
multiply: '*' signed;
multiply: '*' signed;
divide:   '/' signed;
divide: '/' signed;
signed:   [ '-' ] term;
signed: [ '-' ] term;
term:     input | number | name | '(' sum ')';
term: input | number | name | '(' sum ')';
input:    'input' [ Number ];
input: 'input' [ Number ];
number:   Number;
number: Number;
name:     Name;
name: Name;