-- MPL BNF, taken from Motorola M68MPLR(D) MPL manual, 1/22/81

-- Token definitions

Integer-constant = 2 ;
Decimal-constant = 3 ;
String-constant = 4 ;

-- Special tokens

'->' =  :10 ;

-- Single character tokens

'$' = :24 ;
'%' = :25 ;
'&' = :26 ;
'(' = :28 ;
')' = :29 ;
'*' = :2A ;
'+' = :2B ;
',' = :2C ;
'-' = :2D ;
'/' = :2F ;
':' = :3A ;
'<' = :3C ;
'=' = :3D ;
'>' = :3E ;

-- Reserved words

'A' = :40 ;
'ADDR' = :41 ;
'AND' = :42 ;
'B' = :43 ;
'BASED' = :44 ;
'BIN' = :45 ;
'BIT' = :46 ;
'BSCT' = :47 ;
'BY' = :48 ;
'CALL' = :49 ;
'CHAR' = :4A ;
'CSCT' = :4B ;
-- ***** this should be compared to PL/M!!!!!
'DEC'  = :4D ;
'DECLARE' = :4E ; -- can use 'DCL' as synonym
'DEFINED' = :50 ; -- abbreviated 'DEF'
'DO' = :51 ;
'DSCT' = :52 ;
'ELSE' = :53 ;
'END' = :54 ;
'EQ' = :55 ;
'EXTERNAL' = :56 ;
'GE' = :57 ;
'GIVING' = :58 ;
'GLOBAL' = :59 ;
'GO' = :5A ;
'GOTO' = :5B ;
'GT' = :5C ;
'IAND' = :5D ;
'IEOR' = :5E ;
'IF' = :5F ;
'INITIAL' = :61 ; -- can use 'INIT' as synonym
'IOR' = :62 ;
'LABEL' = :63 ;
'LE' = :64 ;
'LT' = :66 ;
'MAIN' = :67 ;
'NARG' = :68 ;
'NE' = :69 ;
'NOT' = :6A ;
'OPTIONS' = :6B ;
'OR' = :6C ;
'PROCEDURE' = :6E ; -- synonym for 'PROC'
'PSCT' = :6F ;
'RETURN' = :70 ;
'SHIFT' = :71 ;
'SIGNED' = :73 ;
'SS' = :74 ;
'THEN' = :75 ;
'TO' = :76 ;
'WHILE' = :77 ;
'X' = :78 ;
'D' = :79 ;
'P' = :7A ;
'U' = :7B ;
'S' = :7C ;
'Y' = :7D ;

-- MPL syntax equations

program = statement-list ;

statement-list = statement ;
statement-list = statement-list statement ;

statement = label ;
statement = procedure ;
statement = DCL-statement ;
statement = IF-statement ;
statement = DO-block ;
statement = GOTO-statement ;
statement = CALL-statement ;
statement = assignment-statement ;
statement = RETURN-statement ;

label = label-definition ':' ;
-- lexical analyzer converts "id :" to "label-definition :"

label = '$' assembly-language-statement ;

procedure = label-definition ':' 'PROCEDURE' formal-parameters block-end ;

formal-parameters = ;
formal-parameters = 'OPTIONS' ;
formal-parameters = 'OPTIONS' '(' 'MAIN' ')' ;
formal-parameters = 'OPTIONS' '(' 'MAIN' ',' 'SS' '=' integer-constant ')' ;
formal-parameters = '<' '>' ;
formal-parameters = '(' ')' ;
formal-parameters = '<' formal-parameter-list '>' ;
formal-parameters = '(' formal-parameter-list ')' ;

formal-parameter-list = formal-parameter ;
formal-parameter-list = formal-parameter-list ',' formal-parameter ;

formal-parameter = identifier ; -- undeclared or declared

block-end = optional-statement-list END-statement ;

optional-statement-list = ;
optional-statement-list = statement-list ;

END-statement = 'END' ;
END-statement = 'END' label-constant ;
-- label-constant is returned by Lex if identifier is found...
-- that is not followed by '->', '(' or '='

DCL-statement = 'DECLARE' optional-section-name item-list ;

optional-section-name = 'BSCT' ;
optional-section-name = 'CSCT' ;
optional-section-name = 'DSCT' ;
optional-section-name = 'PSCT' ;
optional-section-name = ;

item-list = item ;
item-list = item-list ',' item ;

item = optional-level-number identifier optional-dimension-designator ...
&      attribute ;

optional-level-number = ;
optional-level-number = integer-constant ;

optional-dimension-designator = ;
optional-dimension-designator = '(' integer-constant ')' ;
optional-dimension-designator = '(' integer-constant ',' integer-constant ')' ;
optional-dimension-designator = '(' integer-constant ',' integer-constant ',' ...
&                                   integer-constant ')' ;

attribute = 'LABEL' ;
attribute = 'LABEL' INITIAL-attribute ;
attribute = type-attribute ;
attribute = type-attribute other-attribute ;
attribute = other-attribute ;

INITIAL-attribute = 'INITIAL' '(' constant-list ')' ;

constant-list = constant ;
constant-list = constant-list ',' constant ;

