#ifndef PARSENODE_H #define PARSENODE_H #include #include #include #include #include "lex.h" #include "utility.h" #include "SynTree/SynTree.h" #include "SynTree/Declaration.h" #include "SemanticError.h" #include "UniqueName.h" class ExpressionNode; class CompositeExprNode; class CommaExprNode; class StatementNode; class CompoundStmtNode; class DeclarationNode; class InitializerNode; // Builder class ParseNode { public: // ParseNode(void); ParseNode( std::string, char *filename, int lineno ); virtual ~ParseNode(void); ParseNode *set_name (std::string) ; ParseNode *set_name (std::string *) ; std::string get_name(void); ParseNode *get_link(void) const; ParseNode *get_last(void); ParseNode *set_link(ParseNode *); void set_next( ParseNode *newlink ) { next = newlink; } char *get_filename() const { return filename; } int get_lineno() const { return lineno; } virtual ParseNode *clone() const { return 0; }; const std::string get_name(void) const; virtual void print( std::ostream &, int indent = 0 ) const; virtual void printList( std::ostream &, int indent = 0 ) const; ParseNode &operator,(ParseNode &); protected: std::string name; ParseNode *next; static int indent_by; char *filename; int lineno; }; ParseNode *mkList(ParseNode &); class ExpressionNode : public ParseNode { public: // ExpressionNode(); ExpressionNode( std::string*, char *filename, int lineno ); ExpressionNode( const ExpressionNode &other ); virtual ~ExpressionNode() { /* can't delete asArgName because it might be referenced elsewhere */ }; virtual ExpressionNode *clone() const = 0; virtual CommaExprNode *add_to_list(ExpressionNode *); ExpressionNode *get_argName() const { return argName; } ExpressionNode *set_asArgName( std::string *aName ); ExpressionNode *set_asArgName( ExpressionNode *aDesignator ); virtual void print(std::ostream &, int indent = 0) const = 0; virtual void printOneLine(std::ostream &, int indent = 0) const = 0; virtual Expression *build() const = 0; protected: void printDesignation (std::ostream &, int indent = 0) const; private: ExpressionNode *argName; }; // NullExprNode is used in tuples as a place-holder where a tuple component is omitted // e.g., [ 2, , 3 ] class NullExprNode : public ExpressionNode { public: NullExprNode( char *filename, int lineno ); virtual NullExprNode *clone() const; virtual void print(std::ostream &, int indent = 0) const; virtual void printOneLine(std::ostream &, int indent = 0) const; virtual Expression *build() const; }; class ConstantNode : public ExpressionNode { public: enum Type { Integer, Float, Character, String /* , Range, EnumConstant */ }; ConstantNode(); ConstantNode( struct token & ); ConstantNode( Type, struct token & ); ConstantNode( const ConstantNode &other ); virtual ConstantNode *clone() const { return new ConstantNode( *this ); } Type get_type(void) const ; virtual void print(std::ostream &, int indent = 0) const; virtual void printOneLine(std::ostream &, int indent = 0) const; std::string get_value() const { return value; } ConstantNode *append( std::string *newValue ); Expression *build() const; private: void classify(std::string &); Type type; std::string value; bool sign; short base; int longs, size; }; class VarRefNode : public ExpressionNode { public: VarRefNode(); VarRefNode( struct token &tok, bool isLabel = false ); VarRefNode( const VarRefNode &other ); virtual Expression *build() const ; virtual VarRefNode *clone() const { return new VarRefNode( *this ); } virtual void print(std::ostream &, int indent = 0) const; virtual void printOneLine(std::ostream &, int indent = 0) const; private: bool isLabel; }; class TypeValueNode : public ExpressionNode { public: TypeValueNode(DeclarationNode *); TypeValueNode( const TypeValueNode &other ); DeclarationNode *get_decl() const { return decl; } virtual Expression *build() const ; virtual TypeValueNode *clone() const { return new TypeValueNode( *this ); } virtual void print(std::ostream &, int indent = 0) const; virtual void printOneLine(std::ostream &, int indent = 0) const; private: DeclarationNode *decl; }; class OperatorNode : public ExpressionNode { public: enum Type { TupleC, Comma, TupleFieldSel, Cond, NCond, SizeOf, AlignOf, CompLit, Plus, Minus, Mul, Div, Mod, Or, And, BitOr, BitAnd, Xor, Cast, LShift, RShift, LThan, GThan, LEThan, GEThan, Eq, Neq, Assign, MulAssn, DivAssn, ModAssn, PlusAssn, MinusAssn, LSAssn, RSAssn, AndAssn, ERAssn, OrAssn, Index, FieldSel, PFieldSel, Range, UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost, LabelAddress }; OperatorNode(Type t, char *filename, int lineno); OperatorNode( const OperatorNode &other ); virtual ~OperatorNode(); virtual OperatorNode *clone() const { return new OperatorNode( *this ); } Type get_type(void) const; std::string get_typename(void) const; virtual void print(std::ostream &, int indent = 0) const; virtual void printOneLine(std::ostream &, int indent = 0) const; virtual Expression *build() const { return 0; } private: Type type; static const char *OpName[]; }; class CompositeExprNode : public ExpressionNode { public: // CompositeExprNode(void); CompositeExprNode( struct token & ); CompositeExprNode(ExpressionNode *f, ExpressionNode *args = 0); CompositeExprNode(ExpressionNode *f, ExpressionNode *arg1, ExpressionNode *arg2); CompositeExprNode( const CompositeExprNode &other ); virtual ~CompositeExprNode(); virtual CompositeExprNode *clone() const { return new CompositeExprNode( *this ); } virtual Expression *build() const; virtual void print(std::ostream &, int indent = 0) const; virtual void printOneLine(std::ostream &, int indent = 0) const; void set_function(ExpressionNode *); void set_args(ExpressionNode *); void add_arg(ExpressionNode *); ExpressionNode *get_function() const; ExpressionNode *get_args() const; private: ExpressionNode *function; ExpressionNode *arguments; }; class CommaExprNode : public CompositeExprNode { public: // CommaExprNode(); CommaExprNode(ExpressionNode *); CommaExprNode(ExpressionNode *, ExpressionNode *); CommaExprNode( const CommaExprNode &other ); virtual CommaExprNode *add_to_list(ExpressionNode *); virtual CommaExprNode *clone() const { return new CommaExprNode( *this ); } }; class ForCtlExprNode : public ExpressionNode { public: ForCtlExprNode(ParseNode *, ExpressionNode *, ExpressionNode *) throw (SemanticError); ForCtlExprNode( const ForCtlExprNode &other ); ~ForCtlExprNode(); StatementNode *get_init() const { return init; } ExpressionNode *get_condition() const { return condition; } ExpressionNode *get_change() const { return change; } virtual ForCtlExprNode *clone() const { return new ForCtlExprNode( *this ); } virtual Expression *build() const; virtual void print( std::ostream &, int indent = 0 ) const; virtual void printOneLine( std::ostream &, int indent = 0 ) const; private: StatementNode *init; ExpressionNode *condition; ExpressionNode *change; }; class ValofExprNode : public ExpressionNode { public: // ValofExprNode(); ValofExprNode( StatementNode *s = 0 ); ValofExprNode( const ValofExprNode &other ); ~ValofExprNode(); virtual ValofExprNode *clone() const { return new ValofExprNode( *this ); } StatementNode *get_body() const { return body; } void print( std::ostream &, int indent = 0 ) const; void printOneLine( std::ostream &, int indent = 0 ) const; Expression *ValofExprNode::build() const; private: StatementNode *body; }; class TypeData; class DeclarationNode : public ParseNode { public: enum Qualifier { Const, Restrict, Volatile, Lvalue }; enum StorageClass { Static, Auto, Extern, Register, Inline, Fortran }; enum BasicType { Char, Int, Float, Double, Void, Bool, Complex, Imaginary }; enum Modifier { Signed, Unsigned, Short, Long }; enum TyCon { Struct, Union, Context }; enum TypeClass { Type, Dtype, Ftype }; static const char *qualifierName[]; static const char *basicTypeName[]; static const char *modifierName[]; static const char *tyConName[]; static const char *typeClassName[]; static DeclarationNode *newFunction( struct token &name, DeclarationNode *ret, DeclarationNode *param, StatementNode *body ); static DeclarationNode *newFunction( char *filename, int lineno, DeclarationNode *ret, DeclarationNode *param, StatementNode *body ); static DeclarationNode *newQualifier( Qualifier, char *filename, int lineno ); static DeclarationNode *newStorageClass( StorageClass, char *filename, int lineno ); static DeclarationNode *newBasicType( BasicType, char *filename, int lineno ); static DeclarationNode *newModifier( Modifier, char *filename, int lineno ); static DeclarationNode *newForall( DeclarationNode*, char *filename, int lineno ); static DeclarationNode *newFromTypedef( struct token & ); static DeclarationNode *newAggregate( TyCon kind, char *filename, int lineno, DeclarationNode *formals, ExpressionNode *actuals, DeclarationNode *fields ); static DeclarationNode *newAggregate( TyCon kind, struct token &, DeclarationNode *formals, ExpressionNode *actuals, DeclarationNode *fields ); static DeclarationNode *newEnum( struct token &, DeclarationNode *constants ); static DeclarationNode *newEnum( char *filename, int lineno, DeclarationNode *constants ); static DeclarationNode *newEnumConstant( struct token &name, ExpressionNode *constant ); static DeclarationNode *newName( struct token &tok ); static DeclarationNode *newFromTypeGen( struct token &tok, ExpressionNode *params ); static DeclarationNode *newTypeParam( TypeClass, std::string*, char *filename, int lineno ); static DeclarationNode *newContext( struct token &name, DeclarationNode *params, DeclarationNode *asserts ); static DeclarationNode *newContextUse( struct token &name, ExpressionNode *params ); static DeclarationNode *newTypeDecl( struct token &name, DeclarationNode *typeParams ); static DeclarationNode *newPointer( DeclarationNode *qualifiers, char *filename, int lineno ); static DeclarationNode *newArray( ExpressionNode *size, DeclarationNode *qualifiers, bool isStatic, char *filename, int lineno ); static DeclarationNode *newVarArray( DeclarationNode *qualifiers, char *filename, int lineno ); static DeclarationNode *newBitfield( ExpressionNode *size ); static DeclarationNode *newTuple( DeclarationNode *members, char *filename, int lineno ); static DeclarationNode *newTypeof( ExpressionNode *expr, char *filename, int lineno ); DeclarationNode *addQualifiers( DeclarationNode* ); DeclarationNode *copyStorageClasses( DeclarationNode* ); DeclarationNode *addType( DeclarationNode* ); DeclarationNode *addTypedef(); DeclarationNode *addAssertions( DeclarationNode* ); DeclarationNode *addName( struct token & ); DeclarationNode *addBitfield( ExpressionNode *size ); DeclarationNode *addVarArgs(); DeclarationNode *addFunctionBody( StatementNode *body ); DeclarationNode *addOldDeclList( DeclarationNode *list ); DeclarationNode *addPointer( DeclarationNode *qualifiers ); DeclarationNode *addArray( DeclarationNode *array ); DeclarationNode *addNewPointer( DeclarationNode *pointer ); DeclarationNode *addNewArray( DeclarationNode *array ); DeclarationNode *addParamList( DeclarationNode *list ); DeclarationNode *addIdList( DeclarationNode *list ); // old-style functions DeclarationNode *addInitializer( InitializerNode *init ); DeclarationNode *cloneType( struct token &newName ); DeclarationNode *cloneType( DeclarationNode *existing ); DeclarationNode *cloneBaseType( struct token &newName ); DeclarationNode *cloneBaseType( DeclarationNode *newdecl ); DeclarationNode *appendList( DeclarationNode * ); DeclarationNode *clone() const; void print( std::ostream &, int indent = 0 ) const; void printList( std::ostream &, int indent = 0 ) const; Declaration *build() const; Type *buildType() const; bool get_hasEllipsis() const; std::string get_name() const { return name; } LinkageSpec::Type get_linkage() const { return linkage; } DeclarationNode *extractAggregate() const; DeclarationNode( char *filename, int lineno ); ~DeclarationNode(); private: Declaration::StorageClass buildStorageClass() const; bool buildInline() const; TypeData *type; std::string name; std::list< StorageClass > storageClasses; ExpressionNode *bitfieldWidth; InitializerNode *initializer; bool hasEllipsis; LinkageSpec::Type linkage; static UniqueName anonymous; }; class StatementNode : public ParseNode { public: enum Type { Exp, If, Switch, Case, Default, Choose, Fallthru, While, Do, For, Goto, Continue, Break, Return, Throw, Try, Catch, Asm, Decl }; /// StatementNode( void ); StatementNode( struct token &tok ); StatementNode( char *filename, int lineno ); StatementNode( Type, char *filename, int lineno, ExpressionNode *e = 0, StatementNode *s = 0 ); StatementNode( Type, char *filename, int lineno, std::string *target ); StatementNode( DeclarationNode *decl ); ~StatementNode(void); static StatementNode * newCatchStmt( char *filename, int lineno, DeclarationNode *d = 0, StatementNode *s = 0, bool catchRestP = false ); void set_control(ExpressionNode *); StatementNode * set_block(StatementNode *); ExpressionNode *get_control() const ; StatementNode *get_block() const; StatementNode::Type get_type(void) const; StatementNode *add_label( struct token & ); std::list *get_labels() const; void addDeclaration( DeclarationNode *newDecl ) { decl = newDecl; } void setCatchRest( bool newVal ) { isCatchRest = newVal; } std::string get_target() const; StatementNode *add_controlexp(ExpressionNode *); StatementNode *append_block(StatementNode *); StatementNode *append_last_case(StatementNode *); void print( std::ostream &, int indent = 0) const; virtual StatementNode *clone() const; virtual Statement *build() const; private: static const char *StType[]; Type type; ExpressionNode *control; StatementNode *block; std::list *labels; std::string *target; // target label for jump statements DeclarationNode *decl; bool isCatchRest; }; class CompoundStmtNode : public StatementNode { public: // CompoundStmtNode(void); CompoundStmtNode( struct token & ); CompoundStmtNode( char *filename, int lineno ); CompoundStmtNode(StatementNode *); ~CompoundStmtNode(); void add_statement(StatementNode *); void print( std::ostream &, int indent = 0 ) const; virtual Statement *build() const; private: StatementNode *first, *last; }; class NullStmtNode : public CompoundStmtNode { public: NullStmtNode( char *filename, int lineno ) : CompoundStmtNode( filename, lineno ) {} Statement *build() const; void print(std::ostream &, int indent = 0) const; }; class InitializerNode : public ParseNode { public: InitializerNode( ExpressionNode *, bool aggrp = false, ExpressionNode *des = 0 ); InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode *des = 0 ); ~InitializerNode(); ExpressionNode *get_expression() const { return expr; } InitializerNode *set_designators( ExpressionNode *des ) { designator = des; return this; } ExpressionNode *get_designators() const { return designator; } InitializerNode *next_init() const { return kids; } void print( std::ostream &, int indent = 0 ) const; void printOneLine( std::ostream & ) const; virtual Initializer *build() const; private: ExpressionNode *expr; bool aggregate; ExpressionNode *designator; // may be list InitializerNode *kids; }; template< typename SynTreeType, typename NodeType > void buildList( const NodeType *firstNode, std::list< SynTreeType* > &outputList ) { SemanticError errors; std::back_insert_iterator< std::list< SynTreeType* > > out( outputList ); const NodeType *cur = firstNode; while( cur ) { try { SynTreeType *result = dynamic_cast< SynTreeType* >( cur->build() ); if( result ) { *out++ = result; } else { } } catch( SemanticError &e ) { errors.append( e ); } cur = dynamic_cast< NodeType* >( cur->get_link() ); } if( !errors.isEmpty() ) { throw errors; } } // in DeclarationNode.cc void buildList( const DeclarationNode *firstNode, std::list< Declaration* > &outputList ); void buildList( const DeclarationNode *firstNode, std::list< DeclarationWithType* > &outputList ); void buildTypeList( const DeclarationNode *firstNode, std::list< Type* > &outputList ); // in ExpressionNode.cc ExpressionNode *flattenCommas( ExpressionNode *list ); #endif /* #ifndef PARSENODE_H */ // Local Variables: // // mode: C++ // // compile-command: "gmake" // // End: //