⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpp5.y

📁 用于lex和yacc的c++及c语言的文法,可用来构造C++语言的编译器
💻 Y
📖 第 1 页 / 共 5 页
字号:
%{

    /* Copyright (C) 1989-1991 James A. Roskind, All rights reserved. 
    This grammar was developed  and  written  by  James  A.  Roskind. 
    Copying  of  this  grammar  description, as a whole, is permitted 
    providing this notice is intact and applicable  in  all  complete 
    copies.   Translations as a whole to other parser generator input 
    languages  (or  grammar  description  languages)   is   permitted 
    provided  that  this  notice is intact and applicable in all such 
    copies,  along  with  a  disclaimer  that  the  contents  are   a 
    translation.   The reproduction of derived text, such as modified 
    versions of this grammar, or the output of parser generators,  is 
    permitted,  provided  the  resulting  work includes the copyright 
    notice "Portions Copyright (c)  1989,  1990  James  A.  Roskind". 
    Derived products, such as compilers, translators, browsers, etc., 
    that  use  this  grammar,  must also provide the notice "Portions 
    Copyright  (c)  1989,  1990  James  A.  Roskind"  in   a   manner 
    appropriate  to  the  utility,  and in keeping with copyright law 
    (e.g.: EITHER displayed when first invoked/executed; OR displayed 
    continuously on display terminal; OR via placement in the  object 
    code  in  form  readable in a printout, with or near the title of 
    the work, or at the end of the file).  No royalties, licenses  or 
    commissions  of  any  kind are required to copy this grammar, its 
    translations, or derivative products, when the copies are made in 
    compliance with this notice. Persons or corporations that do make 
    copies in compliance with this notice may charge  whatever  price 
    is  agreeable  to  a  buyer, for such copies or derivative works. 
    THIS GRAMMAR IS PROVIDED ``AS IS'' AND  WITHOUT  ANY  EXPRESS  OR 
    IMPLIED  WARRANTIES,  INCLUDING,  WITHOUT LIMITATION, THE IMPLIED 
    WARRANTIES  OF  MERCHANTABILITY  AND  FITNESS  FOR  A  PARTICULAR 
    PURPOSE.

    James A. Roskind
    Independent Consultant
    516 Latania Palm Drive
    Indialantic FL, 32903
    (407)729-4348
    jar@hq.ileaf.com


    ---end of copyright notice---

MOTIVATION-

My  goal  is  to  see  software  developers  adopt  this grammar as a 
standard until such time as a better  standard  is  accessible.   The 
only  way  to  get it to become a standard, is to be sure that people 
know that derivations are based on a specific work.   The  intent  of 
releasing  this  grammar is to provide a publicly accessible standard 
grammar for C++.  The intent of the  copyright  notice  is  to  allow 
arbitrary  commercial  and non-commercial use of the grammar, as long 
as reference is given to the original standard.  Without reference to 
a specific standard, many alternative  grammars  would  develop.   By 
referring  to  the  standard,  this grammar is given publicity, which 
should lead to further use in compatible products and  systems.   The 
benefits  of  such  a  standard  to  commercial  products  (browsers, 
beautifiers, translators, compilers, ...) should be  obvious  to  the 
developers,  in  that  other compatible products will emerge, and the 
value of all conforming products  will  rise.   Most  developers  are 
aware  of  the  value  of  acquiring  a fairly complete grammar for a 
language, and the copyright notice  (and  the  resulting  affiliation 
with my work) should not be too high a price to pay.  By copyrighting 
this  grammar,  I have some minor control over what this standard is, 
and I can (hopefully) keep it from degrading without my approval.   I 
will  consistently  attempt  to  provide  upgraded  grammars that are 
compliant  with  the  current  art,  and  the  ANSI   C++   Committee 
recommendation  in  particular.   A developer is never prevented from 
modifying the grammar to improve it in  whatever  way  is  seen  fit.  
There  is  also  no  restriction on the sale of copies, or derivative 
works, providing the requests in the copyright notice are satisfied.

If you are not "copying" my work, but  are  rather  only  abstracting 
some  of  the  standard,  an acknowledgment with references to such a 
standard would be appreciated.  Specifically,  agreements  with  this 
standard  as  to  the  resolution  of otherwise ambiguous constructs, 
should be noted.

Simply put: "make whatever use you would like  of  the  grammar,  but 
include  the  ``portions  Copyright  ...''  as  a  reference  to this 
standard."


*/


/* Last modified 7/4/91, Version 2.0  */

/* File CPP5.Y is translated by YACC to Y.TAB.C */

/*  ACKNOWLEDGMENT: Without Bjarne Stroustrup and his many co-workers 
at Bell Labs, there would be no C++ Language for which to  provide  a 
syntax  description. Bjarne has also been especially helpful and open 
in discussions, and by permitting me to review  his  texts  prior  to 
their publication, allowed me a wonderful vantage point of clarity.

Without  the effort expended by the ANSI C standardizing committee, I 
would have been lost.  Although the ANSI C standard does not  include 
a  fully disambiguated syntax description, the committee has at least 
provided most of the disambiguating rules in  narratives.   This  C++ 
grammar  is intended to be a superset of an ANSI C compatible grammar 
that is provided in an related file.

Several reviewers have also  recently  critiqued  this  grammar,  the 
related  C  grammar,  and  or  assisted  in  discussions  during it's 
preparation.  These reviewers are certainly not responsible  for  the 
errors  I  have committed here, but they are responsible for allowing 
me  to  provide  fewer  errors.   These  colleagues  include:   Bruce 
Blodgett,  Mark Langley, Joe Fialli, Greg Perkins, Ron Guilmette, and 
Eric Krohn. */

/* Required fixes from last release :

done: 0) Allow direct call to destructors

done: 1) Allow placement of declarations in labeled statements.   The 
easiest  fix involves using a larger variance from the C grammar, and 
simply making "statement" include declarations.  Note that it  should 
also  be  legal  for  declarations  to  be  in  the  branches  of  if 
statements, as long as there is no other code in the block (I think).  
Consider:

        ...
        {
           if (0 == a)
                int b=5;
           else
                int c=4;
         }

1) template support: Not  done:  pending  syntax  specification  from 
ANSI.  (This looks like a major effort, as ANSI has decided to extend 
the  "TYPEDEFname"-feedback-to-the-lexer-hack  to  support   template 
names as a new kind of terminal token.)

2)  exception  handling:  Not done: pending syntax specification from 
ANSI (but it doesn't look hard)

done: 3) Support nested types, including identifier::name,  where  we 
realize  that  identifier was a hidden type.  Force the lexer to keep 
pace in this situation.   This  will  require  an  extension  of  the 
yacc-lex feedback loop.

done: 4) Support nested types even when derivations are used in class 
definitions.

5)  Provide  advanced  tutorial  on  YACC  conflicts:  almost done in 
documentation about machine generated documentation.

done: 6) Allow declaration specifiers to be left out of  declarations 
at file and structure scope so that operator conversion functions can 
be  declared and/or defined.  Note that checking to see that it was a 
function type that does not require declaration_specifiers is  now  a 
constraint  check,  and  not  a  syntax  issue.  Within function body 
scopes, declaration specifiers are required, and this is critical  to 
distinguishing expressions.


*/

%}

