Get rid of glsl.g.in and start working on the semantic actions.

This commit is contained in:
Roberto Raggi
2010-11-11 12:01:37 +01:00
parent 6a5f06d463
commit ca4439bcef
22 changed files with 4847 additions and 8407 deletions

View File

@@ -1,8 +1,8 @@
HEADERS += $$PWD/glsl.h $$PWD/glsllexer.h $$PWD/glslparser.h glslparsertable_p.h $$PWD/glslast.h \ HEADERS += $$PWD/glsl.h $$PWD/glsllexer.h $$PWD/glslparser.h $$PWD/glslparsertable_p.h $$PWD/glslast.h \
$$PWD/glslastvisitor.h $$PWD/glslastvisitor.h $$PWD/glslengine.h
SOURCES += $$PWD/glslkeywords.cpp $$PWD/glslparser.cpp $$PWD/glslparsertable.cpp \ SOURCES += $$PWD/glslkeywords.cpp $$PWD/glslparser.cpp $$PWD/glslparsertable.cpp \
$$PWD/glsllexer.cpp $$PWD/glslast.cpp $$PWD/glsldump.cpp $$PWD/glsldelete.cpp \ $$PWD/glsllexer.cpp $$PWD/glslast.cpp \
$$PWD/glslastvisitor.cpp $$PWD/glslastvisitor.cpp $$PWD/glslengine.cpp
OTHER_FILES = $$PWD/specs/glsl.g.in \ OTHER_FILES = $$PWD/glsl.g \
$$PWD/specs/grammar.txt $$PWD/specs/grammar.txt

File diff suppressed because it is too large Load Diff

View File

@@ -42,4 +42,12 @@
# define GLSL_EXPORT Q_DECL_IMPORT # define GLSL_EXPORT Q_DECL_IMPORT
#endif #endif
namespace GLSL {
class Engine;
class Lexer;
class Parser;
class AST;
template <typename T> class List;
}
#endif // GLSL_H #endif // GLSL_H

View File

@@ -66,17 +66,10 @@ Statement *AST::makeCompound(Statement *left, Statement *right)
return compound; return compound;
} }
void Operand::accept0(Visitor *visitor) void TranslationUnit::accept0(Visitor *visitor)
{
visitor->visit(this);
visitor->endVisit(this);
}
void Operator::accept0(Visitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
for (_Base::iterator it = begin(); it != end(); ++it) accept(declarations, visitor);
accept(*it, visitor);
} }
visitor->endVisit(this); visitor->endVisit(this);
} }

View File

