Build AST nodes from within the parser.

This commit is contained in:
Rhys Weatherley
2010-11-12 10:23:46 +10:00
parent 73f77a0b8e
commit 1f8f99df28
7 changed files with 973 additions and 774 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -111,11 +111,19 @@ void FunctionCallExpression::accept0(Visitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(expr, visitor); accept(expr, visitor);
accept(id, visitor);
accept(arguments, visitor); accept(arguments, visitor);
} }
visitor->endVisit(this); visitor->endVisit(this);
} }
void FunctionIdentifier::accept0(Visitor *visitor)
{
if (visitor->visit(this))
accept(type, visitor);
visitor->endVisit(this);
}
void ExpressionStatement::accept0(Visitor *visitor) void ExpressionStatement::accept0(Visitor *visitor)
{ {
if (visitor->visit(this)) if (visitor->visit(this))
@@ -198,8 +206,8 @@ void CaseLabelStatement::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
BasicType::BasicType(int _token) BasicType::BasicType(int _token, const char *_name, Category _category)
: Type(Kind_BasicType), token(_token) : Type(Kind_BasicType), token(_token), name(_name), categ(_category)
{ {
switch (token) { switch (token) {
case GLSLParserTable::T_VOID: case GLSLParserTable::T_VOID:
@@ -314,14 +322,22 @@ void StructType::Field::setInnerType(Type *innerType)
*parent = innerType; *parent = innerType;
} }
void StructType::fixInnerTypes(Type *innerType, List<Field *> *fields) List<StructType::Field *> *StructType::fixInnerTypes(Type *innerType, List<Field *> *fields)
{ {
if (!fields) if (!fields)
return; return fields;
List<Field *> *head = fields->next; List<Field *> *head = fields->next;
List<Field *> *current = head; List<Field *> *current = head;
do { do {
current->value->setInnerType(innerType); current->value->setInnerType(innerType);
current = current->next; current = current->next;
} while (current && current != head); } while (current && current != head);
return fields;
}
void PrecisionDeclaration::accept0(Visitor *visitor)
{
if (visitor->visit(this))
accept(type, visitor);
visitor->endVisit(this);
} }

View File

@@ -37,7 +37,6 @@ namespace GLSL {
class AST; class AST;
class TranslationUnit; class TranslationUnit;
class Declaration;
class Expression; class Expression;
class IdentifierExpression; class IdentifierExpression;
class LiteralExpression; class LiteralExpression;
@@ -47,6 +46,7 @@ class TernaryExpression;
class AssignmentExpression; class AssignmentExpression;
class MemberAccessExpression; class MemberAccessExpression;
class FunctionCallExpression; class FunctionCallExpression;
class FunctionIdentifier;
class Statement; class Statement;
class ExpressionStatement; class ExpressionStatement;
class CompoundStatement; class CompoundStatement;
@@ -63,6 +63,8 @@ class BasicType;
class NamedType; class NamedType;
class ArrayType; class ArrayType;
class StructType; class StructType;
class Declaration;
class PrecisionDeclaration;
class Visitor; class Visitor;
template <typename T> template <typename T>
@@ -145,6 +147,7 @@ public:
Kind_GreaterEqual, Kind_GreaterEqual,
Kind_LogicalAnd, Kind_LogicalAnd,
Kind_LogicalOr, Kind_LogicalOr,
Kind_LogicalXor,
Kind_BitwiseAnd, Kind_BitwiseAnd,
Kind_BitwiseOr, Kind_BitwiseOr,
Kind_BitwiseXor, Kind_BitwiseXor,
@@ -156,6 +159,7 @@ public:
Kind_MemberAccess, Kind_MemberAccess,
Kind_FunctionCall, Kind_FunctionCall,
Kind_MemberFunctionCall, Kind_MemberFunctionCall,
Kind_FunctionIdentifier,
// Assignment expressions // Assignment expressions
Kind_Assign, Kind_Assign,
@@ -186,8 +190,6 @@ public:
Kind_CaseLabel, Kind_CaseLabel,
Kind_DefaultLabel, Kind_DefaultLabel,
// Declarations
// Types // Types
Kind_BasicType, Kind_BasicType,
Kind_NamedType, Kind_NamedType,
@@ -195,13 +197,14 @@ public:
Kind_OpenArrayType, Kind_OpenArrayType,
Kind_StructType, Kind_StructType,
Kind_AnonymousStructType, Kind_AnonymousStructType,
Kind_StructField Kind_StructField,
// Declarations
Kind_PrecisionDeclaration
}; };
virtual TranslationUnit *asTranslationUnit() { return 0; } virtual TranslationUnit *asTranslationUnit() { return 0; }
virtual Declaration *asDeclaration() { return 0; }
virtual Expression *asExpression() { return 0; } virtual Expression *asExpression() { return 0; }
virtual IdentifierExpression *asIdentifierExpression() { return 0; } virtual IdentifierExpression *asIdentifierExpression() { return 0; }
virtual LiteralExpression *asLiteralExpression() { return 0; } virtual LiteralExpression *asLiteralExpression() { return 0; }
@@ -211,6 +214,7 @@ public:
virtual AssignmentExpression *asAssignmentExpression() { return 0; } virtual AssignmentExpression *asAssignmentExpression() { return 0; }
virtual MemberAccessExpression *asMemberAccessExpression() { return 0; } virtual MemberAccessExpression *asMemberAccessExpression() { return 0; }
virtual FunctionCallExpression *asFunctionCallExpression() { return 0; } virtual FunctionCallExpression *asFunctionCallExpression() { return 0; }
virtual FunctionIdentifier *asFunctionIdentifier() { return 0; }
virtual Statement *asStatement() { return 0; } virtual Statement *asStatement() { return 0; }
virtual ExpressionStatement *asExpressionStatement() { return 0; } virtual ExpressionStatement *asExpressionStatement() { return 0; }
@@ -230,6 +234,9 @@ public:
virtual ArrayType *asArrayType() { return 0; } virtual ArrayType *asArrayType() { return 0; }
virtual StructType *asStructType() { return 0; } virtual StructType *asStructType() { return 0; }
virtual Declaration *asDeclaration() { return 0; }
virtual PrecisionDeclaration *asPrecisionDeclaration() { return 0; }
void accept(Visitor *visitor); void accept(Visitor *visitor);
static void accept(AST *ast, Visitor *visitor); static void accept(AST *ast, Visitor *visitor);
@@ -275,15 +282,6 @@ public: // attributes
List<Declaration *> *declarations; List<Declaration *> *declarations;
}; };
class GLSL_EXPORT Declaration: public AST
{
protected:
Declaration(Kind _kind) : AST(_kind) {}
public:
virtual Declaration *asDeclaration() { return this; }
};
class GLSL_EXPORT Expression: public AST class GLSL_EXPORT Expression: public AST
{ {
protected: protected:
@@ -399,13 +397,13 @@ public: // attributes
class GLSL_EXPORT FunctionCallExpression: public Expression class GLSL_EXPORT FunctionCallExpression: public Expression
{ {
public: public:
FunctionCallExpression(const std::string *_name, FunctionCallExpression(FunctionIdentifier *_id,
List<Expression *> *_arguments) List<Expression *> *_arguments)
: Expression(Kind_FunctionCall), expr(0), name(_name) : Expression(Kind_FunctionCall), expr(0), id(_id)
, arguments(finish(_arguments)) {} , arguments(finish(_arguments)) {}
FunctionCallExpression(Expression *_expr, const std::string *_name, FunctionCallExpression(Expression *_expr, FunctionIdentifier *_id,
List<Expression *> *_arguments) List<Expression *> *_arguments)
: Expression(Kind_MemberFunctionCall), expr(_expr), name(_name) : Expression(Kind_MemberFunctionCall), expr(_expr), id(_id)
, arguments(finish(_arguments)) {} , arguments(finish(_arguments)) {}
virtual FunctionCallExpression *asFunctionCallExpression() { return this; } virtual FunctionCallExpression *asFunctionCallExpression() { return this; }
@@ -414,10 +412,27 @@ public:
public: // attributes public: // attributes
Expression *expr; Expression *expr;
const std::string *name; FunctionIdentifier *id;
List<Expression *> *arguments; List<Expression *> *arguments;
}; };
class GLSL_EXPORT FunctionIdentifier: public AST
{
public:
FunctionIdentifier(const std::string *_name)
: AST(Kind_FunctionIdentifier), name(_name), type(0) {}
FunctionIdentifier(Type *_type)
: AST(Kind_FunctionIdentifier), name(0), type(_type) {}
virtual FunctionIdentifier *asFunctionIdentifier() { return this; }
virtual void accept0(Visitor *visitor);
public: // attributes
const std::string *name;
Type *type;
};
class GLSL_EXPORT Statement: public AST class GLSL_EXPORT Statement: public AST
{ {
protected: protected:
@@ -444,6 +459,8 @@ public: // attributes
class GLSL_EXPORT CompoundStatement: public Statement class GLSL_EXPORT CompoundStatement: public Statement
{ {
public: public:
CompoundStatement()
: Statement(Kind_CompoundStatement), statements(0) {}
CompoundStatement(List<Statement *> *_statements) CompoundStatement(List<Statement *> *_statements)
: Statement(Kind_CompoundStatement), statements(finish(_statements)) {} : Statement(Kind_CompoundStatement), statements(finish(_statements)) {}
@@ -582,29 +599,59 @@ protected:
public: public:
enum Precision enum Precision
{ {
PrecNotValid, // Precision not valid (e.g. structs and samplers). PrecNotValid, // Precision not valid (e.g. structs).
PrecUnspecified, // Precision not known, but can be validly set. PrecUnspecified, // Precision not known, but can be validly set.
Lowp, Lowp,
Mediump, Mediump,
Highp Highp
}; };
enum Category
{
Void,
Primitive,
Vector2,
Vector3,
Vector4,
Matrix,
Sampler1D,
Sampler2D,
Sampler3D,
SamplerCube,
Sampler1DShadow,
Sampler2DShadow,
SamplerCubeShadow,
Sampler1DArray,
Sampler2DArray,
SamplerCubeArray,
Sampler1DArrayShadow,
Sampler2DArrayShadow,
SamplerCubeArrayShadow,
Sampler2DRect,
Sampler2DRectShadow,
Sampler2DMS,
Sampler2DMSArray,
SamplerBuffer,
Array,
Struct
};
virtual Type *asType() { return this; } virtual Type *asType() { return this; }
virtual Precision precision() const = 0; virtual Precision precision() const = 0;
// Set the precision for the innermost basic type. Returns false if it // Set the precision for the innermost basic type. Returns false if it
// is not valid to set a precision (e.g. structs, samplers, etc). // is not valid to set a precision (e.g. structs).
virtual bool setPrecision(Precision precision) = 0; virtual bool setPrecision(Precision precision) = 0;
virtual Category category() const = 0;
}; };
class GLSL_EXPORT BasicType: public Type class GLSL_EXPORT BasicType: public Type
{ {
public: public:
// Pass the parser's token code: T_VOID, T_VEC4, etc. // Pass the parser's token code: T_VOID, T_VEC4, etc.
BasicType(int _token); BasicType(int _token, const char *_name, Category _category);
BasicType(int _token, Precision _prec)
: Type(Kind_BasicType), prec(_prec), token(_token) {}
virtual BasicType *asBasicType() { return this; } virtual BasicType *asBasicType() { return this; }
@@ -613,9 +660,13 @@ public:
virtual Precision precision() const; virtual Precision precision() const;
virtual bool setPrecision(Precision precision); virtual bool setPrecision(Precision precision);
virtual Category category() const { return categ; }
public: // attributes public: // attributes
Precision prec; Precision prec;
int token; int token;
const char *name;
Category categ;
}; };
class GLSL_EXPORT NamedType: public Type class GLSL_EXPORT NamedType: public Type
@@ -630,6 +681,8 @@ public:
virtual Precision precision() const; virtual Precision precision() const;
virtual bool setPrecision(Precision precision); virtual bool setPrecision(Precision precision);
virtual Category category() const { return Struct; }
public: // attributes public: // attributes
const std::string *name; const std::string *name;
}; };
@@ -649,6 +702,8 @@ public:
virtual Precision precision() const; virtual Precision precision() const;
virtual bool setPrecision(Precision precision); virtual bool setPrecision(Precision precision);
virtual Category category() const { return Array; }
public: // attributes public: // attributes
Type *elementType; Type *elementType;
Expression *size; Expression *size;
@@ -691,19 +746,40 @@ public:
// Fix the inner types of a field list. The "innerType" will // Fix the inner types of a field list. The "innerType" will
// be copied into the "array holes" of all fields. // be copied into the "array holes" of all fields.
static void fixInnerTypes(Type *innerType, List<Field *> *fields); static List<Field *> *fixInnerTypes(Type *innerType, List<Field *> *fields);
// Add a new group of fields after having their inner types fixed. virtual Category category() const { return Struct; }
void addFields(List<Field *> *list)
{
fields = appendLists(fields, list);
}
public: // attributes public: // attributes
const std::string *name; const std::string *name;
List<Field *> *fields; List<Field *> *fields;
}; };
class GLSL_EXPORT Declaration: public AST
{
protected:
Declaration(Kind _kind) : AST(_kind) {}
public:
virtual Declaration *asDeclaration() { return this; }
};
class GLSL_EXPORT PrecisionDeclaration: public Declaration
{
public:
PrecisionDeclaration(Type::Precision _precision, Type *_type)
: Declaration(Kind_PrecisionDeclaration)
, precision(_precision), type(_type) {}
virtual PrecisionDeclaration *asPrecisionDeclaration() { return this; }
virtual void accept0(Visitor *visitor);
public: // attributes
Type::Precision precision;
Type *type;
};
} // namespace GLSL } // namespace GLSL
#endif // GLSLAST_H #endif // GLSLAST_H