type-attribute = 'SIGNED' ;
type-attribute = 'BIN' size-specification ;
type-attribute = 'SIGNED' 'BIN' size-specification ;
type-attribute = 'DEC' decimal-size-specification ;
type-attribute = 'SIGNED' 'DEC' decimal-size-specification ;
type-attribute = 'CHAR' size-specification ;
type-attribute = 'BIT' size-specificaton ;

size-specification = ;
size-specification = '(' integer-constant ')' ;

decimal-size-specification = ;
decimal-size-specification = '(' integer-constant ')' ;
decimal-size-specification = '(' integer-constant ',' integer-constant ')' ;

other-attribute = INITIAL-attribute ;
other-attribute = 'BASED' ;
other-attribute = 'DEFINED' identifier ; -- that is already defined
other-attribute = 'DEFINED' hexadecimal-constant ;
other-attribute = 'EXTERNAL' ;
other-attribute = 'GLOBAL' ;

IF-statement = 'IF' logical-expression 'THEN' statement ;
IF-statement = 'IF' logical-expression' 'THEN' statement 'ELSE' statement ;

logical-expression = logical-term ;
logical-expression = logical-expression 'OR' logical-term ;

logical-term = logical-factor ;
logical-term = logical-term 'AND' logical-factor ;

logical-factor = logical-primary ;
logical-factor = 'NOT' logical-primary ;

logical-primary = relation ;
logical-primary = '(' logical-expression ')' ;

relation = arithmetic-expression relational-operator arithmetic-expression ;

relational-operator = 'EQ' ;
relational-operator = 'NE' ;
relational-operator = 'LE' ;
relational-operator = 'GE' ;
relational-operator = 'LT' ;
relational-operator = 'GT' ;
relational-operator = '<' ;
relational-operator = '>' ;
-- why can't we use '>=' '<=' '=' here ?

arithmetic-expression = arithmetic-term ;
arithmetic-expression = arithmetic-expression add-op arithmetic-term ;

add-op = '+' ;
add-op = '-' ;

arithmetic-term = arithmetic-factor ;
arithmetic-term = arithmetic-term multiply-op arithmetic-factor ;

multiply-op = '*' ;
multiply-op = '/' ;

arithmetic-factor = arithmetic-pattern ;
arithmetic-factor = arithmetic-factor boolean-op arithmetic-pattern ;

boolean-op = 'IAND' ;
boolean-op = '&' ;
boolean-op = 'IOR' ;
boolean-op = 'IEOR' ;

arithmetic-pattern = arithmetic-slide ;
arithmetic-pattern = arithmetic-pattern shift-op signed-constant ;

shift-op = 'SHIFT' ;
shift-op = '%' ;

signed-constant = constant ;
signed-constant = '-' constant ;

arithmetic-slide = arithmetic-primary ;
arithmetic-slide = '-' arithmetic-primary ;

arithmetic-primary = constant ;
arithmetic-primary = variable ;
arithmetic-primary = '(' arithmetic-expression ')' ;

constant = integer-constant ;
constant = decimal-constant ;
constant = string-constant ;
constant = 'ADDR' '(' identifier ')' ;
constant = 'ADDR' '(' identifier add-op integer-constant ')' ;

variable = identifier ; -- declared name
variable = identifier '->' identifier ; -- both names must be declared
variable = identifier '(' subscript-list ')' ;
variable = identifier '->' identifier '(' subscript-list ')' ;

subscript-list = subscript ;
subscript-list = subscript ',' subscript ;
subscript-list = subscript ',' subscript ',' subscript ;

subscript = integer-constant ;
subscript = identifier ; -- declared name
subscript = identifier add-op integer-constant ;

DO-block = 'DO' iteration-clause WHILE-clause block-end ;
DO-block = 'DO' iteration-clause block-end ;
DO-block = 'DO' WHILE-clause block-end ;

iteration-clause = variable '=' DO-operand 'TO' DO-operand ;
iteration-clause = 'DO' variable '=' DO-operand 'TO' DO-operand ...
&                  'BY' DO-operand ;

DO-operand = variable ;
DO-operand = constant ;

WHILE-clause = 'WHILE' logical-expression ;

GOTO-statement = 'GOTO' destination ;
GOTO-statement = 'GO' 'TO' destination ;

destination = label-constant ;
destination = variable ;
destination = '(' label-constant-list ')' variable ;
destination = '(' label-constant-list ')' ',' variable ;

label-constant-list = label-constant ;
label-constant-list = label-constant-list ',' label-constant ;

CALL-statement = 'CALL' label-constant optional-argument-list optional-GIVING ;

optional-argument-list = ;
optional-argument-list = '(' actual-parameter-list ')' ;
optional-argument-list = '<' actual-parameter-list '>' ;

actual-parameter-list = ;
actual-parameter-list = actual-parameter ;
actual-parameter-list = actual-parameter-list ',' ;
actual-parameter-list = actual-parameter-list ',' actual-parameter ;

actual-parameter = variable ;
actual-parameter = constant ;

optional-GIVING = ;
optional-GIVING = 'GIVING' '<' formal-parameter-list '>' ;

assignment-statement = variable-list '=' arithmetic-expression ;

variable-list = variable ;
variable-list = variable-list ',' variable ;

RETURN-statement = 'RETURN' ;
RETURN-statement = 'RETURN' '<' actual-parameter-list '>' ;

-- End of MPL bnf