@@ -36,8 +36,8 @@
namespace GLSL { namespace GLSL {
class AST; class AST;
class Operand; class TranslationUnit;
class Operator; class Declaration;
class Expression; class Expression;
class IdentifierExpression; class IdentifierExpression;
class LiteralExpression; class LiteralExpression;
@@ -65,12 +65,40 @@ class ArrayType;
class StructType; class StructType;
class Visitor; class Visitor;
template <typename T>
class GLSL_EXPORT List
{
public:
List(const T &value)
: value(value), next(this) {}
List(List *previous, const T &value)
: value(value)
{
next = previous->next;
previous->next = this;
}
List *finish()
{
List *head = next;
next = 0;
return head;
}
T value;
List *next;
};
class GLSL_EXPORT AST class GLSL_EXPORT AST
{ {
public: public:
enum Kind { enum Kind {
Kind_Undefined, Kind_Undefined,
// Translation unit
Kind_TranslationUnit,
// Primary expressions // Primary expressions
Kind_Identifier, Kind_Identifier,
Kind_Literal, Kind_Literal,
@@ -157,8 +185,9 @@ public:
AST() : kind(Kind_Undefined), lineno(0) {} AST() : kind(Kind_Undefined), lineno(0) {}
virtual ~AST(); virtual ~AST();
virtual Operand *asOperand() { return 0; } virtual TranslationUnit *asTranslationUnit() { return 0; }
virtual Operator *asOperator() { 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; }
@@ -191,6 +220,13 @@ public:
void accept(Visitor *visitor); void accept(Visitor *visitor);
static void accept(AST *ast, Visitor *visitor); static void accept(AST *ast, Visitor *visitor);
template <typename T>
static void accept(List<T> *it, Visitor *visitor)
{
for (; it; it = it->next)
accept(it->value, visitor);
}
virtual void accept0(Visitor *visitor) = 0; virtual void accept0(Visitor *visitor) = 0;
// Efficiently make a compound statement out of "left" and "right", // Efficiently make a compound statement out of "left" and "right",
@@ -200,40 +236,42 @@ public:
protected: protected:
AST(Kind _kind) : kind(_kind), lineno(0) {} AST(Kind _kind) : kind(_kind), lineno(0) {}
protected:
template <typename T>
static List<T> *finish(List<T> *list)
{
if (! list)
return 0;
return list->finish(); // convert the circular list with a linked list.
}
public: // attributes public: // attributes
int kind; int kind;
int lineno; int lineno;
}; };
class GLSL_EXPORT Operand: public AST class GLSL_EXPORT TranslationUnit: public AST
{ {
public: public:
Operand(int location) TranslationUnit(List<Declaration *> *declarations)
: location(location) {} : declarations(finish(declarations))
{ kind = Kind_TranslationUnit; }
virtual Operand *asOperand() { return this; } virtual TranslationUnit *asTranslationUnit() { return this; }
virtual void accept0(Visitor *visitor); virtual void accept0(Visitor *visitor);
public: // attributes public: // attributes
int location; List<Declaration *> *declarations;
}; };
class GLSL_EXPORT Operator: public AST, public std::vector<AST *> class GLSL_EXPORT Declaration: public AST
{ {
typedef std::vector<AST *> _Base; protected:
Declaration(Kind _kind) { kind = _kind; }
public: public:
template <typename It> virtual Declaration *asDeclaration() { return this; }
Operator(int ruleno, It begin, It end)
: _Base(begin, end), ruleno(ruleno) {}
virtual Operator *asOperator() { return this; }
virtual void accept0(Visitor *visitor);
public: // attributes
int ruleno;
}; };
class GLSL_EXPORT Expression: public AST class GLSL_EXPORT Expression: public AST

View File

@@ -42,11 +42,8 @@ public:
virtual bool preVisit(AST *) { return true; } virtual bool preVisit(AST *) { return true; }
virtual void postVisit(AST *) {} virtual void postVisit(AST *) {}
virtual bool visit(Operand *) { return true; } virtual bool visit(TranslationUnit *) { return true; }
virtual void endVisit(Operand *) {} virtual void endVisit(TranslationUnit *) {}
virtual bool visit(Operator *) { return true; }
virtual void endVisit(Operator *) {}
virtual bool visit(IdentifierExpression *) { return true; } virtual bool visit(IdentifierExpression *) { return true; }
virtual void endVisit(IdentifierExpression *) {} virtual void endVisit(IdentifierExpression *) {}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,21 @@
#include "glslengine.h"
using namespace GLSL;
Engine::Engine()
{
}
Engine::~Engine()
{
}
const std::string *Engine::identifier(const std::string &s)
{
return &*_identifiers.insert(s).first;
}
const std::string *Engine::identifier(const char *s, int n)
{
return &*_identifiers.insert(std::string(s, n)).first;
}

View File

@@ -0,0 +1,25 @@
#ifndef GLSLENGINE_H
#define GLSLENGINE_H
#include "glsl.h"
#include <set>
#include <string>
namespace GLSL {
class GLSL_EXPORT Engine
{
public:
Engine();
~Engine();
const std::string *identifier(const std::string &s);
const std::string *identifier(const char *s, int n);
private:
std::set<std::string> _identifiers;
};
} // namespace GLSL
#endif // GLSLENGINE_H

View File

@@ -29,16 +29,17 @@
#include "glsllexer.h" #include "glsllexer.h"
#include "glslparser.h" #include "glslparser.h"
#include "glslengine.h"
#include <cctype> #include <cctype>
#include <iostream> #include <iostream>
#include <cstdio> #include <cstdio>
using namespace GLSL; using namespace GLSL;
Lexer::Lexer(const char *source, unsigned size) Lexer::Lexer(Engine *engine, const char *source, unsigned size)
: _source(source), : _engine(engine),
_source(source),
_it(source), _it(source),
_end(source + size),
_size(size), _size(size),
_yychar('\n'), _yychar('\n'),
_lineno(0), _lineno(0),
@@ -64,12 +65,13 @@ int Lexer::yylex(Token *tk)
{ {
const char *pos = 0; const char *pos = 0;
int line = 0; int line = 0;
_yyval.ptr = 0;
const int kind = yylex_helper(&pos, &line); const int kind = yylex_helper(&pos, &line);
tk->kind = kind; tk->kind = kind;
tk->position = pos - _source; tk->position = pos - _source;
tk->length = _it - pos - 1; tk->length = _it - pos - 1;
tk->line = line; tk->line = line;
tk->matchingBrace = 0; tk->ptr = _yyval.ptr;
return kind; return kind;
} }
@@ -360,8 +362,14 @@ int Lexer::yylex_helper(const char **position, int *line)
while (std::isalnum(_yychar) || _yychar == '_') { while (std::isalnum(_yychar) || _yychar == '_') {
yyinp(); yyinp();
} }
if (_scanKeywords) if (_scanKeywords) {
return findKeyword(word, _it - word - 1); const int k = findKeyword(word, _it - word - 1);
if (k != Parser::T_IDENTIFIER)
return k;
}
if (_engine)
_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)) {
while (std::isalnum(_yychar) || _yychar == '.') { while (std::isalnum(_yychar) || _yychar == '.') {

View File

@@ -31,6 +31,7 @@
#define GLSLLEXER_H #define GLSLLEXER_H
#include "glsl.h" #include "glsl.h"
#include <string>
namespace GLSL { namespace GLSL {
@@ -44,6 +45,8 @@ public:
union { union {
int matchingBrace; int matchingBrace;
int i; // integer value
const std::string *string; // string value
void *ptr; void *ptr;
}; };
@@ -57,7 +60,7 @@ public:
class GLSL_EXPORT Lexer class GLSL_EXPORT Lexer
{ {
public: public:
Lexer(const char *source, unsigned size); Lexer(Engine *engine, const char *source, unsigned size);
~Lexer(); ~Lexer();
enum enum
@@ -75,6 +78,14 @@ public:
Variant_Mask = 0xFFFF0000 Variant_Mask = 0xFFFF0000
}; };
union Value {
int i;
const std::string *string;
void *ptr;
};
Engine *engine() const { return _engine; }
int state() const { return _state; } int state() const { return _state; }
void setState(int state) { _state = state; } void setState(int state) { _state = state; }
@@ -90,6 +101,8 @@ public:
int yylex(Token *tk); int yylex(Token *tk);
int findKeyword(const char *word, int length) const; int findKeyword(const char *word, int length) const;
void *yyval() const { return _yyval.ptr; }
private: private:
static int classify(const char *s, int len); static int classify(const char *s, int len);
@@ -97,9 +110,9 @@ private:
int yylex_helper(const char **position, int *line); int yylex_helper(const char **position, int *line);
private: private:
Engine *_engine;
const char *_source; const char *_source;
const char *_it; const char *_it;
const char *_end;
int _size; int _size;
int _yychar; int _yychar;
int _lineno; int _lineno;
@@ -107,6 +120,7 @@ private:
int _variant; int _variant;
unsigned _scanKeywords: 1; unsigned _scanKeywords: 1;
unsigned _scanComments: 1; unsigned _scanComments: 1;
Value _yyval;
}; };
} // end of namespace GLSL } // end of namespace GLSL

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,6 @@
#line 212 "./glsl.g"
/************************************************************************** /**************************************************************************
** **
** This file is part of Qt Creator ** This file is part of Qt Creator
@@ -36,26 +38,41 @@
namespace GLSL { namespace GLSL {
class Parser: public GLSLParserTable class GLSL_EXPORT Parser: public GLSLParserTable
{ {
public: public:
Parser(const char *source, unsigned size, int variant); union Value {
void *ptr;
const std::string *string;
AST *ast;
List<AST *> *ast_list;
Declaration *declaration;
List<Declaration *> *declaration_list;
TranslationUnit *translation_unit;
};
Parser(Engine *engine, const char *source, unsigned size, int variant);
~Parser(); ~Parser();
bool parse(); TranslationUnit *parse();
private: private:
// 1-based
Value &sym(int n) { return _symStack[_tos + n - 1]; }
AST *&ast(int n) { return _symStack[_tos + n - 1].ast; }
const std::string *&string(int n) { return _symStack[_tos + n - 1].string; }
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); }
inline int tokenKind(int index) const { return _tokens.at(index).kind; } inline int tokenKind(int index) const { return _tokens.at(index).kind; }
void dump(AST *ast); void reduce(int ruleno);
private: private:
int _tos; int _tos;
int _index; int _index;
std::vector<int> _stateStack; std::vector<int> _stateStack;
std::vector<int> _locationStack; std::vector<int> _locationStack;
std::vector<AST *> _astStack; std::vector<Value> _symStack;
std::vector<Token> _tokens; std::vector<Token> _tokens;
}; };

File diff suppressed because it is too large Load Diff

View File

@@ -235,15 +235,15 @@ public:
T_XOR_ASSIGN = 165, T_XOR_ASSIGN = 165,
T_XOR_OP = 166, T_XOR_OP = 166,
ACCEPT_STATE = 435, ACCEPT_STATE = 440,
RULE_COUNT = 312, RULE_COUNT = 314,
STATE_COUNT = 455, STATE_COUNT = 459,
TERMINAL_COUNT = 172, TERMINAL_COUNT = 172,
NON_TERMINAL_COUNT = 82, NON_TERMINAL_COUNT = 84,
GOTO_INDEX_OFFSET = 455, GOTO_INDEX_OFFSET = 459,
GOTO_INFO_OFFSET = 4796, GOTO_INFO_OFFSET = 4728,
GOTO_CHECK_OFFSET = 4796 GOTO_CHECK_OFFSET = 4728
}; };
static const char *const spell []; static const char *const spell [];

View File

@@ -1,6 +1,5 @@
#!/bin/sh #!/bin/sh
me=$(dirname $0) me=$(dirname $0)
cat $me/specs/glsl.g.in $me/specs/grammar.txt > $me/glsl.g qlalr --qt --no-debug $me/glsl.g
qlalr --qt --no-lines --no-debug $me/glsl.g

View File

@@ -1,447 +0,0 @@
---------------------------------------------------------------------------
--
-- This file is part of Qt Creator
--
-- Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
--
-- Contact: Nokia Corporation (qt-info@nokia.com)
--
-- Commercial Usage
--
-- Licensees holding valid Qt Commercial licenses may use this file in
-- accordance with the Qt Commercial License Agreement provided with the
-- Software or, alternatively, in accordance with the terms contained in
-- a written agreement between you and Nokia.
--
-- GNU Lesser General Public License Usage
--
-- Alternatively, this file may be used under the terms of the GNU Lesser
-- General Public License version 2.1 as published by the Free Software
-- Foundation and appearing in the file LICENSE.LGPL included in the
-- packaging of this file. Please review the following information to
-- ensure the GNU Lesser General Public License version 2.1 requirements
-- will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
--
-- If you are unsure which license is appropriate for your use, please
-- contact the sales department at http://qt.nokia.com/contact.
---------------------------------------------------------------------------
--
-- todo:
-- spelling of XOR_OP and CARET
%decl glslparser.h
%impl glslparser.cpp
%parser GLSLParserTable
%token_prefix T_
%token ADD_ASSIGN "+="
%token AMPERSAND "&"
%token AND_ASSIGN "&="
%token AND_OP "&&"
%token ATTRIBUTE "attribute"
%token BANG "!"
%token BOOL "bool"
%token BREAK "break"
%token BVEC2 "bvec2"
%token BVEC3 "bvec3"
%token BVEC4 "bvec4"
%token CARET "^"
%token CASE "case"
%token CENTROID "centroid"
%token COLON ":"
%token COMMA ","
%token CONST "const"
%token CONTINUE "continue"
%token DASH "-"
%token DEC_OP "--"
%token DEFAULT "default"
%token DISCARD "discard"
%token DIV_ASSIGN "/="
%token DMAT2 "dmat2"
%token DMAT2X2 "dmat2x2"
%token DMAT2X3 "dmat2x3"
%token DMAT2X4 "dmat2x4"
%token DMAT3 "dmat3"
%token DMAT3X2 "dmat3x2"
%token DMAT3X3 "dmat3x3"
%token DMAT3X4 "dmat3x4"
%token DMAT4 "dmat4"
%token DMAT4X2 "dmat4x2"
%token DMAT4X3 "dmat4x3"
%token DMAT4X4 "dmat4x4"
%token DO "do"
%token DOT "."
%token DOUBLE "double"
%token DVEC2 "dvec2"
%token DVEC3 "dvec3"
%token DVEC4 "dvec4"
%token ELSE "else"
%token EQUAL "="
%token EQ_OP "=="
%token FLAT "flat"
%token FLOAT "float"
%token FOR "for"
%token GE_OP ">="
%token HIGHP "highp"
%token IDENTIFIER "identifier"
%token IF "if"
%token IN "in"
%token INC_OP "++"
%token INOUT "inout"
%token INT "int"
%token INVARIANT "invariant"
%token ISAMPLER1D "isampler1D"
%token ISAMPLER1DARRAY "isampler1DArray"
%token ISAMPLER2D "isampler2D"
%token ISAMPLER2DARRAY "isampler2DArray"
%token ISAMPLER2DMS "isampler2DMS"
%token ISAMPLER2DMSARRAY "isampler2DMSArray"
%token ISAMPLER2DRECT "isampler2DRect"
%token ISAMPLER3D "isampler3D"
%token ISAMPLERBUFFER "isamplerBuffer"
%token ISAMPLERCUBE "isamplerCube"
%token ISAMPLERCUBEARRAY "isamplerCubeArray"
%token IVEC2 "ivec2"
%token IVEC3 "ivec3"
%token IVEC4 "ivec4"
%token LAYOUT "layout"
%token LEFT_ANGLE "<"
%token LEFT_ASSIGN "<<="
%token LEFT_BRACE "{"
%token LEFT_BRACKET "["
%token LEFT_OP "<<"
%token LEFT_PAREN "("
%token LE_OP "<="
%token LOWP "lowp"
%token MAT2 "mat2"
%token MAT2X2 "mat2x2"
%token MAT2X3 "mat2x3"
%token MAT2X4 "mat2x4"
%token MAT3 "mat3"
%token MAT3X2 "mat3x2"
%token MAT3X3 "mat3x3"
%token MAT3X4 "mat3x4"
%token MAT4 "mat4"
%token MAT4X2 "mat4x2"
%token MAT4X3 "mat4x3"
%token MAT4X4 "mat4x4"
%token MEDIUMP "mediump"
%token MOD_ASSIGN "%="
%token MUL_ASSIGN "*="
%token NE_OP "!="
%token NOPERSPECTIVE "noperspective"
%token NUMBER "number constant"
%token OR_ASSIGN "|="
%token OR_OP "||"
%token OUT "out"
%token PATCH "patch"
%token PERCENT "%"
%token PLUS "plus"
%token PRECISION "precision"
%token QUESTION "?"
%token RETURN "return"
%token RIGHT_ANGLE ">"
%token RIGHT_ASSIGN ">>="
%token RIGHT_BRACE "}"
%token RIGHT_BRACKET "]"
%token RIGHT_OP ">>"
%token RIGHT_PAREN ")"
%token SAMPLE "sample"
%token SAMPLER1D "sampler1D"
%token SAMPLER1DARRAY "sampler1DArray"
%token SAMPLER1DARRAYSHADOW "sampler1DArrayShadow"
%token SAMPLER1DSHADOW "sampler1DShadow"
%token SAMPLER2D "sampler2D"
%token SAMPLER2DARRAY "sampler2DArray"
%token SAMPLER2DARRAYSHADOW "sampler2DArrayShadow"
%token SAMPLER2DMS "sampler2DMS"
%token SAMPLER2DMSARRAY "sampler2DMSArray"
%token SAMPLER2DRECT "sampler2DRect"
%token SAMPLER2DRECTSHADOW "sampler2DRectShadow"
%token SAMPLER2DSHADOW "sampler2DShadow"
%token SAMPLER3D "sampler3D"
%token SAMPLERBUFFER "samplerBuffer"
%token SAMPLERCUBE "samplerCube"
%token SAMPLERCUBEARRAY "samplerCubeArray"
%token SAMPLERCUBEARRAYSHADOW "samplerCubeArrayShadow"
%token SAMPLERCUBESHADOW "samplerCubeShadow"
%token SEMICOLON ";"
%token SLASH "/"
%token SMOOTH "smooth"
%token STAR "*"
%token STRUCT "struct"
%token SUBROUTINE "subroutine"
%token SUB_ASSIGN "-="
%token SWITCH "switch"
%token TILDE "~"
%token TYPE_NAME "type_name"
%token UINT "uint"
%token UNIFORM "uniform"
%token USAMPLER1D "usampler1D"
%token USAMPLER1DARRAY "usampler1DArray"
%token USAMPLER2D "usampler2D"
%token USAMPLER2DARRAY "usampler2DArray"
%token USAMPLER2DMS "usampler2DMS"
%token USAMPLER2DMSARRAY "usampler2DMSarray"
%token USAMPLER2DRECT "usampler2DRect"
%token USAMPLER3D "usampler3D"
%token USAMPLERBUFFER "usamplerBuffer"
%token USAMPLERCUBE "usamplerCube"
%token USAMPLERCUBEARRAY "usamplerCubeArray"
%token UVEC2 "uvec2"
%token UVEC3 "uvec3"
%token UVEC4 "uvec4"
%token VARYING "varying"
%token VEC2 "vec2"
%token VEC3 "vec3"
%token VEC4 "vec4"
%token VERTICAL_BAR "|"
%token VOID "void"
%token WHILE "while"
%token XOR_ASSIGN "^="
%token XOR_OP "^"
%token TRUE "true"
%token FALSE "false"
%token PREPROC "preprocessor directive"
%token COMMENT "comment"
%token ERROR "error"
%start translation_unit
/:
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include "$header"
#include "glsllexer.h"
#include "glslast.h"
#include <vector>
#include <stack>
namespace GLSL {
class Parser: public $table
{
public:
Parser(const char *source, unsigned size, int variant);
~Parser();
bool parse();
private:
inline int consumeToken() { return _index++; }
inline const Token &tokenAt(int index) const { return _tokens.at(index); }
inline int tokenKind(int index) const { return _tokens.at(index).kind; }
void dump(AST *ast);
private:
int _tos;
int _index;
std::vector<int> _stateStack;
std::vector<int> _locationStack;
std::vector<AST *> _astStack;
std::vector<Token> _tokens;
};
} // end of namespace GLSL
:/
/.
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include "glslparser.h"
#include <iostream>
#include <cstdio>
using namespace GLSL;
namespace GLSL {
void dumpAST(AST *);
void deleteAST(AST *ast);
}
Parser::Parser(const char *source, unsigned size, int variant)
: _tos(-1), _index(0)
{
_tokens.reserve(1024);
_stateStack.resize(128);
_locationStack.resize(128);
_astStack.resize(128);
_tokens.push_back(Token()); // invalid token
std::stack<int> parenStack;
std::stack<int> bracketStack;
std::stack<int> braceStack;
Lexer lexer(source, size);
lexer.setVariant(variant);
Token tk;
do {
lexer.yylex(&tk);
switch (tk.kind) {
case T_LEFT_PAREN:
parenStack.push(_tokens.size());
break;
case T_LEFT_BRACKET:
bracketStack.push(_tokens.size());
break;
case T_LEFT_BRACE:
braceStack.push(_tokens.size());
break;
case T_RIGHT_PAREN:
if (! parenStack.empty()) {
_tokens[parenStack.top()].matchingBrace = _tokens.size();
parenStack.pop();
}
break;
case T_RIGHT_BRACKET:
if (! bracketStack.empty()) {
_tokens[bracketStack.top()].matchingBrace = _tokens.size();
bracketStack.pop();
}
break;
case T_RIGHT_BRACE:
if (! braceStack.empty()) {
_tokens[braceStack.top()].matchingBrace = _tokens.size();
braceStack.pop();
}
break;
default:
break;
}
_tokens.push_back(tk);
} while (tk.isNot(EOF_SYMBOL));
_index = 1;
}
Parser::~Parser()
{
}
void Parser::dump(AST *ast)
{
dumpAST(ast);
}
bool Parser::parse()
{
int action = 0;
int yytoken = -1;
int yyloc = -1;
Operand *opd = 0;
_tos = -1;
do {
if (yytoken == -1 && -TERMINAL_COUNT != action_index[action]) {
yyloc = consumeToken();
yytoken = tokenKind(yyloc);
if (yytoken == T_IDENTIFIER && t_action(action, T_TYPE_NAME) != 0) {
const Token &la = tokenAt(_index);
if (la.is(T_IDENTIFIER)) {
yytoken = T_TYPE_NAME;
} else if (la.is(T_LEFT_BRACKET) && la.matchingBrace != 0 &&
tokenAt(la.matchingBrace + 1).is(T_IDENTIFIER)) {
yytoken = T_TYPE_NAME;
}
}
opd = new Operand(yyloc);
}
if (unsigned(++_tos) == _stateStack.size()) {
_stateStack.resize(_tos * 2);
_locationStack.resize(_tos * 2);
_astStack.resize(_tos * 2);
}
_stateStack[_tos] = action;
action = t_action(action, yytoken);
if (action > 0) {
if (action == ACCEPT_STATE) {
--_tos;
dump(_astStack[0]);
deleteAST(_astStack[0]);
return true;
}
_astStack[_tos] = opd;
_locationStack[_tos] = yyloc;
yytoken = -1;
} else if (action < 0) {
const int ruleno = -action - 1;
const int N = rhs[ruleno];
_tos -= N;
if (N == 0)
_astStack[_tos] = 0;
else
_astStack[_tos] = new Operator(ruleno, &_astStack[_tos], &_astStack[_tos + N]);
action = nt_action(_stateStack[_tos], lhs[ruleno] - TERMINAL_COUNT);
}
} while (action);
fprintf(stderr, "unexpected token `%s' at line %d\n", yytoken != -1 ? spell[yytoken] : "",
_tokens[yyloc].line + 1);
return false;
}
./

View File

@@ -99,7 +99,7 @@ parameter_declaration ::= parameter_type_qualifier parameter_qualifier parameter
parameter_declaration ::= parameter_qualifier parameter_declarator ; parameter_declaration ::= parameter_qualifier parameter_declarator ;
parameter_declaration ::= parameter_type_qualifier parameter_qualifier parameter_type_specifier ; parameter_declaration ::= parameter_type_qualifier parameter_qualifier parameter_type_specifier ;
parameter_declaration ::= parameter_qualifier parameter_type_specifier ; parameter_declaration ::= parameter_qualifier parameter_type_specifier ;
parameter_qualifier ::= ; parameter_qualifier ::= empty ;
parameter_qualifier ::= IN ; parameter_qualifier ::= IN ;
parameter_qualifier ::= OUT ; parameter_qualifier ::= OUT ;
parameter_qualifier ::= INOUT ; parameter_qualifier ::= INOUT ;
@@ -285,7 +285,7 @@ selection_rest_statement ::= statement ;
condition ::= expression ; condition ::= expression ;
condition ::= fully_specified_type IDENTIFIER EQUAL initializer ; condition ::= fully_specified_type IDENTIFIER EQUAL initializer ;
switch_statement ::= SWITCH LEFT_PAREN expression RIGHT_PAREN LEFT_BRACE switch_statement_list RIGHT_BRACE ; switch_statement ::= SWITCH LEFT_PAREN expression RIGHT_PAREN LEFT_BRACE switch_statement_list RIGHT_BRACE ;
switch_statement_list ::= ; switch_statement_list ::= empty ;
switch_statement_list ::= statement_list ; switch_statement_list ::= statement_list ;
case_label ::= CASE expression COLON ; case_label ::= CASE expression COLON ;
case_label ::= DEFAULT COLON ; case_label ::= DEFAULT COLON ;
@@ -294,7 +294,7 @@ iteration_statement ::= DO statement WHILE LEFT_PAREN expression RIGHT_PAREN SEM
iteration_statement ::= FOR LEFT_PAREN for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope ; iteration_statement ::= FOR LEFT_PAREN for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope ;
for_init_statement ::= expression_statement ; for_init_statement ::= expression_statement ;
for_init_statement ::= declaration_statement ; for_init_statement ::= declaration_statement ;
conditionopt ::= ; conditionopt ::= empty ;
conditionopt ::= condition ; conditionopt ::= condition ;
for_rest_statement ::= conditionopt SEMICOLON ; for_rest_statement ::= conditionopt SEMICOLON ;
for_rest_statement ::= conditionopt SEMICOLON expression ; for_rest_statement ::= conditionopt SEMICOLON expression ;
@@ -309,3 +309,4 @@ external_declaration ::= function_definition ;
external_declaration ::= declaration ; external_declaration ::= declaration ;
external_declaration ::= SEMICOLON ; external_declaration ::= SEMICOLON ;
function_definition ::= function_prototype compound_statement_no_new_scope ; function_definition ::= function_prototype compound_statement_no_new_scope ;
empty ::= ;

View File

@@ -1,6 +1,7 @@
#include "glslparser.h" #include <glslengine.h>
#include "glsllexer.h" #include <glslparser.h>
#include <glsllexer.h>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <string.h> #include <string.h>
@@ -15,7 +16,7 @@ using namespace GLSL;
#endif #endif
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int variant = 0; int variant = 0;
while (argc > 1 && argv[1][0] == '-' && argv[1][1] == '-') { while (argc > 1 && argv[1][0] == '-' && argv[1][1] == '-') {
@@ -62,7 +63,8 @@ int main(int argc, char *argv[])
variant = Lexer::Variant_Mask & ~Lexer::Variant_Reserved; variant = Lexer::Variant_Mask & ~Lexer::Variant_Reserved;
else if ((variant & (Lexer::Variant_VertexShader | Lexer::Variant_FragmentShader)) == 0) else if ((variant & (Lexer::Variant_VertexShader | Lexer::Variant_FragmentShader)) == 0)
variant |= Lexer::Variant_VertexShader | Lexer::Variant_FragmentShader; variant |= Lexer::Variant_VertexShader | Lexer::Variant_FragmentShader;
Parser parser(source, size, variant); Engine engine;
Parser parser(&engine, source, size, variant);
std::cout << argv[1] << (parser.parse() ? " OK " : " KO ") << std::endl; std::cout << argv[1] << (parser.parse() ? " OK " : " KO ") << std::endl;
delete source; delete source;

View File

@@ -0,0 +1,14 @@
TEMPLATE = app
CONFIG -= app_bundle
CONFIG += console
TARGET = glsl
DEPENDPATH += .
INCLUDEPATH += . ..
QT = core
# Input
SOURCES += main.cpp
include(../glsl-lib.pri)

View File

@@ -53,7 +53,7 @@ void Highlighter::setFormats(const QVector<QTextCharFormat> &formats)
void Highlighter::highlightBlock(const QString &text) void Highlighter::highlightBlock(const QString &text)
{ {
const QByteArray data = text.toLatin1(); const QByteArray data = text.toLatin1();
GLSL::Lexer lex(data.constData(), data.size()); GLSL::Lexer lex(/*engine=*/ 0, data.constData(), data.size());
lex.setState(qMax(0, previousBlockState())); lex.setState(qMax(0, previousBlockState()));
lex.setScanKeywords(false); lex.setScanKeywords(false);
lex.setScanComments(true); lex.setScanComments(true);