View File

@@ -69,6 +69,9 @@ public:
virtual bool visit(FunctionCallExpression *) { return true; } virtual bool visit(FunctionCallExpression *) { return true; }
virtual void endVisit(FunctionCallExpression *) {} virtual void endVisit(FunctionCallExpression *) {}
virtual bool visit(FunctionIdentifier *) { return true; }
virtual void endVisit(FunctionIdentifier *) {}
virtual bool visit(ExpressionStatement *) { return true; } virtual bool visit(ExpressionStatement *) { return true; }
virtual void endVisit(ExpressionStatement *) {} virtual void endVisit(ExpressionStatement *) {}
@@ -113,6 +116,9 @@ public:
virtual bool visit(StructType::Field *) { return true; } virtual bool visit(StructType::Field *) { return true; }
virtual void endVisit(StructType::Field *) {} virtual void endVisit(StructType::Field *) {}
virtual bool visit(PrecisionDeclaration *) { return true; }
virtual void endVisit(PrecisionDeclaration *) {}
}; };
} // namespace GLSL } // namespace GLSL

View File

@@ -372,9 +372,12 @@ int Lexer::yylex_helper(const char **position, int *line)
_yyval.string = _engine->identifier(word, _it - word - 1); _yyval.string = _engine->identifier(word, _it - word - 1);
return Parser::T_IDENTIFIER; return Parser::T_IDENTIFIER;
} else if (std::isdigit(ch)) { } else if (std::isdigit(ch)) {
const char *word = _it - 2;
while (std::isalnum(_yychar) || _yychar == '.') { while (std::isalnum(_yychar) || _yychar == '.') {
yyinp(); yyinp();
} }
if (_engine)
_yyval.string = _engine->identifier(word, _it - word - 1);
return Parser::T_NUMBER; return Parser::T_NUMBER;
} }