/*

Interesting ambiguity:
Usually
        typename ( typename2 ) ...
or
        typename ( typename2 [4] ) ...
etc.
is a redeclaration of typename2.

Inside  a structure elaboration, it is sometimes the declaration of a 
constructor!  Note, this only  counts  if  typename  IS  the  current 
containing  class name. (Note this can't conflict with ANSI C because 
ANSI C would call it a redefinition, but  claim  it  is  semantically 
illegal because you can't have a member declared the same type as the 
containing struct!) Since the ambiguity is only reached when a ';' is 
found,   there  is  no  problem  with  the  fact  that  the  semantic 
interpretation  is  providing  the  true  resolution.   As  currently 
implemented, the constructor semantic actions must be able to process 
an  ordinary  declaration.  I may reverse this in the future, to ease 
semantic implementation.

*/



/*

INTRO TO ANSI C GRAMMAR (provided in a separate file):

The refined grammar resolves several typedef ambiguities in the draft 
proposed ANSI C standard syntax down to 1 shift/reduce  conflict,  as 
reported by a YACC process.  Note that the one shift reduce conflicts 
is  the  traditional  if-if-else conflict that is not resolved by the 
grammar.  This ambiguity can be removed using the method described in 
the Dragon Book (2nd edition), but this does  not  appear  worth  the 
effort.

There  was quite a bit of effort made to reduce the conflicts to this 
level, and an additional effort was made to make  the  grammar  quite 
similar  to  the  C++ grammar being developed in parallel.  Note that 
this grammar resolves the following ANSI C ambiguities:

ANSI C section 3.5.6, "If the [typedef  name]  is  redeclared  at  an 
inner  scope,  the  type specifiers shall not be omitted in the inner 
declaration".  Supplying type specifiers prevents consideration of  T 
as a typedef name in this grammar.  Failure to supply type specifiers 
forced the use of the TYPEDEFname as a type specifier.  This is taken 
to an (unnecessary) extreme by this implementation.  The ambiguity is 
only  a  problem  with  the first declarator in a declaration, but we 
restrict  ALL  declarators  whenever  the  users  fails  to   use   a 
type_specifier.

ANSI C section 3.5.4.3, "In a parameter declaration, a single typedef 
name  in  parentheses  is  taken  to  be  an abstract declarator that 
specifies a function  with  a  single  parameter,  not  as  redundant 
parentheses  around  the  identifier".  This is extended to cover the 
following cases:

typedef float T;
int noo(const (T[5]));
int moo(const (T(int)));
...

Where again the '(' immediately to the left of 'T' is interpreted  as 
being  the  start  of  a  parameter type list, and not as a redundant 
paren around a redeclaration of T.  Hence an equivalent code fragment 
is:

typedef float T;
int noo(const int identifier1 (T identifier2 [5]));
int moo(const int identifier1 (T identifier2 (int identifier3)));
...

*/


