[comp.lang.eiffel] Eiffel grammar

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

From prlbcom!prlb.philips.be!mswe.decnet.philips.be!jvdgoor@philabs.philips.com Mon May 14 18:10:13 1990
Return-Path: <prlbcom!prlb.philips.be!mswe.decnet.philips.be!jvdgoor@philabs.philips.com>
Received: from prls.local by plsn01. (4.0/SMI-4.0)
	id AA09468; Mon, 14 May 90 18:10:10 PDT
Received: by prls.local (1.2/Ultrix2.0-B)
	id AA11660; Mon, 14 May 90 18:06:42 pdt
Received: by philabs.Philips.Com (smail2.5/12-15-87/5.51) 
	id AA18655; Mon, 14 May 90 18:58:24 EDT
Received: by prlbcom.prlb.philips.be (4.0/4.7)
	id AA00444; Mon, 14 May 90 18:48:00 +0200
Date: Mon, 14 May 90 18:48:00 +0200
From: mswe.decnet.philips.be!jvdgoor@prlb.philips.be
Message-Id: <9005141648.AA00444@prlbcom.prlb.philips.be>
To: prls!schutten@prls.
Subject: Eiffel (lex and yacc)
X-Received: at PRLB50 14-MAY-1990 14:18:27
X-Vms-To: PRLB::NET%"schutten@prls.uucp"
Status: R

/*********************************************************/
/*                  FILE: eiffel.l                       */
/*                                                       */
/*       Lex description for Eiffel 2.2                  */
/* as used by Interactive Software Engineering, Inc.     */
/*                                                       */
/*      Authors:                                         */
/*         Olivier Mallet                                */
/*         Jean-Marc Nerson                              */
/*         Jean-Pierre Sarkis                            */
/*         Herve Templereau                              */
/*         Deniz Yuksel                                  */
/*      Date:                                            */
/*         December 24, 1989                             */
/*                                                       */
/*********************************************************/

