fixed problems with declaration syntax
authoreck <none@none>
Mon, 3 Sep 1990 13:46:30 +0000 (13:46 +0000)
committereck <none@none>
Mon, 3 Sep 1990 13:46:30 +0000 (13:46 +0000)
lang/cem/cemcom.ansi/declar.g
lang/cem/cemcom.ansi/domacro.c
lang/cem/cemcom.ansi/label.c

index 4848cbb..c15f204 100644 (file)
@@ -67,43 +67,38 @@ declaration
                short typedef yepp;
        makes all hope of writing a specific grammar for typedefs illusory.
 */
-/*     We do not accept the whole of the grammar, since when we see
-       something like 'unsigned plain' (where plain is a typedef) is
-       illegal if 'plain' is a typedef.  Therefore, we assume that
-       'plain' is the identifier of a declarator.  Unfortunately, this
-       causes declarations like 'unsigned plain x;' to be rejected on the
-       grounds of syntax, even though it is syntactically right.  This may
-       cause a lot of extra messages.
-       To do this, decl_specifiers is divided into:
-       1: normal specifiers == storage class specifiers + type_qualifiers
-       2: special specifiers == short + long + signed + unsigned
-       3: basic types == void + char + int + float + double
-       4: single type specifiers == struct or union specifiers
-                                   + enum specifiers + typedef names
+/*     Accept a single declaration specifier.  Then accept zero or more
+       type-specifiers.  There can be a conflict on both TYPE_IDENTIFIER
+       and IDENTIFIER.
+       The following rule is used:
+       When we see a TYPE_IDENTIFIER, we accept it if no type-specifier
+       was given, and it is not directly followed by an identifier.
+       If no type-dpecifier was given, it is taken as the identifier being
+       declared.  If it is followed by an identifier, we assume that an
+       error has been  made, (e.g. unsigned typedeffed_int x;) and that
+       this will be detected later on.
+       When we see an IDENTIFIER, directly followed by another IDENTIFIER,
+       we assume that a typing mistake has been made, and we accept it as
+       an erroneous type-identifier.
+*/
 
- */
 decl_specifiers        /* non-empty */ (register struct decspecs *ds;)
        /*      Reads a non-empty decl_specifiers and fills the struct
                decspecs *ds.
        */
 :
-[ %if (AHEAD == IDENTIFIER)                    /* like: register i; */
-       normal_specifier(ds)
-|
-       normal_specifier(ds)*
-       [       special_specifier(ds)
-       |       basic_type(ds)
-       |       single_type_specifier(ds)
-       ]
-       [       normal_specifier(ds)
-       |       special_specifier(ds)
-       |       basic_type(ds)
+       single_decl_specifier(ds)
+       [ %while(  (DOT==TYPE_IDENTIFIER
+                       && ds->ds_size == 0
+                       && ds->ds_unsigned == 0
+                       && ds->ds_type == (struct type *)0)
+                   || AHEAD == IDENTIFIER)     /* always an error */
+               single_decl_specifier(ds)
        ]*
-]
        {do_decspecs(ds);}
 ;
 
-normal_specifier(register struct decspecs *ds;)
+single_decl_specifier /* non_empty */ (register struct decspecs *ds;)
 :
        [ AUTO | STATIC | EXTERN | TYPEDEF | REGISTER ]
        {       if (ds->ds_sc_given)
@@ -112,28 +107,18 @@ normal_specifier(register struct decspecs *ds;)
                ds->ds_sc = DOT;
        }
 |
-       /*      This qualifier applies to the top type.
-               E.g. volatile float * is a pointer to volatile float.
-       */
        VOLATILE
        {       if (ds->ds_typequal & TQ_VOLATILE)
                        error("repeated type qualifier");
                ds->ds_typequal |= TQ_VOLATILE;
        }
 |
-       /*      This qualifier applies to the top type.
-               E.g. volatile float * is a pointer to volatile float.
-       */
        CONST
-       {
-               if (ds->ds_typequal & TQ_CONST)
+       {       if (ds->ds_typequal & TQ_CONST)
                        error("repeated type qualifier");
                ds->ds_typequal |= TQ_CONST;
        }
-;
-
-special_specifier(register struct decspecs *ds;)
-:
+|
        [ SHORT | LONG ]
        {       if (ds->ds_size)
                        error("repeated size specifier");
@@ -145,35 +130,14 @@ special_specifier(register struct decspecs *ds;)
                        error("repeated sign specifier");
                ds->ds_unsigned = DOT;
        }
-;
-
-/* 3.5.2 */
-type_specifier(struct type **tpp;)
-       /*      Used in struct/union declarations and in casts; only the
-               type is relevant.
-       */
-       {struct decspecs Ds; Ds = null_decspecs;}
-:
-       decl_specifiers(&Ds)
-       {
-               if (Ds.ds_sc_given)
-                       error("storage class ignored");
-               if (Ds.ds_sc == REGISTER)
-                       error("register ignored");
-       }
-       {*tpp = Ds.ds_type;}
-;
-
-basic_type(register struct decspecs *ds;):
+|
        [ VOID | CHAR | INT | FLOAT | DOUBLE ]
        {
                idf2type(dot.tk_idf, &ds->ds_type);
                ds->ds_typedef = 0;
        }
-;
-
-single_type_specifier(register struct decspecs *ds;):
-       %default TYPE_IDENTIFIER        /* this includes INT, CHAR, etc. */
+|
+       %default TYPE_IDENTIFIER
        {
                idf2type(dot.tk_idf, &ds->ds_type);
                ds->ds_typedef = 1;
@@ -194,6 +158,23 @@ single_type_specifier(register struct decspecs *ds;):
        enum_specifier(&ds->ds_type)
 ;
 
+/* 3.5.2 */
+type_specifier(struct type **tpp;)
+       /*      Used in struct/union declarations and in casts; only the
+               type is relevant.
+       */
+       {struct decspecs Ds; Ds = null_decspecs;}
+:
+       decl_specifiers(&Ds)
+       {
+               if (Ds.ds_sc_given)
+                       error("storage class ignored");
+               if (Ds.ds_sc == REGISTER)
+                       error("register ignored");
+       }
+       {*tpp = Ds.ds_type;}
+;
+
 /* 3.5 */
 init_declarator_list(struct decspecs *ds;):
        init_declarator(ds)
index cc075f9..28d8473 100644 (file)
@@ -195,6 +195,17 @@ int to_endif;
                */
                switch(tk.tk_idf->id_resmac) {
                default:
+               case K_UNKNOWN:
+                       /* invalid word seen after the '#'      */
+                       lexerror("%s: unknown control", tk.tk_idf->id_text);
+                       /* fallthrough */
+               case K_DEFINE:
+               case K_ERROR:
+               case K_INCLUDE:
+               case K_LINE:
+               case K_PRAGMA:
+               case K_UNDEF:
+               case K_FILE:
                        SkipToNewLine();
                        break;
                case K_IF:
index 90b6a89..e975f42 100644 (file)
@@ -41,8 +41,8 @@ enter_label(idf, defining)
        }
        else    {
                add_def(idf, LABEL, label_type, L_LOCAL);
-               def = idf->id_def;
        }
+       def = idf->id_def;      /* might be changed by 1 of the 2 add_defs */
        if (def->df_address == 0)
                def->df_address = (arith) text_label();
        if (defining)