File diff suppressed because it is too large Load Diff

View File

@@ -51,7 +51,27 @@ public:
List<Declaration *> *declaration_list; List<Declaration *> *declaration_list;
Expression *expression; Expression *expression;
List<Expression *> *expression_list; List<Expression *> *expression_list;
Statement *statement;
List<Statement *> *statement_list;
Type *type;
StructType::Field *field;
List<StructType::Field *> *field_list;
TranslationUnit *translation_unit; TranslationUnit *translation_unit;
FunctionIdentifier *function_identifier;
AST::Kind kind;
Type::Precision precision;
struct {
Statement *thenClause;
Statement *elseClause;
} ifstmt;
struct {
Expression *condition;
Expression *increment;
} forstmt;
struct {
FunctionIdentifier *id;
List<Expression *> *arguments;
} function;
// ### ast nodes... // ### ast nodes...
}; };
@@ -65,6 +85,9 @@ private:
Value &sym(int n) { return _symStack[_tos + n - 1]; } Value &sym(int n) { return _symStack[_tos + n - 1]; }
AST *&ast(int n) { return _symStack[_tos + n - 1].ast; } AST *&ast(int n) { return _symStack[_tos + n - 1].ast; }
const std::string *&string(int n) { return _symStack[_tos + n - 1].string; } const std::string *&string(int n) { return _symStack[_tos + n - 1].string; }
Expression *&expression(int n) { return _symStack[_tos + n - 1].expression; }
Statement *&statement(int n) { return _symStack[_tos + n - 1].statement; }
Type *&type(int n) { return _symStack[_tos + n - 1].type; }
inline int consumeToken() { return _index++; } inline int consumeToken() { return _index++; }
inline const Token &tokenAt(int index) const { return _tokens.at(index); } inline const Token &tokenAt(int index) const { return _tokens.at(index); }
@@ -111,6 +134,13 @@ private:
return node; return node;
} }
Type *makeBasicType(int token, BasicType::Category category)
{
Type *type = new (_engine->pool()) BasicType(token, spell[token], category);
type->lineno = yyloc >= 0 ? (_tokens[yyloc].line + 1) : 0;
return type;
}
private: private:
Engine *_engine; Engine *_engine;
int _tos; int _tos;