D      [0-9]
O      [0-7]   
E      e[+-]?{D}+
A      ([a-z]|_)
X      ([a-z]|[0-9]|_)
W      [ \t\n]
U      [!#$%&\\|`~]


%{
#include <ctype.h>
#undef input
/* 
 * Eiffel is not case sensitive: convert Lex input into a lowercase stream 
 */
#define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):getc(yyin))==10?(yylineno++,yytchar):yytchar)==EOF?0:isupper(yytchar)?tolower(yytchar):yytchar)
#include "y.tab.h"
static void get_string(), get_char();
%}
%p 3200
%%
--.*      {/*delete comments first*/}
{W}+      {/*ignore white space*/}   
{D}+/".." {return AN_INTEGER;}
"integer"      {return INTEGER;}
"real"      {return REAL;}
"boolean"      {return BOOLEAN;}
"character"   {return CHARACTER;}
"true"      {return TTRUE;}
"false"      {return FFALSE;}
";"      {return SEMICOLON;}
":"      {return COLON;}
","      {return COMMA;}
".."      {return DOTDOT;}
"."      {return DOT;}
"@"      {return ADDRESS;}
":="      {return ASSIGN;}
"?="      {return ACCEPT;}
"="      {return EQ;}
"<"      {return LT;}
">"      {return GT;}
"<="      {return LE;}
">="      {return GE;}
"/="      {return NE;}
"--"      {return COMM;}
"("      {return LPARAN;}
")"      {return RPARAN;}
"{"      {return LCURLY;}
"}"      {return RCURLY;}
"["      {return LSQURE;}
"]"      {return RSQURE;}
"+"      {return PLUS;}
"-"      {return MINUS;}
"*"      {return STAR;}
"/"      {return SLASH;}
"^"      {return POWER;}
"->"     {return CONSTRAIN;}
"as"   {return AS;}
"and"      {return AND;}
"and"{W}+"then"   {return AND_THEN;}
"bits"      {return BITS;}
"check"      {return CHECK;}
"class"      {return CLASS;}
"clone"      {return CLONE;}
"create"   {return CREATE;}
"current"   {return CURRENT;}
"debug"      {return DEBUGG;}
"deferred"   {return DEFERRED;}
"define"   {return DEFINE;}
"div"      {return DIV;}
"do"      {return DO;}
"double"   {return DOUBLE;}
"else"      {return ELSE;}
"elsif"      {return ELSIF;}
"end"      {return END;}
"ensure"   {return ENSURE;}
"expanded"   {return EXPANDED;}
"export"   {return EXPORT;}
"external"   {return EXTE;}
"feature"   {return FEATURE;}
"forget"   {return FORGET;}
"from"      {return FROM;}
"if"      {return IF;}
"implies"   {return IMPLIES;}
"indexing" {return INDEXING;}
"infix"   {return INFIX;}
"inherit"   {return INHERIT;}
"inspect"   {return   INSPECT;}
"invariant"   {return INVARIANT;}
"is"      {return IS;}
"language"   {return LANGUAGE;}
"like"      {return LIKE;}
"local"      {return LOCAL;}
"loop"      {return LOOP;}
"mod"      {return MOD;}
"name"      {return NAME;}
"nochange"   {return NOCHANGE;}
"not"      {return NOT;}
"obsolete"   {return OBSOLETE;}
"old"      {return OLD;}
"once"      {return ONCE;}
"or"      {return OR;}
"or"{W}+"else"   {return OR_ELSE;}
"prefix"   {return PREFIX;}
"redefine"   {return REDEFINE;}
"require"   {return REQUIRE;}
"rename"   {return RENAME;}
"repeat"   {return REPEAT;}
"rescue" {return RESCUE;}
"result"   {return RESULT;}
"retry"  {return RETRY;}
"then"      {return THEN;}
"unique"      {return UNIQUE;}
"until"      {return UNTIL;}
"variant"   {return VARIANT;}
"void"      {return VOID;}
"when"      {return WHEN;}
"xor"      {return XOR;}

{A}{X}*      {return AN_ID;}
{D}*      {return AN_INTEGER; }
{D}*\.{D}+({E})? | 
{D}+\.{D}*({E})? | 
{D}+{E}   {return A_REAL; }
\"      {get_string(); return A_STRING;}
\'      {get_char(); return A_CHAR;}

{U}   {yyerror ("unknown character (ignored)");}
%%

/* 
 * Character recognition: over-simplified version. 
 */
static   void get_char()
{
   int c;
   switch (c = getc (yyin)) {
      case '\'':
      case '\\': c = getc (yyin); while((c = getc(yyin)) != '\''); break;
      default: while((c = getc(yyin)) != '\''); break;
   }
}

/* 
 * String recognition: over-simplified version. 
 */
static   void get_string()
{
   int c;
   do {
      switch (c = getc (yyin)) {
         case '\\': if ((c = getc (yyin))== '"') c = getc (yyin); break;
         default: break;
      }
   } while (c != '"');
}
===================== CUT HERE ================================
/*********************************************************/
/*         FILE: eiffel.y                                */
/*                                                       */
/*       Yacc description for Eiffel 2.2
 * as used by Interactive Software Engineering 
 *
 * 
 *      Authors: 
 *         Olivier Mallet
 *         Jean-Marc Nerson
 *         Jean-Pierre Sarkis
 *         Herve Templereau
 *         Deniz Yuksel
 *
 *      Date:
 *          December 24, 1989
 *
 *    Redundancy added to comply with LALR constraint.
 *    Syntax only, no semantic actions.
 * 
 * 
 * *********************************************************/
%nonassoc   DOTDOT;
%left      IMPLIES;
%left      OR OR_ELSE;
%left      XOR;
%left      AND AND_THEN;
%nonassoc   NE EQ LT GT LE GE;
%left      PLUS MINUS;
%left      STAR SLASH MOD DIV;
%right      NOT;
%left      POWER;
%left      OLD;
%left      DOT;
%right      LPARAN;

%start class;
%token      AN_INTEGER;
%token      A_CHAR;
%token      A_REAL;
%token      A_STRING;
%token      AN_ID;
%token      SEMICOLON;
%token      COLON;
%token      COMMA;
%token      DOT;
%token      DOTDOT;
%token      COMM;
%token       LPARAN;
%token       RPARAN;
%token      LCURLY;
%token      RCURLY;
%token      LSQURE;
%token      RSQURE;
%token      CONSTRAIN;

%token      FFALSE TTRUE;
%token      BITS;
%token      BOOLEAN;
%token      CHARACTER;
%token      DOUBLE;
%token      INTEGER;
%token      REAL;

%token      ACCEPT;
%token      ADDRESS;
%token      AS;
%token      ASSIGN;
%token      CHECK;
%token      CLASS;
%token      CLONE;
%token      CREATE;
%token      CURRENT;
%token      DEBUGG;
%token      DEFERRED;
%token      DEFINE;
%token      DO;
%token      ELSE;
%token      ELSIF;
%token      END;
%token      ENSURE;
%token      EXPANDED;
%token      EXPORT;
%token      EXTE;
%token      FEATURE;
%token      FORGET;
%token      FROM;
%token      IF;
%token      INDEXING;
%token      INFIX;
%token      INHERIT;
%token      INSPECT;
%token      INVARIANT;
%token      IS;
%token      LANGUAGE;
%token      LIKE;
%token      LOCAL;
%token      LOOP;
%token      NAME;
%token      NOCHANGE;
%token      OBSOLETE;
%token      ONCE;
%token      PREFIX;
%token      REDEFINE;
%token      RENAME;
%token      REPEAT;
%token      REQUIRE;
%token      RESCUE;
%token      RESULT;
%token      RETRY;
%token      THEN;
%token      UNIQUE;
%token      UNTIL;
%token      VARIANT;
%token      VOID;
%token      WHEN;

%% 
class:           index class_dec export inherit 
           feature class_invariant class_rescue END endmark
         ;

endmark:        /* empty */
         | SEMICOLON
         ;

index: /* empty */
         | INDEXING identification_list
         ;

identification_list:        labeled_identification_list
         | identification_list SEMICOLON labeled_identification_list
         ;

labeled_identification_list: list_of_index
         | AN_ID COLON list_of_index
         ;

list_of_index: valid_index
         | list_of_index COMMA valid_index
         ;

valid_index: /* empty */
         | AN_ID
         | AN_INTEGER
         ;

class_dec:         class_mark AN_ID generic1 class_obsolete
         ;

class_mark: CLASS
         | DEFERRED CLASS
         ;

generic1:        /* empty */
         | LSQURE generic_list1 RSQURE
         ;

generic_list1:        generic_type1
         | generic_list1 COMMA generic_type1
         | generic_list1 SEMICOLON generic_type1
         | generic_list1 CONSTRAIN type
         ;

generic_type1:        /* empty */
         | AN_ID
         ;

class_obsolete:       /* empty */
         | OBSOLETE class_obsolete_comment
         ;

class_obsolete_comment:     /* empty */
         | A_STRING
         ;   
          
export:        /* empty */ 
         | EXPORT export_name_list
         ;

export_name_list:        export_item
         | export_name_list COMMA export_item
         ;

export_item:        /* empty */
         | feature_name 
         | feature_name LCURLY export_class_list RCURLY 
         | REPEAT AN_ID
         ;

feature_name:      AN_ID
         | PREFIX prefix_operator
         | INFIX  infix_operator
         ;

prefix_operator:   A_STRING
         ;

infix_operator:    A_STRING
         ;
   
export_class_list:     AN_ID
         | export_class_list COMMA AN_ID
         ;

inherit:        /* empty */
         | INHERIT inherit_list
         ;

inherit_list:        inherit_dec
         | inherit_list SEMICOLON inherit_dec
         ;

inherit_dec:       /* empty */
         | AN_ID generic2
               rename change_list
         ;

change_list: /* empty */
         | redefine change_list
         | define change_list
         ;

rename:        /* empty */
         | RENAME rename_list
         ;

rename_list:        rename_dec
         | rename_list COMMA rename_dec
         ;

rename_dec:        feature_name AS feature_name
         | CREATE AS AN_ID
         ;

redefine:   REDEFINE redefine_list
         ;

redefine_list:        redefine_item
         | redefine_list COMMA redefine_item
         ;

redefine_item:        /* empty */
         | feature_name
         ;

define   :  DEFINE define_list
         ;

define_list:       define_item
         |  define_list COMMA define_item
         ;

define_item: /* empty */
         |  AN_ID
         | PREFIX prefix_operator
         | INFIX  infix_operator
         ;

feature:        /* empty */
         | FEATURE  feature_list
         ;

feature_list:        feature_dec 
         | feature_list SEMICOLON feature_dec 
         ;

feature_dec:        /* empty */
         | feature_name arguments maybetype obsolete what_feature
         | AN_ID COMMA list_of_attributes COLON type is_unique
         | CREATE arguments what_feature
         ;

list_of_attributes:     list_of_identifiers
         ;

list_of_identifiers:     AN_ID
         | list_of_identifiers COMMA AN_ID
         ;

arguments:        /* empty */
         | LPARAN type_decs RPARAN
         ;

maybetype:        /* empty */  
         | COLON type
         ;

is_unique:      /* empty */
         | IS UNIQUE
         ; 

type_decs:        type_dec
         | type_decs SEMICOLON type_dec
         | type_decs COMMA type_dec
         ;

type_dec:        /*empty */
         | list_of_identifiers COLON type
         ;

type:           basic_type
         | maybe_expanded class_type
         | BITS AN_INTEGER
         | LIKE AN_ID
         | LIKE CURRENT
         ;

basic_type:        INTEGER 
         | REAL
         | BOOLEAN
         | CHARACTER
         | DOUBLE
         ;

maybe_expanded:  /* empty */
         |  EXPANDED
         ;

class_type:         AN_ID generic2
         ;

generic2:        /* empty */
         | LSQURE   generic_list2 RSQURE
         ;

generic_list2:        generic_type2
         | generic_list2 COMMA generic_type2
         | generic_list2 SEMICOLON generic_type2
         ;

generic_type2:        /* empty */
         | type 
         ;

obsolete:       /* empty */
         | OBSOLETE obsolete_comment
         ;

obsolete_comment:     /* empty */
         | A_STRING
         ;

what_feature:        /* empty */
         | IS c_value
         | IS A_STRING
         | IS UNIQUE
         | routine
         ;

routine:        IS require body ensure routine_rescue END
         ;

body:           external_part local do 
         | DEFERRED
         ;

require:        /* empty */
         | REQUIRE boolean_list 
         ;

external_part:           /* empty */
         | EXTE external_list 
         ;

external_list:        external_declaration 
         | external_list SEMICOLON external_declaration
         ;

external_declaration:        /* empty */
         | AN_ID maybeargument maybetype
            optional_c_name LANGUAGE A_STRING 
         ;

maybeargument:      /* empty   */
         | LPARAN arguments_list RPARAN
         ;

list_of_identifiers2:  AN_ID
         | list_of_identifiers2 COMMA AN_ID
         ;

arguments_list:    argument_list
         | arguments_list COMMA argument_list
         | arguments_list SEMICOLON argument_list
         ;

argument_list:     list_of_identifiers2 COLON a_type
         ;
 
a_type:       AN_ID
         | LIKE AN_ID
         | LIKE CURRENT
         | INTEGER
         | CHARACTER
         | BOOLEAN
         | REAL 
         | DOUBLE
         | BITS AN_INTEGER
         ;

optional_c_name:         /*empty */
         | NAME A_STRING
         ;

local:           /* empty */
         | LOCAL type_decs 
         ;

do:           DO instruction_list
         | ONCE instruction_list
         ;

instruction:         /* empty instruction   */
         | conditional
         | assignment
         | feature_call
         | loop 
         | CHECK boolean_expr_list END
         | DEBUGG instruction_list END
         | RETRY
         | inspect_instruction
         ;

instruction_list:        instruction 
         | instruction_list SEMICOLON instruction
         ;

interval_bound:        feature_call
         | sign AN_INTEGER
         | A_CHAR
         ;
   
interval:  interval_bound
         | sign AN_INTEGER DOTDOT sign AN_INTEGER
         | sign AN_INTEGER DOTDOT feature_call
         | A_CHAR DOTDOT A_CHAR
         | A_CHAR DOTDOT feature_call
         | feature_call DOTDOT interval_bound
         ;
   
sign:      /* empty */
         | PLUS
         | MINUS
         ;

interval_list:      interval
         | interval_list COMMA interval
         ;
 
inspect_instruction:       INSPECT expression case_list else_case END
         ;
   
case_list:       /* empty */
         | case_list WHEN interval_list THEN instruction_list
         ;
 
else_case:      /* empty */
         | ELSE instruction_list
         ;
 
conditional:        IF boolean_expr THEN instruction_list elsif_list else END 
         ;

elsif_list:        /* empty */
         | elsif_list ELSIF boolean_expr THEN instruction_list
         ;

else:           /* empty */
         | ELSE instruction_list
         ;

loop:   FROM instruction_list 
			invariant variant 
			UNTIL boolean_expr 
			LOOP instruction_list 
			END 
         ;

assignment:        AN_ID ASSIGN expression 
         | RESULT ASSIGN expression
         | AN_ID ACCEPT expression
         | RESULT ACCEPT expression
         ;

ensure:        /* empty */
         | ENSURE boolean_expr_list
         ;

invariant:        /* empty */
         | INVARIANT boolean_expr_list
         ;

class_invariant:  /* empty */
         | INVARIANT boolean_expr_list
         ;

boolean_expr_list:     boolean_list 
         ;

boolean_list:          labeled_boolean_expr
         | boolean_list COMMA labeled_boolean_expr
         | boolean_list SEMICOLON labeled_boolean_expr
         ;

labeled_boolean_expr:     /* empty */
         | AN_ID COLON boolean_expr
         | boolean_expr
         ;

expression:           value  
         | A_STRING 
         | feature_call 
         | LPARAN expression RPARAN 
         | expression PLUS expression
         | expression MINUS expression
         | expression STAR expression
         | expression SLASH expression 
         | expression MOD expression
         | expression DIV expression 
         | expression POWER expression
         | expression AND expression
         | expression AND_THEN expression
         | expression OR expression
         | expression OR_ELSE expression 
         | expression IMPLIES expression
         | expression XOR expression
         | MINUS expression %prec NOT
         | PLUS  expression %prec NOT
         | OLD expression
         | NOCHANGE;
         | NOT expression
         | expression GE expression
         | expression LE expression
         | expression GT expression
         | expression LT expression
         | expression EQ expression
         | expression NE expression
         | ADDRESS AN_ID
         ;

boolean_expr:        expression 
         ;


boolean_value:        FFALSE
         | TTRUE
         ;

number_value:        AN_INTEGER
         | A_REAL
         ;

value :        number_value
         | boolean_value 
         | A_CHAR
         ;

c_value:        value
         | MINUS number_value 
         | PLUS number_value 
         ;

feature_call:        CURRENT
         | CURRENT DOT multidot
         | RESULT 
         | RESULT DOT multidot
         | multidot
         ;

multidot:        a_feature 
         | predefined_routine 
         | a_feature DOT multidot
         ;
         
a_feature:        AN_ID parameter_list 
         ;

predefined_routine:        CREATE parameter_list 
         | CLONE paran_expr
         | VOID
         | FORGET
         ;

paran_expr:        LPARAN expression RPARAN
         ;

parameter_list:     /* empty */ 
         | LPARAN RPARAN  
         | LPARAN expression_list RPARAN
         ;

expression_list:        expression
         | expression_list COMMA expression
         ;

variant:        /* empty */
         | VARIANT
         | VARIANT expression
         | VARIANT AN_ID COLON expression
         ;

class_rescue:         /* empty */
            | RESCUE instruction_list
            ;

routine_rescue:         /* empty */
            | RESCUE instruction_list 
            ;
===================== CUT HERE ================================
/*
 *                 FILE: eiffel_scanner.c
 *
 *   Scanner driver program for Eiffel Lex and Yacc descriptions.
 *   Author: Jean-Marc Nerson, Interactive Software Engineering, Inc.
 *   Date: December 24, 1989.
 */

#include <stdio.h>
extern yyparse();
char *file_name;

/* 
 * Required by yacc 
 */
yyerror (s)
char *s;
{
   extern int yylineno;

   fprintf (stderr, "Eiffel class file: %s: %s, line: %d\n", file_name, s, yylineno);
}

/* 
 * Required by yacc 
 */
int yywrap ()
{
   return (1);
}

main (argc, argv)
int argc;
char *argv [];
{
   extern FILE *yyin;
   
   file_name = argv [1];
	if (!file_name) {
		fprintf (stderr, "Usage: eiffel_scanner eiffel_class_file.e\n");
		return (-1);
	}
   yyin = fopen (file_name, "r");
	if (yyin) yyparse ();
	else fprintf (stderr, "Eiffel class file: %s: not found\n", file_name);
   fclose (yyin);
   return (0);
}

===================== CUT HERE ================================
#
# Makefile
# Compile Eiffel Yacc and Lex descriptions with driver program
# Author: Jean-Marc Nerson, Interactive Software Engineering, Inc.
# Date: December 24, 1989
# 

CC= cc
CFLAGS= -O
YFLAGS=-d
OBJECTS=  y.tab.o eiffel.o eiffel_scanner.o

eiffel_scanner: $(OBJECTS)
	cc $(CFLAGS) -o $@ $(OBJECTS)

y.tab.h: y.tab.c

y.tab.c: eiffel.y
	yacc $(YFLAGS) eiffel.y
	cc $(CFLAGS) -c y.tab.c

eiffel.c: eiffel.l y.tab.h


======================== CUT HERE AS WELL =============================


I hope this is usefull for you. 

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

Rindert Schutten

ty@palmetto.cis.ufl.edu (Tyng-Jing Yang) (07/07/90)

Hi,
	I tried to compile this eiffel_scanner
and I got the folloing compiling error  message.

Please give me some pointer.
Thanks in advance

Tyng-Jing Yang.
------------------------------------------------------------------------------
make -k
cc -O  -sun3 -c  y.tab.c
cc -O  -sun3 -c  eiffel.c
cc -O  -sun3 -c  eiffel_scanner.c
cc -O -o eiffel_scanner y.tab.o eiffel.o eiffel_scanner.o
ld: Undefined symbol 
   _yyparse 
*** Error code 1
make: Warning: Target `eiffel_scanner' not remade because of errors

Compilation finished at Fri Jul  6 13:13:37
--------------------------------------------------------------------
--
============================
  === Tyng-Jing Yang ===
============================

erradi@IRO.UMontreal.CA (Erradi Mohamed) (07/17/90)

I'm looking for references about testing object oriented systems. Your help
will be very appreciated.

thanks in advance. 

E-mail: erradi@iro.umontreal.ca

tom@opera.chorus.fr (Michel Tombroff) (10/31/90)

Hi all,

is there a formal and complete description of Eiffel grammar available.
I remember ( some time ago ) of such a posting in comp.lang.eiffel,
but I have lost the reference.

Could anybody send me that, if it exists.

Thanks,


Michel Tombroff

Email: tom@chorus.fr