%{
/*************** Includes and Defines *****************************/
#define YYDEBUG_LEXER_TEXT (yylval) /* our lexer loads this up each time.
				     We are telling the graphical debugger
				     where to find the spelling of the 
				     tokens.*/
#define YYDEBUG 1        /* get the pretty debugging code to compile*/
#define YYSTYPE  char *  /* interface with flex: should be in header file */

/*************** Standard ytab.c continues here *********************/
%}

/*************************************************************************/


/* This group is used by the C/C++ language parser */
%token AUTO            DOUBLE          INT             STRUCT
%token BREAK           ELSE            LONG            SWITCH
%token CASE            ENUM            REGISTER        TYPEDEF
%token CHAR            EXTERN          RETURN          UNION
%token CONST           FLOAT           SHORT           UNSIGNED
%token CONTINUE        FOR             SIGNED          VOID
%token DEFAULT         GOTO            SIZEOF          VOLATILE
%token DO              IF              STATIC          WHILE

/* The following are used in C++ only.  ANSI C would call these IDENTIFIERs */
%token NEW             DELETE
%token THIS
%token OPERATOR
%token CLASS
%token PUBLIC          PROTECTED       PRIVATE
%token VIRTUAL         FRIEND
%token INLINE          OVERLOAD

/* ANSI C Grammar suggestions */
%token IDENTIFIER              STRINGliteral
%token FLOATINGconstant        INTEGERconstant        CHARACTERconstant
%token OCTALconstant           HEXconstant

/* New Lexical element, whereas ANSI C suggested non-terminal */
%token TYPEDEFname

/* Multi-Character operators */
%token  ARROW            /*    ->                              */
%token  ICR DECR         /*    ++      --                      */
%token  LS RS            /*    <<      >>                      */
%token  LE GE EQ NE      /*    <=      >=      ==      !=      */
%token  ANDAND OROR      /*    &&      ||                      */
%token  ELLIPSIS         /*    ...                             */
                 /* Following are used in C++, not ANSI C        */
%token  CLCL             /*    ::                              */
%token  DOTstar ARROWstar/*    .*       ->*                    */

/* modifying assignment operators */
%token MULTassign  DIVassign    MODassign   /*   *=      /=      %=      */
%token PLUSassign  MINUSassign              /*   +=      -=              */
%token LSassign    RSassign                 /*   <<=     >>=             */
%token ANDassign   ERassign     ORassign    /*   &=      ^=      |=      */

/*************************************************************************/

%start translation_unit

/*************************************************************************/

%%

/*********************** CONSTANTS *********************************/
constant:
        INTEGERconstant
        | FLOATINGconstant
        /*  We  are not including ENUMERATIONconstant here because we 
          are treating it like a variable with a type of "enumeration 
          constant".  */
        | OCTALconstant
        | HEXconstant
        | CHARACTERconstant
        ;

string_literal_list:
                STRINGliteral
                | string_literal_list STRINGliteral
                ;


/************************* EXPRESSIONS ********************************/


    /* Note that I provide  a  "scope_opt_identifier"  that  *cannot* 
    begin  with ::.  This guarantees we have a viable declarator, and 
    helps to disambiguate :: based uses in the grammar.  For example:

            ...
            {
            int (* ::b()); // must be an expression
            int (T::b); // officially a declaration, which fails on constraint grounds

    This *syntax* restriction reflects the current syntax in the ANSI 
    C++ Working Papers.   This  means  that  it  is  *incorrect*  for 
    parsers to misparse the example:

            int (* ::b()); // must be an expression

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -