[comp.lang.modula2] Modula grammar

schutten@prls.UUCP (Rindert Schutten) (07/05/90)

I hope this is usefull for you. 

If you have any grammars fopr me, BNF or YACC please send them.

Rindert Schutten

------------------------------------------------------------------------





From mips!sysadmin!uunet!mcsun!brunel.ac.uk!cornelia.boldyreff Fri May 11 08:01:20 1990
Received: by mips.com (5.61.14/1.11) id AA13203; Fri, 11 May 90 07:30:58 -0700 
Received: by sysadmin.sysadmin.com (/\=-/\ Smail3.1.17.5 #17.4)
	id <m0hTZMm-0000RBC@sysadmin.sysadmin.com>; Fri, 11 May 90 05:45 PDT
Received: from mcsun.UUCP by uunet.uu.net (5.61/1.14) with UUCP 
	id AA21268; Fri, 11 May 90 07:54:03 -0400
Received: by mcsun.EU.net via EUnet; Fri, 11 May 90 13:49:35 +0200 (MET)
Received: from brunel.ac.uk by kestrel.Ukc.AC.UK   via Janet (UKC CAMEL FTP)
           id aa29872; 11 May 90 12:20 BST
Received: from Saturn by Echo.hub.brunel.ac.uk; Fri, 11 May 90 11:57:03 +0100
From: Cornelia Boldyreff <mips!brunel.ac.uk!Cornelia.Boldyreff>
Date: Fri, 11 May 90 11:55:48 +0100
Message-Id: <11885.9005111055@Saturn.cs.brunel.ac.uk>
To: prls!schutten
Status: R

Subject: Grammars Request
Status: R

This message contains the source of a lex'er and parser for
Modula-2; files m2c.l and m2c.y respectively. The makefile
will generate a syntax checker for Modula 2 in m2c. There is 
also a manual page in m2c.1.
Cornelia Boldyreff
p.s. I would be interested to hear what other grammars you receive;
we may be interested in the C/C++ grammars.
====m2cm.l (=lex input)
%%
[ \n\t]       { ; } /* ignore white space: blanks, newlines & tabs */
AND { return( AND );}
ARRAY { return( ARRAY );}
BEGIN { return( _BEGIN );}
BY { return( BY );}
CASE { return( CASE );}
CONST { return( CONST );}
DEFINITION { return( DEFINITION );}
DIV { return( DIV );}
DO { return( DO );}
ELSE { return( ELSE );}
ELSIF { return( ELSIF );}
END { return( END );}
EXIT { return( EXIT );}
EXPORT { return( EXPORT );}
FOR { return( FOR );}
FROM { return( FROM );}
IF { return( IF );}
IMPLEMENTATION { return( IMPLEMENTATION );}
IMPORT { return( IMPORT );}
IN { return( IN );}
LOOP { return( LOOP );}
MODULE { return( MODULE );}
MOD { return( MOD );}
NOT { return( NOT );}
OF { return( OF );}
OR { return( OR );}
POINTER { return( POINTER );}
PROCEDURE { return( PROCEDURE );}
QUALIFIED { return( QUALIFIED );}
RECORD { return( RECORD );}
REPEAT { return( REPEAT );}
RETURN { return( RETURN );}
SET { return( SET );}
THEN { return( THEN );}
TO { return( TO );}
TYPE { return( TYPE );}
UNTIL { return( UNTIL );}
VAR { return( VAR );}
WHILE { return( WHILE );}
WITH { return( WITH );}
\& { return( ampersand );}
\* { return( asterisk );}
\:\= { return( colon_equals );}
: { return( colon );}
\, { return( comma );}
\.\. { return( dot_dot );}
\. { return( dot );}
= { return( equals_sign );}
\>= { return( greater_than_or_equals );}
\> { return( greater_than );}
\{ { return( left_curley_bracket );}
\( { return( left_parenthesis );}
\[ { return( left_square_bracket );}
\<= { return( less_than_or_equals );}
\<\> { return( not_equals );}
\< { return( less_than );}
\- { return( minus );}
\+ { return( plus );}
# { return( pound_sign );}
\} { return( right_curley_bracket );}
\) { return( right_parenthesis );}
\] { return( right_square_bracket );}
; { return( semicolon );}
\/ { return( slash );}
\^ { return( up_arrow );}
\| { return( vertical_bar );}
"\""[^"\""\n]*"\"" { return( string );}
\'[^\'\n]*\' { return( string );}
[A-Za-z][0-9A-Za-z]* { return( identifier ); }
[0-9][0-9]*\.[0-9]*E[\+\-][0-9]+ { return( real );}
[0-9][0-9]*\.[0-9]* { return( real );}
[0-7]+B { return( integer );}
[0-7]+C { return( integer );}
[0-9][0-9A-F]*H { return( integer );}
[0-9]+ { return( integer );}
====m2c.y (=yacc input)
%token AND
%token ARRAY
%token _BEGIN
%token BY
%token CASE
%token CONST
%token DEFINITION
%token DIV
%token DO
%token ELSE
%token ELSIF
%token END
%token EXIT
%token EXPORT
%token FOR
%token FROM
%token IF
%token IMPLEMENTATION
%token IMPORT
%token IN
%token LOOP
%token MOD
%token MODULE
%token NOT
%token OF
%token OR
%token POINTER
%token PROCEDURE
%token QUALIFIED
%token RECORD
%token REPEAT
%token RETURN
%token SET
%token THEN
%token TO
%token TYPE
%token UNTIL
%token VAR
%token WHILE
%token WITH
%token ampersand
%token asterisk
%token colon
%token colon_equals
%token comma
%token dot
%token dot
%token dot_dot
%token end_of_file
%token equals_sign
%token greater_than
%token greater_than_or_equals
%token identifier
%token integer
%token left_curley_bracket
%token left_parenthesis
%token left_square_bracket
%token left_square_bracket
%token less_than
%token less_than_or_equals
%token minus
%token not_equals
%token plus
%token pound_sign
%token real
%token right_curley_bracket
%token right_parenthesis
%token right_square_bracket
%token semicolon
%token slash
%token string
%token up_arrow
%token vertical_bar
%%
compilation : compilation_unit_list ;
compilation_unit_list : compilation_unit | compilation_unit_list
			compilation_unit;
compilation_unit : module;
module : program_module | definition_module | implementation_module;
file_ident : identifier;
program_module : MODULE file_ident priority_opt semicolon
                 import_list_opt block ident dot;
definition_module : DEFINITION MODULE file_ident semicolon
		    import_list_opt export_opt definition_list_opt
		    END ident dot;
implementation_module : IMPLEMENTATION program_module;
priority_opt : | priority;
priority : left_square_bracket const_expression right_square_bracket;
const_expression : expression;
relation : equals_sign | pound_sign | not_equals | less_than | 
	   less_than_or_equals | greater_than | greater_than_or_equals
	   | IN;
import_list_opt : | import_list;
import_list : import | import_list import;
import : from_opt IMPORT ident_list semicolon;
from_opt : | from;
from : FROM ident;
ident_list : ident | ident_list comma ident;
ident : identifier;
block : declaration_list_opt begin_and_stmts_opt END;
declaration_list_opt : | declaration_list;
declaration_list : declaration | declaration_list declaration;
declaration : error semicolon |
	      CONST constant_declaration_list_opt |
	      TYPE type_declaration_list_opt |
	      VAR variable_declaration_list_opt |
	      procedure_declaration semicolon|
	      module_declaration semicolon;
begin_and_stmts_opt : | begin_and_stmts;
begin_and_stmts : _BEGIN statement_list;
export_opt : | export;
export : EXPORT qualified_opt ident_list semicolon;
qualified_opt : | qualified;
qualified : QUALIFIED;
definition_list_opt : | definition_list;
definition_list : definition | definition_list definition;
definition : CONST constant_declaration_list_opt |
	     TYPE type_definition_list_opt |
	     VAR variable_declaration_list_opt |
	     procedure_heading semicolon;
type_declaration_list_opt : | type_declaration_list;
type_declaration_list : type_declaration | type_declaration_list
			type_declaration;
type_declaration : ident equals_sign type semicolon;
constant_declaration_list_opt : | constant_declaration_list;
constant_declaration_list : constant_declaration | constant_declaration_list
			constant_declaration;
constant_declaration : ident equals_sign const_expression semicolon;
type_definition_list_opt : | type_definition_list;
type_definition_list : type_definition | type_definition_list
                       type_definition;
type_definition : ident type_definition_opt semicolon;
type_definition_opt : | type_definition;
type_definition : equals_sign type;
variable_declaration_list_opt : | variable_declaration_list;
variable_declaration_list : variable_declaration | variable_declaration_list
			variable_declaration;
variable_declaration : field_declaration semicolon;
field_declaration : ident_list colon type;
proc_ident : ident;
procedure_heading : PROCEDURE proc_ident formal_parameters_opt function_opt;
procedure_declaration : procedure_heading semicolon block ident;
module_declaration : MODULE ident priority_opt semicolon import_list_opt
                     export_opt block ident;
type : simple_type | array_type | record_type | set_type | pointer_type
       procedure_type;
formal_parameters_opt : | formal_parameters;
formal_parameters : left_parenthesis fp_section_list_opt right_parenthesis;
fp_section_list_opt : | fp_section_list;
fp_section_list : fp_section | fp_section_list semicolon fp_section;
fp_section : var_opt ident_list colon formal_type;
function_opt : | function;
function : colon qualident;
var_opt : | var;
var : VAR;
formal_type : array_opt qualident;
qualident : designator;
array_opt : | array;
array : ARRAY OF;
simple_type : qualident | enumeration | subrange_type;
enumeration : left_parenthesis ident_list right_parenthesis;
subrange_type : left_square_bracket subrange right_square_bracket;
subrange : const_expression dot_dot const_expression;
array_type : ARRAY simple_type_list OF type;
simple_type_list : simple_type | simple_type_list comma simple_type;
record_type : RECORD field_list END;
field_list : field | field_list semicolon field;
field :  | field_declaration | variant_field;
variant_field : CASE tag OF variant_list variant_else_opt END;
tag : ident colon qualident | ident ref_list_opt;
variant_list : variant | variant_list vertical_bar variant;
variant : case_label_list colon field_list;
case_label_list : case_label | case_label_list comma case_label;
case_label : const_expression | subrange;
variant_else_opt : | variant_else;
variant_else : ELSE field_list;
set_type : SET OF simple_type;
pointer_type : POINTER TO type;
procedure_type : PROCEDURE formal_type_list_opt function_opt;
formal_type_list_opt : | formal_type_list;
formal_type_list : left_parenthesis ft_list_opt right_parenthesis;
ft_list_opt : | ft_list;
ft_list : ft | ft_list comma ft;
ft : var_opt formal_type;
statement_list : statement | statement_list semicolon statement;
statement :  | assignment | procedure_call | if_statement |
            case_statement | while_statement | repeat_statement |
	    loop_statement | for_statement | with_statement | EXIT |
	    RETURN expression_opt;
expression_opt : | expression;
assignment : out_designator out_colon_equals expression;
out_designator : designator;
out_colon_equals : colon_equals;
designator : ident ref_list_opt;
ref_list_opt : | ref_list;
ref_list : ref | ref_list ref;
ref : dot ident | left_square_bracket exp_list right_square_bracket |
      up_arrow;
exp_list_opt : | exp_list;
exp_list : expression | exp_list comma expression;
procedure_call : designator actual_parameters_opt;
actual_parameters_opt : | actual_parameters;
actual_parameters : left_parenthesis exp_list_opt right_parenthesis;
if_statement : IF expression THEN statement_list elsif_list_opt
               else_opt END;
elsif_list_opt : | elsif_list;
elsif_list : elsif | elsif_list elsif;
elsif : ELSIF expression THEN statement_list;
else_opt : | else;
else : ELSE statement_list;
case_statement : CASE expression OF case_list else_opt END;
case_list : case | case_list vertical_bar case;
case : case_label_list colon statement_list;
while_statement : WHILE expression DO statement_list END;
repeat_statement : REPEAT statement_list UNTIL expression;
loop_statement : LOOP statement_list END;
for_statement : FOR ident colon_equals expression TO expression by_opt
		DO statement_list END;
by_opt : | by;
by : BY const_expression;
with_statement : WITH designator DO statement_list END;
expression : simple_expression | simple_expression relation simple_expression;
simple_expression : sign_opt term | simple_expression add_operator term;
add_operator : plus | minus | OR;
sign_opt : | sign;
sign : plus | minus;
term : factor | term mul_operator factor;
mul_operator : asterisk | slash | DIV | MOD | AND | ampersand;
factor : number | string | set | designator actual_parameters_opt |
	 left_parenthesis expression right_parenthesis | NOT factor;
number : integer | real;
set : qualident_opt left_curley_bracket element_list_opt
      right_curley_bracket;
qualident_opt : | qualident;
element_list_opt :  | element_list;
element_list : element | element_list comma element;
element : case_label;
%%
#include <stdio.h>
char *filename="-";
main(argc, argv) 
int argc;
char *argv[];
{ 
  register int rc=0;
  extern int yynerrs;
  extern int yylineno;
  if (argc <= 1) 
      yyparse();
  else 
     {
       while (argc > 1) 
       { if (freopen(argv[1], "r", stdin)==NULL) {
	     fprintf(stderr, "m2c: %s: cannot open\n", argv[1]);
	     rc++; }
         else {
             filename=argv[1];
	     yylineno=1;
	     yyparse(); }
         argc--; argv++;
       }
      }
   if (yynerrs > 0) rc++; 
   return(rc);
}
#include "lex.yy.c"
yyerror(s)
 char *s;
{
 fprintf(stderr, "\"%s\", line %d: %s\n", 
	 filename, yylineno, s);
}
====makefile
m2c : m2c.l m2c.y
	lex m2c.l; yacc m2c.y; cc y.tab.c -ll -o m2c
====m2c.1 (=man page)
.\" $Header: m2c.1, 87/05/26 corn Stab $
.de SB
.\" SuBheader
.sp 1
.nr Sf \\n(.f
.ft B
.PP
\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
.ft \\n(Sf
.sp 1
..
.TH M2C I
.ad
.SH NAME
m2c \- Modula 2 Syntax Checker
.SH SYNOPSIS
\fBm2c\fP [file...]
.SH DESCRIPTION
.PP
.PP
.PP
.PP
\fIm2c\fP accepts any number of file arguments. 
.PP
.SH "SEE ALSO"
.PD 0
.br
.nf
.fi
.PP
.SH KNOWN BUGS/BODGES/LIMITATIONS
.PP
m2c does not always recover from syntax errors.
.PP
Feel free to distribute m2c further but please acknowledge use/references.
.PP
.SH AUTHOR
.PP
.nf
Cornelia Boldyreff
Department of Computer Science
Brunel University
Uxbridge UB8 3PH
The United Kingdom
.br