www.pudn.com > cppcc.rar > ansi_c.cg
/* -*-c++-*- */
/*
* File: ansi_c.cg
* $Id: ansi_c.cg,v 1.4 2002/07/09 03:04:58 alec Exp $
*
* Author: Alec Panoviciu (alecu@email.com)
*
* Comments:
*
* Revision history:
*
* $Log: ansi_c.cg,v $
* Revision 1.4 2002/07/09 03:04:58 alec
* OWN_STRINGS bu*beep*it finally vanished
* gcc 3.1&mingw - related cleanups
*
* Revision 1.3 2002/06/23 23:47:59 alec
* sync
*
* Revision 1.2 2002/06/05 21:44:44 alec
* release-ready
*
* Revision 1.1 2002/05/31 12:15:47 alec
* *** empty log message ***
*
*/
/*
* This file is Public Domain software. Use it as you wish and in good
* health.
*/
/*
* This grammar is (hopefully) ANSI-C, based on Jeff Lee's (gatech!jeff
* jeff@gatech jeff%gatech.CSNet@CSNet-Relay.ARPA) YACC one (which is in its
* turn based on the April '85 draft of the standard).
*/
OPTIONS
{
// DEBUG_SCANNER = true
// DEBUG_PARSER = true
// OWN_STRINGS = true; DEPRECATED !
PROFILING_FILE = "profile.dat";
}
TOKEN CToken
{}
{
// probably tis will only compile if you are using the SGI STL.
// if you don't have the hash_set extension, look for something simmilar in
// your own STL and replace this stuff
#include
#if defined __GNUC__
#if __GNUC__ >= 3
#include
#include
using __gnu_cxx::hash;
using __gnu_cxx::hash_set;
#else
#include
#endif
#else
#error "No implementation for hash_map provided for this platoform, please replace this line with an appropriate one."
#endif
using namespace std;
}
SCANNER CScanner
{
SKIP
{
{ newLine(); }
}
MORE
{
{ pushState(LONG_COMMENT); }
}
MORE
{
{ newLine(); }
{ newLine(); }
}
SKIP
{
{ popState(); }
}
/* THE KEYWORDS */
KEYWORD
{
}
/* CONSTANT LITERALS */
TOKEN
{
<#D: ['0'-'9'] >
<#L: ['a'-'z', 'A'-'Z', '_'] >
<#H: ['a'-'f', 'A'-'F', '0'-'9'] >
<#E: ['E', 'e']['+', '-']?+ >
<#FS: ['f', 'F', 'l', 'L'] >
<#IS: ['u', 'U', 'l', 'L']* >
<#SIMPLE_ESCAPE: ['a','b','f','n','r','t','v','\'','\"','\\','?'] >
<#OCTAL_ESCAPE: ['0'-'7'] (['0'-'7'] ['0'-'7']?)? >
<#HEX_ESCAPE: "x"['0'-'9', 'a'-'f', 'A'-'F']+ >
<#ESCAPE_SEQ: "\\"(||) >
+? >
+? >
+? >
)+"\'" >
)* "\"" >
}
/* IDENTIFIERS */
TOKEN
{
(|)* >
{
if (typeNames.find(token->image().c_str()) != typeNames.end())
token->id = CToken::TYPE_NAME;
}
}
SPECIAL { TYPE_NAME }
KEYWORD // these aren't really keywords, of course, it's just that we
// don't need the scanner to duplicate their images
{
>=" >
>" >
" >
=" >
" >
}
{
public:
void addType (const string &typeName)
{
typeNames.insert(strdup(typeName.c_str()));
}
private:
struct t_strCmp
{
bool operator () (const char *s1, const char *s2) const
{
return strcmp(s1, s2) == 0;
}
};
hash_set, t_strCmp> typeNames;
}
} // end of scanner
PARSER CParser
{
/* EXPRESSIONS */
() primaryExpr ()
{
| constant() | expr()
}
() postfixExpr ()
{
primaryExpr() postfixOperator()*
}
() postfixOperator ()
{
expr()
| argumentExprList() ?
| identifier()
| identifier()
|
|
}
() argumentExprList ()
{
assignmentExpr() ( assignmentExpr() )*
}
() unaryExpr ()
{
postfixExpr()
| unaryExpr()
| unaryExpr()
| unaryOperator() castExpr()
| ( LOOKAHEAD( typeSpecifier())
( typeName() )
| unaryExpr() )
}
() unaryOperator ()
{
| | | | |
}
() castExpr ()
{
LOOKAHEAD( typeSpecifier())
( typeName() castExpr() )
| unaryExpr()
}
() multiplicativeExpr ()
{
castExpr() ( multiplicativeOperator() castExpr() ) *
}
() multiplicativeOperator ()
{
| |
}
() additiveExpr ()
{
multiplicativeExpr () ( additiveOperator() multiplicativeExpr() ) *
}
() additiveOperator ()
{
|
}
() shiftExpr ()
{
additiveExpr() ( shiftOperator() additiveExpr() ) *
}
() shiftOperator ()
{
|
}
() relationalExpr ()
{
shiftExpr() ( relationalOperator() shiftExpr() ) *
}
() relationalOperator ()
{
| | |
}
() equalityExpr ()
{
relationalExpr() ( equalityOperator() relationalExpr() ) *
}
() equalityOperator ()
{
|
}
() andExpr ()
{
equalityExpr() ( equalityExpr() ) *
}
() exclusiveOrExpr ()
{
andExpr() ( andExpr() ) *
}
() inclusiveOrExpr ()
{
exclusiveOrExpr() ( exclusiveOrExpr() ) *
}
() logicalAndExpr ()
{
inclusiveOrExpr() ( inclusiveOrExpr() ) *
}
() logicalOrExpr ()
{
logicalAndExpr() ( logicalAndExpr() ) *
}
() conditionalExpr ()
{
logicalOrExpr() ( logicalOrExpr() logicalOrExpr() ) ?
}
() assignmentExpr ()
{
// ok , i know this is ridiculous, but otherwise id need a lookahead.
// the correct grammar here only accepts unaryExpression as a lvalue.
// however, since a lvalue check is needed anyway, why not just put the
// conditionalExpression and do the check afterwards.
conditionalExpr() ( assignmentOperator() conditionalExpr() ) *
}
() assignmentOperator ()
{
| | |
| | | |
| | |
}
() expr ()
{
assignmentExpr() ( assignmentExpr() ) *
}
() constantExpr ()
{
conditionalExpr()
}
/* DECLARATIONS */
() declaration ()
{
{ bool isType; }
isType = declarationSpecifiers()
( initDeclarator(isType) ( initDeclarator(isType) ) * ) ?
}
(bool) declarationSpecifiers ()
{
{ bool isType = false; }
( isType = storageClassSpecifier() | typeSpecifier() ) *
{ return isType; }
}
() initDeclarator (bool isType)
{
declarator(isType) ( initializer() ) ?
}
(bool) storageClassSpecifier ()
{
{ bool isType = false; }
( {isType = true;} | | | | )
{ return isType; }
}
() typeSpecifier ()
{
| | | | |
| | | | |
| structOrUnionSpecifier()
| enumSpecifier()
|
}
() structOrUnionSpecifier ()
{
( | )
( identifier() ( structDeclaration()+ ) ?
| structDeclaration()+
)
}
() structDeclaration ()
{
typeSpecifier()+ structDeclarator() ( structDeclarator() ) *
}
() structDeclarator ()
{
declarator(false) ( constantExpr() ) ?
| constantExpr()
}
() enumSpecifier ()
{
( identifier() ( enumeratorList() ) ?
| enumeratorList()
)
}
() enumeratorList ()
{
enumerator() ( enumerator() ) *
}
() enumerator ()
{
identifier() ( constantExpr() ) ?
}
() declarator (bool isType)
{
pointer() ?
(
{
if (isType > 0)
{
scanner.addType(token->image());
// cerr << "GOT A TYPE !!!! " << token->image << endl;
}
}
| declarator(isType) )
(LOOKAHEAD( | (typeSpecifier() | ) ?) (
constantExpr() ?
| ( parameterTypeList() | parameterIdentifierList() ) ?
))*
}
() pointer ()
{
( typeSpecifier()* )+
}
() parameterIdentifierList ()
{
identifierList() ( ) ?
}
() parameterTypeList ()
{
parameterList() ( ) ?
}
() identifierList ()
{
(LOOKAHEAD(2) ( )) *
}
() parameterList ()
{
parameterDeclaration()
( LOOKAHEAD(2) ( parameterDeclaration() ) ) *
}
() parameterDeclaration ()
{
typeSpecifier()+ ( LOOKAHEAD(declarator()) declarator(false)
| abstractDeclarator() ) ?
}
() typeName ()
{
typeSpecifier()+ abstractDeclarator()?
}
() abstractDeclarator ()
{
pointer()?
( ( abstractDeclarator() | parameterTypeList() ) ?
| constantExpr()?
) *
}
() initializer ()
{
assignmentExpr()
| initializer()
( initializer()? )*
}
/* STATEMENTS */
() statement ()
{
LOOKAHEAD(2) labeledStatement()
| ( compoundStatement()
| expressionStatement()
| selectionStatement()
| iterationStatement()
| jumpStatement()
)
}
() labeledStatement ()
{
identifier() statement()
| constantExpr() statement()
| statement()
}
() compoundStatement ()
{
(LOOKAHEAD(declaration()) declaration())* statement()*
}
() expressionStatement ()
{
expr() ?
}
() selectionStatement ()
{
expr() statement() ( statement() ) ?
| expr() statement()
}
() iterationStatement ()
{
expr() statement()
|