forked from qt-creator/qt-creator
Imported our new GLSL front-end.
This commit is contained in:
6
src/libs/glsl/glsl-lib.pri
Normal file
6
src/libs/glsl/glsl-lib.pri
Normal file
@@ -0,0 +1,6 @@
|
||||
HEADERS += $$PWD/glsllexer.h $$PWD/glslparser.h glslparsertable_p.h $$PWD/glslast.h
|
||||
SOURCES += $$PWD/glslkeywords.cpp $$PWD/glslparser.cpp $$PWD/glslparsertable.cpp \
|
||||
$$PWD/glsllexer.cpp $$PWD/glslast.cpp $$PWD/glsldump.cpp $$PWD/glsldelete.cpp
|
||||
|
||||
OTHER_FILES = $$PWD/specs/glsl.g.in \
|
||||
$$PWD/specs/grammar.txt
|
||||
668
src/libs/glsl/glsl.g
Normal file
668
src/libs/glsl/glsl.g
Normal file
@@ -0,0 +1,668 @@
|
||||
-- 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 ERROR "error"
|
||||
|
||||
%start translation_unit
|
||||
|
||||
/:
|
||||
#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
|
||||
:/
|
||||
|
||||
/.
|
||||
#include "glslparser.h"
|
||||
#include <iostream>
|
||||
|
||||
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;
|
||||
}
|
||||
./
|
||||
variable_identifier ::= IDENTIFIER ;
|
||||
primary_expression ::= NUMBER ;
|
||||
primary_expression ::= TRUE ;
|
||||
primary_expression ::= FALSE ;
|
||||
primary_expression ::= variable_identifier ;
|
||||
primary_expression ::= LEFT_PAREN expression RIGHT_PAREN ;
|
||||
postfix_expression ::= primary_expression ;
|
||||
postfix_expression ::= postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET ;
|
||||
postfix_expression ::= function_call ;
|
||||
postfix_expression ::= postfix_expression DOT IDENTIFIER ;
|
||||
postfix_expression ::= postfix_expression INC_OP ;
|
||||
postfix_expression ::= postfix_expression DEC_OP ;
|
||||
integer_expression ::= expression ;
|
||||
function_call ::= function_call_or_method ;
|
||||
function_call_or_method ::= function_call_generic ;
|
||||
function_call_or_method ::= postfix_expression DOT function_call_generic ;
|
||||
function_call_generic ::= function_call_header_with_parameters RIGHT_PAREN ;
|
||||
function_call_generic ::= function_call_header_no_parameters RIGHT_PAREN ;
|
||||
function_call_header_no_parameters ::= function_call_header VOID ;
|
||||
function_call_header_no_parameters ::= function_call_header ;
|
||||
function_call_header_with_parameters ::= function_call_header assignment_expression ;
|
||||
function_call_header_with_parameters ::= function_call_header_with_parameters COMMA assignment_expression ;
|
||||
function_call_header ::= function_identifier LEFT_PAREN ;
|
||||
function_identifier ::= type_specifier ;
|
||||
function_identifier ::= IDENTIFIER ;
|
||||
unary_expression ::= postfix_expression ;
|
||||
unary_expression ::= INC_OP unary_expression ;
|
||||
unary_expression ::= DEC_OP unary_expression ;
|
||||
unary_expression ::= unary_operator unary_expression ;
|
||||
unary_operator ::= PLUS ;
|
||||
unary_operator ::= DASH ;
|
||||
unary_operator ::= BANG ;
|
||||
unary_operator ::= TILDE ;
|
||||
multiplicative_expression ::= unary_expression ;
|
||||
multiplicative_expression ::= multiplicative_expression STAR unary_expression ;
|
||||
multiplicative_expression ::= multiplicative_expression SLASH unary_expression ;
|
||||
multiplicative_expression ::= multiplicative_expression PERCENT unary_expression ;
|
||||
additive_expression ::= multiplicative_expression ;
|
||||
additive_expression ::= additive_expression PLUS multiplicative_expression ;
|
||||
additive_expression ::= additive_expression DASH multiplicative_expression ;
|
||||
shift_expression ::= additive_expression ;
|
||||
shift_expression ::= shift_expression LEFT_OP additive_expression ;
|
||||
shift_expression ::= shift_expression RIGHT_OP additive_expression ;
|
||||
relational_expression ::= shift_expression ;
|
||||
relational_expression ::= relational_expression LEFT_ANGLE shift_expression ;
|
||||
relational_expression ::= relational_expression RIGHT_ANGLE shift_expression ;
|
||||
relational_expression ::= relational_expression LE_OP shift_expression ;
|
||||
relational_expression ::= relational_expression GE_OP shift_expression ;
|
||||
equality_expression ::= relational_expression ;
|
||||
equality_expression ::= equality_expression EQ_OP relational_expression ;
|
||||
equality_expression ::= equality_expression NE_OP relational_expression ;
|
||||
and_expression ::= equality_expression ;
|
||||
and_expression ::= and_expression AMPERSAND equality_expression ;
|
||||
exclusive_or_expression ::= and_expression ;
|
||||
exclusive_or_expression ::= exclusive_or_expression CARET and_expression ;
|
||||
inclusive_or_expression ::= exclusive_or_expression ;
|
||||
inclusive_or_expression ::= inclusive_or_expression VERTICAL_BAR exclusive_or_expression ;
|
||||
logical_and_expression ::= inclusive_or_expression ;
|
||||
logical_and_expression ::= logical_and_expression AND_OP inclusive_or_expression ;
|
||||
logical_xor_expression ::= logical_and_expression ;
|
||||
logical_xor_expression ::= logical_xor_expression XOR_OP logical_and_expression ;
|
||||
logical_or_expression ::= logical_xor_expression ;
|
||||
logical_or_expression ::= logical_or_expression OR_OP logical_xor_expression ;
|
||||
conditional_expression ::= logical_or_expression ;
|
||||
conditional_expression ::= logical_or_expression QUESTION expression COLON assignment_expression ;
|
||||
assignment_expression ::= conditional_expression ;
|
||||
assignment_expression ::= unary_expression assignment_operator assignment_expression ;
|
||||
assignment_operator ::= EQUAL ;
|
||||
assignment_operator ::= MUL_ASSIGN ;
|
||||
assignment_operator ::= DIV_ASSIGN ;
|
||||
assignment_operator ::= MOD_ASSIGN ;
|
||||
assignment_operator ::= ADD_ASSIGN ;
|
||||
assignment_operator ::= SUB_ASSIGN ;
|
||||
assignment_operator ::= LEFT_ASSIGN ;
|
||||
assignment_operator ::= RIGHT_ASSIGN ;
|
||||
assignment_operator ::= AND_ASSIGN ;
|
||||
assignment_operator ::= XOR_ASSIGN ;
|
||||
assignment_operator ::= OR_ASSIGN ;
|
||||
expression ::= assignment_expression ;
|
||||
expression ::= expression COMMA assignment_expression ;
|
||||
constant_expression ::= conditional_expression ;
|
||||
declaration ::= function_prototype SEMICOLON ;
|
||||
declaration ::= init_declarator_list SEMICOLON ;
|
||||
declaration ::= PRECISION precision_qualifier type_specifier_no_prec SEMICOLON ;
|
||||
declaration ::= type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE SEMICOLON ;
|
||||
declaration ::= type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE IDENTIFIER SEMICOLON ;
|
||||
declaration ::= type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE IDENTIFIER LEFT_BRACKET RIGHT_BRACKET SEMICOLON ;
|
||||
declaration ::= type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET SEMICOLON ;
|
||||
declaration ::= type_qualifier SEMICOLON ;
|
||||
function_prototype ::= function_declarator RIGHT_PAREN ;
|
||||
function_declarator ::= function_header ;
|
||||
function_declarator ::= function_header_with_parameters ;
|
||||
function_header_with_parameters ::= function_header parameter_declaration ;
|
||||
function_header_with_parameters ::= function_header_with_parameters COMMA parameter_declaration ;
|
||||
function_header ::= fully_specified_type IDENTIFIER LEFT_PAREN ;
|
||||
parameter_declarator ::= type_specifier IDENTIFIER ;
|
||||
parameter_declarator ::= type_specifier IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET ;
|
||||
parameter_declaration ::= parameter_type_qualifier parameter_qualifier parameter_declarator ;
|
||||
parameter_declaration ::= parameter_qualifier parameter_declarator ;
|
||||
parameter_declaration ::= parameter_type_qualifier parameter_qualifier parameter_type_specifier ;
|
||||
parameter_declaration ::= parameter_qualifier parameter_type_specifier ;
|
||||
parameter_qualifier ::= ;
|
||||
parameter_qualifier ::= IN ;
|
||||
parameter_qualifier ::= OUT ;
|
||||
parameter_qualifier ::= INOUT ;
|
||||
parameter_type_specifier ::= type_specifier ;
|
||||
init_declarator_list ::= single_declaration ;
|
||||
init_declarator_list ::= init_declarator_list COMMA IDENTIFIER ;
|
||||
init_declarator_list ::= init_declarator_list COMMA IDENTIFIER LEFT_BRACKET RIGHT_BRACKET ;
|
||||
init_declarator_list ::= init_declarator_list COMMA IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET ;
|
||||
init_declarator_list ::= init_declarator_list COMMA IDENTIFIER LEFT_BRACKET RIGHT_BRACKET EQUAL initializer ;
|
||||
init_declarator_list ::= init_declarator_list COMMA IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer ;
|
||||
init_declarator_list ::= init_declarator_list COMMA IDENTIFIER EQUAL initializer ;
|
||||
single_declaration ::= fully_specified_type ;
|
||||
single_declaration ::= fully_specified_type IDENTIFIER ;
|
||||
single_declaration ::= fully_specified_type IDENTIFIER LEFT_BRACKET RIGHT_BRACKET ;
|
||||
single_declaration ::= fully_specified_type IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET ;
|
||||
single_declaration ::= fully_specified_type IDENTIFIER LEFT_BRACKET RIGHT_BRACKET EQUAL initializer ;
|
||||
single_declaration ::= fully_specified_type IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer ;
|
||||
single_declaration ::= fully_specified_type IDENTIFIER EQUAL initializer ;
|
||||
single_declaration ::= INVARIANT IDENTIFIER ;
|
||||
fully_specified_type ::= type_specifier ;
|
||||
fully_specified_type ::= type_qualifier type_specifier ;
|
||||
invariant_qualifier ::= INVARIANT ;
|
||||
interpolation_qualifier ::= SMOOTH ;
|
||||
interpolation_qualifier ::= FLAT ;
|
||||
interpolation_qualifier ::= NOPERSPECTIVE ;
|
||||
layout_qualifier ::= LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN ;
|
||||
layout_qualifier_id_list ::= layout_qualifier_id ;
|
||||
layout_qualifier_id_list ::= layout_qualifier_id_list COMMA layout_qualifier_id ;
|
||||
layout_qualifier_id ::= IDENTIFIER ;
|
||||
layout_qualifier_id ::= IDENTIFIER EQUAL NUMBER ;
|
||||
parameter_type_qualifier ::= CONST ;
|
||||
type_qualifier ::= storage_qualifier ;
|
||||
type_qualifier ::= layout_qualifier ;
|
||||
type_qualifier ::= layout_qualifier storage_qualifier ;
|
||||
type_qualifier ::= interpolation_qualifier storage_qualifier ;
|
||||
type_qualifier ::= interpolation_qualifier ;
|
||||
type_qualifier ::= invariant_qualifier storage_qualifier ;
|
||||
type_qualifier ::= invariant_qualifier interpolation_qualifier storage_qualifier ;
|
||||
type_qualifier ::= INVARIANT ;
|
||||
storage_qualifier ::= CONST ;
|
||||
storage_qualifier ::= ATTRIBUTE ;
|
||||
storage_qualifier ::= VARYING ;
|
||||
storage_qualifier ::= CENTROID VARYING ;
|
||||
storage_qualifier ::= IN ;
|
||||
storage_qualifier ::= OUT ;
|
||||
storage_qualifier ::= CENTROID IN ;
|
||||
storage_qualifier ::= CENTROID OUT ;
|
||||
storage_qualifier ::= PATCH IN ;
|
||||
storage_qualifier ::= PATCH OUT ;
|
||||
storage_qualifier ::= SAMPLE IN ;
|
||||
storage_qualifier ::= SAMPLE OUT ;
|
||||
storage_qualifier ::= UNIFORM ;
|
||||
type_specifier ::= type_specifier_no_prec ;
|
||||
type_specifier ::= precision_qualifier type_specifier_no_prec ;
|
||||
type_specifier_no_prec ::= type_specifier_nonarray ;
|
||||
type_specifier_no_prec ::= type_specifier_nonarray LEFT_BRACKET RIGHT_BRACKET ;
|
||||
type_specifier_no_prec ::= type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET ;
|
||||
type_specifier_nonarray ::= VOID ;
|
||||
type_specifier_nonarray ::= FLOAT ;
|
||||
type_specifier_nonarray ::= DOUBLE ;
|
||||
type_specifier_nonarray ::= INT ;
|
||||
type_specifier_nonarray ::= UINT ;
|
||||
type_specifier_nonarray ::= BOOL ;
|
||||
type_specifier_nonarray ::= VEC2 ;
|
||||
type_specifier_nonarray ::= VEC3 ;
|
||||
type_specifier_nonarray ::= VEC4 ;
|
||||
type_specifier_nonarray ::= DVEC2 ;
|
||||
type_specifier_nonarray ::= DVEC3 ;
|
||||
type_specifier_nonarray ::= DVEC4 ;
|
||||
type_specifier_nonarray ::= BVEC2 ;
|
||||
type_specifier_nonarray ::= BVEC3 ;
|
||||
type_specifier_nonarray ::= BVEC4 ;
|
||||
type_specifier_nonarray ::= IVEC2 ;
|
||||
type_specifier_nonarray ::= IVEC3 ;
|
||||
type_specifier_nonarray ::= IVEC4 ;
|
||||
type_specifier_nonarray ::= UVEC2 ;
|
||||
type_specifier_nonarray ::= UVEC3 ;
|
||||
type_specifier_nonarray ::= UVEC4 ;
|
||||
type_specifier_nonarray ::= MAT2 ;
|
||||
type_specifier_nonarray ::= MAT3 ;
|
||||
type_specifier_nonarray ::= MAT4 ;
|
||||
type_specifier_nonarray ::= MAT2X2 ;
|
||||
type_specifier_nonarray ::= MAT2X3 ;
|
||||
type_specifier_nonarray ::= MAT2X4 ;
|
||||
type_specifier_nonarray ::= MAT3X2 ;
|
||||
type_specifier_nonarray ::= MAT3X3 ;
|
||||
type_specifier_nonarray ::= MAT3X4 ;
|
||||
type_specifier_nonarray ::= MAT4X2 ;
|
||||
type_specifier_nonarray ::= MAT4X3 ;
|
||||
type_specifier_nonarray ::= MAT4X4 ;
|
||||
type_specifier_nonarray ::= DMAT2 ;
|
||||
type_specifier_nonarray ::= DMAT3 ;
|
||||
type_specifier_nonarray ::= DMAT4 ;
|
||||
type_specifier_nonarray ::= DMAT2X2 ;
|
||||
type_specifier_nonarray ::= DMAT2X3 ;
|
||||
type_specifier_nonarray ::= DMAT2X4 ;
|
||||
type_specifier_nonarray ::= DMAT3X2 ;
|
||||
type_specifier_nonarray ::= DMAT3X3 ;
|
||||
type_specifier_nonarray ::= DMAT3X4 ;
|
||||
type_specifier_nonarray ::= DMAT4X2 ;
|
||||
type_specifier_nonarray ::= DMAT4X3 ;
|
||||
type_specifier_nonarray ::= DMAT4X4 ;
|
||||
type_specifier_nonarray ::= SAMPLER1D ;
|
||||
type_specifier_nonarray ::= SAMPLER2D ;
|
||||
type_specifier_nonarray ::= SAMPLER3D ;
|
||||
type_specifier_nonarray ::= SAMPLERCUBE ;
|
||||
type_specifier_nonarray ::= SAMPLER1DSHADOW ;
|
||||
type_specifier_nonarray ::= SAMPLER2DSHADOW ;
|
||||
type_specifier_nonarray ::= SAMPLERCUBESHADOW ;
|
||||
type_specifier_nonarray ::= SAMPLER1DARRAY ;
|
||||
type_specifier_nonarray ::= SAMPLER2DARRAY ;
|
||||
type_specifier_nonarray ::= SAMPLER1DARRAYSHADOW ;
|
||||
type_specifier_nonarray ::= SAMPLER2DARRAYSHADOW ;
|
||||
type_specifier_nonarray ::= SAMPLERCUBEARRAY ;
|
||||
type_specifier_nonarray ::= SAMPLERCUBEARRAYSHADOW ;
|
||||
type_specifier_nonarray ::= ISAMPLER1D ;
|
||||
type_specifier_nonarray ::= ISAMPLER2D ;
|
||||
type_specifier_nonarray ::= ISAMPLER3D ;
|
||||
type_specifier_nonarray ::= ISAMPLERCUBE ;
|
||||
type_specifier_nonarray ::= ISAMPLER1DARRAY ;
|
||||
type_specifier_nonarray ::= ISAMPLER2DARRAY ;
|
||||
type_specifier_nonarray ::= ISAMPLERCUBEARRAY ;
|
||||
type_specifier_nonarray ::= USAMPLER1D ;
|
||||
type_specifier_nonarray ::= USAMPLER2D ;
|
||||
type_specifier_nonarray ::= USAMPLER3D ;
|
||||
type_specifier_nonarray ::= USAMPLERCUBE ;
|
||||
type_specifier_nonarray ::= USAMPLER1DARRAY ;
|
||||
type_specifier_nonarray ::= USAMPLER2DARRAY ;
|
||||
type_specifier_nonarray ::= USAMPLERCUBEARRAY ;
|
||||
type_specifier_nonarray ::= SAMPLER2DRECT ;
|
||||
type_specifier_nonarray ::= SAMPLER2DRECTSHADOW ;
|
||||
type_specifier_nonarray ::= ISAMPLER2DRECT ;
|
||||
type_specifier_nonarray ::= USAMPLER2DRECT ;
|
||||
type_specifier_nonarray ::= SAMPLERBUFFER ;
|
||||
type_specifier_nonarray ::= ISAMPLERBUFFER ;
|
||||
type_specifier_nonarray ::= USAMPLERBUFFER ;
|
||||
type_specifier_nonarray ::= SAMPLER2DMS ;
|
||||
type_specifier_nonarray ::= ISAMPLER2DMS ;
|
||||
type_specifier_nonarray ::= USAMPLER2DMS ;
|
||||
type_specifier_nonarray ::= SAMPLER2DMSARRAY ;
|
||||
type_specifier_nonarray ::= ISAMPLER2DMSARRAY ;
|
||||
type_specifier_nonarray ::= USAMPLER2DMSARRAY ;
|
||||
type_specifier_nonarray ::= struct_specifier ;
|
||||
type_specifier_nonarray ::= TYPE_NAME ;
|
||||
precision_qualifier ::= HIGHP ;
|
||||
precision_qualifier ::= MEDIUMP ;
|
||||
precision_qualifier ::= LOWP ;
|
||||
struct_specifier ::= STRUCT IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE ;
|
||||
struct_specifier ::= STRUCT LEFT_BRACE struct_declaration_list RIGHT_BRACE ;
|
||||
struct_declaration_list ::= struct_declaration ;
|
||||
struct_declaration_list ::= struct_declaration_list struct_declaration ;
|
||||
struct_declaration ::= type_specifier struct_declarator_list SEMICOLON ;
|
||||
struct_declaration ::= type_qualifier type_specifier struct_declarator_list SEMICOLON ;
|
||||
struct_declarator_list ::= struct_declarator ;
|
||||
struct_declarator_list ::= struct_declarator_list COMMA struct_declarator ;
|
||||
struct_declarator ::= IDENTIFIER ;
|
||||
struct_declarator ::= IDENTIFIER LEFT_BRACKET RIGHT_BRACKET ;
|
||||
struct_declarator ::= IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET ;
|
||||
initializer ::= assignment_expression ;
|
||||
declaration_statement ::= declaration ;
|
||||
statement ::= compound_statement ;
|
||||
statement ::= simple_statement ;
|
||||
simple_statement ::= declaration_statement ;
|
||||
simple_statement ::= expression_statement ;
|
||||
simple_statement ::= selection_statement ;
|
||||
simple_statement ::= switch_statement ;
|
||||
simple_statement ::= case_label ;
|
||||
simple_statement ::= iteration_statement ;
|
||||
simple_statement ::= jump_statement ;
|
||||
compound_statement ::= LEFT_BRACE RIGHT_BRACE ;
|
||||
compound_statement ::= LEFT_BRACE statement_list RIGHT_BRACE ;
|
||||
statement_no_new_scope ::= compound_statement_no_new_scope ;
|
||||
statement_no_new_scope ::= simple_statement ;
|
||||
compound_statement_no_new_scope ::= LEFT_BRACE RIGHT_BRACE ;
|
||||
compound_statement_no_new_scope ::= LEFT_BRACE statement_list RIGHT_BRACE ;
|
||||
statement_list ::= statement ;
|
||||
statement_list ::= statement_list statement ;
|
||||
expression_statement ::= SEMICOLON ;
|
||||
expression_statement ::= expression SEMICOLON ;
|
||||
selection_statement ::= IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement ;
|
||||
selection_rest_statement ::= statement ELSE statement ;
|
||||
selection_rest_statement ::= statement ;
|
||||
condition ::= expression ;
|
||||
condition ::= fully_specified_type IDENTIFIER EQUAL initializer ;
|
||||
switch_statement ::= SWITCH LEFT_PAREN expression RIGHT_PAREN LEFT_BRACE switch_statement_list RIGHT_BRACE ;
|
||||
switch_statement_list ::= ;
|
||||
switch_statement_list ::= statement_list ;
|
||||
case_label ::= CASE expression COLON ;
|
||||
case_label ::= DEFAULT COLON ;
|
||||
iteration_statement ::= WHILE LEFT_PAREN condition RIGHT_PAREN statement_no_new_scope ;
|
||||
iteration_statement ::= DO statement WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON ;
|
||||
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 ::= declaration_statement ;
|
||||
conditionopt ::= ;
|
||||
conditionopt ::= condition ;
|
||||
for_rest_statement ::= conditionopt SEMICOLON ;
|
||||
for_rest_statement ::= conditionopt SEMICOLON expression ;
|
||||
jump_statement ::= CONTINUE SEMICOLON ;
|
||||
jump_statement ::= BREAK SEMICOLON ;
|
||||
jump_statement ::= RETURN SEMICOLON ;
|
||||
jump_statement ::= RETURN expression SEMICOLON ;
|
||||
jump_statement ::= DISCARD SEMICOLON ;
|
||||
translation_unit ::= external_declaration ;
|
||||
translation_unit ::= translation_unit external_declaration ;
|
||||
external_declaration ::= function_definition ;
|
||||
external_declaration ::= declaration ;
|
||||
external_declaration ::= SEMICOLON ;
|
||||
function_definition ::= function_prototype compound_statement_no_new_scope ;
|
||||
9
src/libs/glsl/glsl.pro
Normal file
9
src/libs/glsl/glsl.pro
Normal file
@@ -0,0 +1,9 @@
|
||||
TEMPLATE = lib
|
||||
CONFIG += dll
|
||||
TARGET = GLSL
|
||||
DEFINES += GLSL_BUILD_DIR QT_CREATOR
|
||||
|
||||
include(../../qtcreatorlibrary.pri)
|
||||
include(glsl-lib.pri)
|
||||
include(../utils/utils.pri)
|
||||
|
||||
12
src/libs/glsl/glslast.cpp
Normal file
12
src/libs/glsl/glslast.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#include "glslast.h"
|
||||
|
||||
using namespace GLSL;
|
||||
|
||||
AST::AST()
|
||||
{
|
||||
}
|
||||
|
||||
AST::~AST()
|
||||
{
|
||||
}
|
||||
|
||||
51
src/libs/glsl/glslast.h
Normal file
51
src/libs/glsl/glslast.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifndef GLSLAST_H
|
||||
#define GLSLAST_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace GLSL {
|
||||
|
||||
class AST;
|
||||
class Operand;
|
||||
class Operator;
|
||||
|
||||
class AST
|
||||
{
|
||||
public:
|
||||
AST();
|
||||
virtual ~AST();
|
||||
|
||||
virtual Operand *asOperand() { return 0; }
|
||||
virtual Operator *asOperator() { return 0; }
|
||||
};
|
||||
|
||||
class Operand: public AST
|
||||
{
|
||||
public:
|
||||
Operand(int location)
|
||||
: location(location) {}
|
||||
|
||||
virtual Operand *asOperand() { return this; }
|
||||
|
||||
public: // attributes
|
||||
int location;
|
||||
};
|
||||
|
||||
class Operator: public AST, public std::vector<AST *>
|
||||
{
|
||||
typedef std::vector<AST *> _Base;
|
||||
|
||||
public:
|
||||
template <typename It>
|
||||
Operator(int ruleno, It begin, It end)
|
||||
: _Base(begin, end), ruleno(ruleno) {}
|
||||
|
||||
virtual Operator *asOperator() { return this; }
|
||||
|
||||
public: // attributes
|
||||
int ruleno;
|
||||
};
|
||||
|
||||
} // namespace GLSL
|
||||
|
||||
#endif // GLSLAST_H
|
||||
3471
src/libs/glsl/glsldelete.cpp
Normal file
3471
src/libs/glsl/glsldelete.cpp
Normal file
File diff suppressed because it is too large
Load Diff
3470
src/libs/glsl/glsldump.cpp
Normal file
3470
src/libs/glsl/glsldump.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1637
src/libs/glsl/glslkeywords.cpp
Normal file
1637
src/libs/glsl/glslkeywords.cpp
Normal file
File diff suppressed because it is too large
Load Diff
325
src/libs/glsl/glsllexer.cpp
Normal file
325
src/libs/glsl/glsllexer.cpp
Normal file
@@ -0,0 +1,325 @@
|
||||
|
||||
#include "glsllexer.h"
|
||||
#include "glslparser.h"
|
||||
#include <cctype>
|
||||
#include <iostream>
|
||||
|
||||
using namespace GLSL;
|
||||
|
||||
Lexer::Lexer(const char *source, unsigned size)
|
||||
: _source(source),
|
||||
_it(source),
|
||||
_end(source + size),
|
||||
_size(size),
|
||||
_yychar('\n'),
|
||||
_lineno(0),
|
||||
_variant(Variant_Mask & ~Variant_Reserved) // everything except reserved
|
||||
{
|
||||
}
|
||||
|
||||
Lexer::~Lexer()
|
||||
{
|
||||
}
|
||||
|
||||
void Lexer::yyinp()
|
||||
{
|
||||
if (_it != _end) {
|
||||
_yychar = *_it++;
|
||||
if (_yychar == '\n')
|
||||
++_lineno;
|
||||
} else
|
||||
_yychar = 0;
|
||||
}
|
||||
|
||||
int Lexer::yylex(Token *tk)
|
||||
{
|
||||
const char *pos = 0;
|
||||
int line = 0;
|
||||
const int kind = yylex_helper(&pos, &line);
|
||||
tk->kind = kind;
|
||||
tk->position = pos - _source;
|
||||
tk->length = _it - pos - 1;
|
||||
tk->line = line;
|
||||
tk->matchingBrace = 0;
|
||||
return kind;
|
||||
}
|
||||
|
||||
int Lexer::yylex_helper(const char **position, int *line)
|
||||
{
|
||||
again:
|
||||
while (std::isspace(_yychar))
|
||||
yyinp();
|
||||
|
||||
*position = _it - 1;
|
||||
*line = _lineno;
|
||||
|
||||
if (_yychar == 0)
|
||||
return Parser::EOF_SYMBOL;
|
||||
|
||||
const int ch = _yychar;
|
||||
yyinp();
|
||||
|
||||
switch (ch) {
|
||||
case '#':
|
||||
for (; _yychar; yyinp()) {
|
||||
if (_yychar == '\n')
|
||||
break;
|
||||
}
|
||||
goto again;
|
||||
|
||||
// one of `!', `!='
|
||||
case '!':
|
||||
if (_yychar == '=') {
|
||||
yyinp();
|
||||
return Parser::T_NE_OP;
|
||||
}
|
||||
return Parser::T_BANG;
|
||||
|
||||
// one of
|
||||
// %
|
||||
// %=
|
||||
case '%':
|
||||
if (_yychar == '=') {
|
||||
yyinp();
|
||||
return Parser::T_MOD_ASSIGN;
|
||||
}
|
||||
return Parser::T_PERCENT;
|
||||
|
||||
// one of
|
||||
// &
|
||||
// &&
|
||||
// &=
|
||||
case '&':
|
||||
if (_yychar == '=') {
|
||||
yyinp();
|
||||
return Parser::T_AND_ASSIGN;
|
||||
} else if (_yychar == '&') {
|
||||
yyinp();
|
||||
return Parser::T_AND_OP;
|
||||
}
|
||||
return Parser::T_AMPERSAND;
|
||||
|
||||
// (
|
||||
case '(':
|
||||
return Parser::T_LEFT_PAREN;
|
||||
|
||||
// )
|
||||
case ')':
|
||||
return Parser::T_RIGHT_PAREN;
|
||||
|
||||
// one of
|
||||
// *
|
||||
// *=
|
||||
case '*':
|
||||
if (_yychar == '=') {
|
||||
yyinp();
|
||||
return Parser::T_MUL_ASSIGN;
|
||||
}
|
||||
return Parser::T_STAR;
|
||||
|
||||
// one of
|
||||
// ++
|
||||
// +=
|
||||
// +
|
||||
case '+':
|
||||
if (_yychar == '=') {
|
||||
yyinp();
|
||||
return Parser::T_ADD_ASSIGN;
|
||||
} else if (_yychar == '+') {
|
||||
yyinp();
|
||||
return Parser::T_INC_OP;
|
||||
}
|
||||
return Parser::T_PLUS;
|
||||
|
||||
// ,
|
||||
case ',':
|
||||
return Parser::T_COMMA;
|
||||
|
||||
// one of
|
||||
// -
|
||||
// --
|
||||
// -=
|
||||
case '-':
|
||||
if (_yychar == '=') {
|
||||
yyinp();
|
||||
return Parser::T_SUB_ASSIGN;
|
||||
} else if (_yychar == '-') {
|
||||
yyinp();
|
||||
return Parser::T_DEC_OP;
|
||||
}
|
||||
return Parser::T_DASH;
|
||||
|
||||
// one of
|
||||
// .
|
||||
// float constant
|
||||
case '.':
|
||||
if (std::isdigit(_yychar)) {
|
||||
while (std::isalnum(_yychar)) {
|
||||
yyinp();
|
||||
}
|
||||
return Parser::T_NUMBER;
|
||||
}
|
||||
return Parser::T_DOT;
|
||||
|
||||
// one of
|
||||
// /
|
||||
// /=
|
||||
// comment
|
||||
case '/':
|
||||
if (_yychar == '/') {
|
||||
for (; _yychar; yyinp()) {
|
||||
if (_yychar == '\n')
|
||||
break;
|
||||
}
|
||||
goto again;
|
||||
} else if (_yychar == '*') {
|
||||
yyinp();
|
||||
while (_yychar) {
|
||||
if (_yychar == '*') {
|
||||
yyinp();
|
||||
if (_yychar == '/') {
|
||||
yyinp();
|
||||
goto again;
|
||||
}
|
||||
} else {
|
||||
yyinp();
|
||||
}
|
||||
}
|
||||
goto again;
|
||||
} else if (_yychar == '=') {
|
||||
yyinp();
|
||||
return Parser::T_DIV_ASSIGN;
|
||||
}
|
||||
return Parser::T_SLASH;
|
||||
|
||||
// :
|
||||
case ':':
|
||||
return Parser::T_COLON;
|
||||
|
||||
// ;
|
||||
case ';':
|
||||
return Parser::T_SEMICOLON;
|
||||
|
||||
// one of
|
||||
// <
|
||||
// <=
|
||||
// <<
|
||||
// <<=
|
||||
case '<':
|
||||
if (_yychar == '=') {
|
||||
yyinp();
|
||||
return Parser::T_LE_OP;
|
||||
} else if (_yychar == '<') {
|
||||
yyinp();
|
||||
if (_yychar == '=') {
|
||||
yyinp();
|
||||
return Parser::T_LEFT_ASSIGN;
|
||||
}
|
||||
return Parser::T_LEFT_OP;
|
||||
}
|
||||
return Parser::T_LEFT_ANGLE;
|
||||
|
||||
// one of
|
||||
// =
|
||||
// ==
|
||||
case '=':
|
||||
if (_yychar == '=') {
|
||||
yyinp();
|
||||
return Parser::T_EQ_OP;
|
||||
}
|
||||
return Parser::T_EQUAL;
|
||||
|
||||
// one of
|
||||
// >
|
||||
// >=
|
||||
// >>=
|
||||
// >>
|
||||
case '>':
|
||||
if (_yychar == '=') {
|
||||
yyinp();
|
||||
return Parser::T_GE_OP;
|
||||
} else if (_yychar == '>') {
|
||||
yyinp();
|
||||
if (_yychar == '=') {
|
||||
yyinp();
|
||||
return Parser::T_RIGHT_ASSIGN;
|
||||
}
|
||||
return Parser::T_RIGHT_OP;
|
||||
}
|
||||
return Parser::T_RIGHT_ANGLE;
|
||||
|
||||
// ?
|
||||
case '?':
|
||||
return Parser::T_QUESTION;
|
||||
|
||||
// [
|
||||
case '[':
|
||||
return Parser::T_LEFT_BRACKET;
|
||||
|
||||
// ]
|
||||
case ']':
|
||||
return Parser::T_RIGHT_BRACKET;
|
||||
|
||||
// one of
|
||||
// ^
|
||||
// ^=
|
||||
case '^':
|
||||
if (_yychar == '=') {
|
||||
yyinp();
|
||||
return Parser::T_XOR_ASSIGN;
|
||||
}
|
||||
return Parser::T_XOR_OP;
|
||||
|
||||
// {
|
||||
case '{':
|
||||
return Parser::T_LEFT_BRACE;
|
||||
|
||||
// one of
|
||||
// |
|
||||
// |=
|
||||
// ||
|
||||
case '|':
|
||||
if (_yychar == '=') {
|
||||
yyinp();
|
||||
return Parser::T_OR_ASSIGN;
|
||||
} else if (_yychar == '|') {
|
||||
yyinp();
|
||||
return Parser::T_OR_OP;
|
||||
}
|
||||
return Parser::T_VERTICAL_BAR;
|
||||
|
||||
// }
|
||||
case '}':
|
||||
return Parser::T_RIGHT_BRACE;
|
||||
|
||||
// ~
|
||||
case '~':
|
||||
return Parser::T_TILDE;
|
||||
|
||||
default:
|
||||
if (std::isalpha(ch) || ch == '_') {
|
||||
const char *word = _it - 2;
|
||||
while (std::isalnum(_yychar) || _yychar == '_') {
|
||||
yyinp();
|
||||
}
|
||||
int t = classify(word, _it - word -1);
|
||||
if (!(t & Variant_Mask))
|
||||
return t;
|
||||
if ((_variant & t & Variant_Mask) == 0) {
|
||||
// TODO: issue a proper error for the unsupported keyword
|
||||
std::string keyword(word, _it - word -1);
|
||||
fprintf(stderr, "unsupported keyword `%s' at line %d\n",
|
||||
keyword.c_str(), _lineno);
|
||||
}
|
||||
return t & ~Variant_Mask;
|
||||
} else if (std::isdigit(ch)) {
|
||||
while (std::isalnum(_yychar) || _yychar == '.') {
|
||||
yyinp();
|
||||
}
|
||||
return Parser::T_NUMBER;
|
||||
}
|
||||
|
||||
} // switch
|
||||
|
||||
return Parser::T_ERROR;
|
||||
}
|
||||
70
src/libs/glsl/glsllexer.h
Normal file
70
src/libs/glsl/glsllexer.h
Normal file
@@ -0,0 +1,70 @@
|
||||
#ifndef GLSLLEXER_H
|
||||
#define GLSLLEXER_H
|
||||
|
||||
namespace GLSL {
|
||||
|
||||
class Token
|
||||
{
|
||||
public:
|
||||
int kind;
|
||||
int position;
|
||||
int length;
|
||||
int line; // ### remove
|
||||
|
||||
union {
|
||||
int matchingBrace;
|
||||
void *ptr;
|
||||
};
|
||||
|
||||
Token()
|
||||
: kind(0), position(0), length(0), line(0), ptr(0) {}
|
||||
|
||||
bool is(int k) const { return k == kind; }
|
||||
bool isNot(int k) const { return k != kind; }
|
||||
};
|
||||
|
||||
class Lexer
|
||||
{
|
||||
public:
|
||||
Lexer(const char *source, unsigned size);
|
||||
~Lexer();
|
||||
|
||||
enum
|
||||
{
|
||||
// Extra flag bits added to tokens by Lexer::classify() that
|
||||
// indicate which variant of GLSL the keyword belongs to.
|
||||
Variant_GLSL_120 = 0x00010000, // 1.20 and higher
|
||||
Variant_GLSL_150 = 0x00020000, // 1.50 and higher
|
||||
Variant_GLSL_400 = 0x00040000, // 4.00 and higher
|
||||
Variant_GLSL_ES_100 = 0x00080000, // ES 1.00 and higher
|
||||
Variant_GLSL_Qt = 0x00100000,
|
||||
Variant_VertexShader = 0x00200000,
|
||||
Variant_FragmentShader = 0x00400000,
|
||||
Variant_Reserved = 0x80000000,
|
||||
Variant_Mask = 0xFFFF0000
|
||||
};
|
||||
|
||||
int variant() const { return _variant; }
|
||||
void setVariant(int flags) { _variant = flags; }
|
||||
|
||||
int yylex(Token *tk);
|
||||
|
||||
private:
|
||||
static int classify(const char *s, int len);
|
||||
|
||||
void yyinp();
|
||||
int yylex_helper(const char **position, int *line);
|
||||
|
||||
private:
|
||||
const char *_source;
|
||||
const char *_it;
|
||||
const char *_end;
|
||||
int _size;
|
||||
int _yychar;
|
||||
int _lineno;
|
||||
int _variant;
|
||||
};
|
||||
|
||||
} // end of namespace GLSL
|
||||
|
||||
#endif // GLSLLEXER_H
|
||||
141
src/libs/glsl/glslparser.cpp
Normal file
141
src/libs/glsl/glslparser.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
|
||||
#include "glslparser.h"
|
||||
#include <iostream>
|
||||
|
||||
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;
|
||||
}
|
||||
33
src/libs/glsl/glslparser.h
Normal file
33
src/libs/glsl/glslparser.h
Normal file
@@ -0,0 +1,33 @@
|
||||
|
||||
#include "glslparsertable_p.h"
|
||||
#include "glsllexer.h"
|
||||
#include "glslast.h"
|
||||
#include <vector>
|
||||
#include <stack>
|
||||
|
||||
namespace GLSL {
|
||||
|
||||
class Parser: public GLSLParserTable
|
||||
{
|
||||
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
|
||||
1264
src/libs/glsl/glslparsertable.cpp
Normal file
1264
src/libs/glsl/glslparsertable.cpp
Normal file
File diff suppressed because it is too large
Load Diff
222
src/libs/glsl/glslparsertable_p.h
Normal file
222
src/libs/glsl/glslparsertable_p.h
Normal file
@@ -0,0 +1,222 @@
|
||||
// This file was generated by qlalr - DO NOT EDIT!
|
||||
#ifndef GLSLPARSERTABLE_P_H
|
||||
#define GLSLPARSERTABLE_P_H
|
||||
|
||||
class GLSLParserTable
|
||||
{
|
||||
public:
|
||||
enum VariousConstants {
|
||||
EOF_SYMBOL = 0,
|
||||
T_ADD_ASSIGN = 1,
|
||||
T_AMPERSAND = 2,
|
||||
T_AND_ASSIGN = 3,
|
||||
T_AND_OP = 4,
|
||||
T_ATTRIBUTE = 5,
|
||||
T_BANG = 6,
|
||||
T_BOOL = 7,
|
||||
T_BREAK = 8,
|
||||
T_BVEC2 = 9,
|
||||
T_BVEC3 = 10,
|
||||
T_BVEC4 = 11,
|
||||
T_CARET = 12,
|
||||
T_CASE = 13,
|
||||
T_CENTROID = 14,
|
||||
T_COLON = 15,
|
||||
T_COMMA = 16,
|
||||
T_CONST = 17,
|
||||
T_CONTINUE = 18,
|
||||
T_DASH = 19,
|
||||
T_DEC_OP = 20,
|
||||
T_DEFAULT = 21,
|
||||
T_DISCARD = 22,
|
||||
T_DIV_ASSIGN = 23,
|
||||
T_DMAT2 = 24,
|
||||
T_DMAT2X2 = 25,
|
||||
T_DMAT2X3 = 26,
|
||||
T_DMAT2X4 = 27,
|
||||
T_DMAT3 = 28,
|
||||
T_DMAT3X2 = 29,
|
||||
T_DMAT3X3 = 30,
|
||||
T_DMAT3X4 = 31,
|
||||
T_DMAT4 = 32,
|
||||
T_DMAT4X2 = 33,
|
||||
T_DMAT4X3 = 34,
|
||||
T_DMAT4X4 = 35,
|
||||
T_DO = 36,
|
||||
T_DOT = 37,
|
||||
T_DOUBLE = 38,
|
||||
T_DVEC2 = 39,
|
||||
T_DVEC3 = 40,
|
||||
T_DVEC4 = 41,
|
||||
T_ELSE = 42,
|
||||
T_EQUAL = 43,
|
||||
T_EQ_OP = 44,
|
||||
T_ERROR = 169,
|
||||
T_FALSE = 168,
|
||||
T_FLAT = 45,
|
||||
T_FLOAT = 46,
|
||||
T_FOR = 47,
|
||||
T_GE_OP = 48,
|
||||
T_HIGHP = 49,
|
||||
T_IDENTIFIER = 50,
|
||||
T_IF = 51,
|
||||
T_IN = 52,
|
||||
T_INC_OP = 53,
|
||||
T_INOUT = 54,
|
||||
T_INT = 55,
|
||||
T_INVARIANT = 56,
|
||||
T_ISAMPLER1D = 57,
|
||||
T_ISAMPLER1DARRAY = 58,
|
||||
T_ISAMPLER2D = 59,
|
||||
T_ISAMPLER2DARRAY = 60,
|
||||
T_ISAMPLER2DMS = 61,
|
||||
T_ISAMPLER2DMSARRAY = 62,
|
||||
T_ISAMPLER2DRECT = 63,
|
||||
T_ISAMPLER3D = 64,
|
||||
T_ISAMPLERBUFFER = 65,
|
||||
T_ISAMPLERCUBE = 66,
|
||||
T_ISAMPLERCUBEARRAY = 67,
|
||||
T_IVEC2 = 68,
|
||||
T_IVEC3 = 69,
|
||||
T_IVEC4 = 70,
|
||||
T_LAYOUT = 71,
|
||||
T_LEFT_ANGLE = 72,
|
||||
T_LEFT_ASSIGN = 73,
|
||||
T_LEFT_BRACE = 74,
|
||||
T_LEFT_BRACKET = 75,
|
||||
T_LEFT_OP = 76,
|
||||
T_LEFT_PAREN = 77,
|
||||
T_LE_OP = 78,
|
||||
T_LOWP = 79,
|
||||
T_MAT2 = 80,
|
||||
T_MAT2X2 = 81,
|
||||
T_MAT2X3 = 82,
|
||||
T_MAT2X4 = 83,
|
||||
T_MAT3 = 84,
|
||||
T_MAT3X2 = 85,
|
||||
T_MAT3X3 = 86,
|
||||
T_MAT3X4 = 87,
|
||||
T_MAT4 = 88,
|
||||
T_MAT4X2 = 89,
|
||||
T_MAT4X3 = 90,
|
||||
T_MAT4X4 = 91,
|
||||
T_MEDIUMP = 92,
|
||||
T_MOD_ASSIGN = 93,
|
||||
T_MUL_ASSIGN = 94,
|
||||
T_NE_OP = 95,
|
||||
T_NOPERSPECTIVE = 96,
|
||||
T_NUMBER = 97,
|
||||
T_OR_ASSIGN = 98,
|
||||
T_OR_OP = 99,
|
||||
T_OUT = 100,
|
||||
T_PATCH = 101,
|
||||
T_PERCENT = 102,
|
||||
T_PLUS = 103,
|
||||
T_PRECISION = 104,
|
||||
T_QUESTION = 105,
|
||||
T_RETURN = 106,
|
||||
T_RIGHT_ANGLE = 107,
|
||||
T_RIGHT_ASSIGN = 108,
|
||||
T_RIGHT_BRACE = 109,
|
||||
T_RIGHT_BRACKET = 110,
|
||||
T_RIGHT_OP = 111,
|
||||
T_RIGHT_PAREN = 112,
|
||||
T_SAMPLE = 113,
|
||||
T_SAMPLER1D = 114,
|
||||
T_SAMPLER1DARRAY = 115,
|
||||
T_SAMPLER1DARRAYSHADOW = 116,
|
||||
T_SAMPLER1DSHADOW = 117,
|
||||
T_SAMPLER2D = 118,
|
||||
T_SAMPLER2DARRAY = 119,
|
||||
T_SAMPLER2DARRAYSHADOW = 120,
|
||||
T_SAMPLER2DMS = 121,
|
||||
T_SAMPLER2DMSARRAY = 122,
|
||||
T_SAMPLER2DRECT = 123,
|
||||
T_SAMPLER2DRECTSHADOW = 124,
|
||||
T_SAMPLER2DSHADOW = 125,
|
||||
T_SAMPLER3D = 126,
|
||||
T_SAMPLERBUFFER = 127,
|
||||
T_SAMPLERCUBE = 128,
|
||||
T_SAMPLERCUBEARRAY = 129,
|
||||
T_SAMPLERCUBEARRAYSHADOW = 130,
|
||||
T_SAMPLERCUBESHADOW = 131,
|
||||
T_SEMICOLON = 132,
|
||||
T_SLASH = 133,
|
||||
T_SMOOTH = 134,
|
||||
T_STAR = 135,
|
||||
T_STRUCT = 136,
|
||||
T_SUBROUTINE = 137,
|
||||
T_SUB_ASSIGN = 138,
|
||||
T_SWITCH = 139,
|
||||
T_TILDE = 140,
|
||||
T_TRUE = 167,
|
||||
T_TYPE_NAME = 141,
|
||||
T_UINT = 142,
|
||||
T_UNIFORM = 143,
|
||||
T_USAMPLER1D = 144,
|
||||
T_USAMPLER1DARRAY = 145,
|
||||
T_USAMPLER2D = 146,
|
||||
T_USAMPLER2DARRAY = 147,
|
||||
T_USAMPLER2DMS = 148,
|
||||
T_USAMPLER2DMSARRAY = 149,
|
||||
T_USAMPLER2DRECT = 150,
|
||||
T_USAMPLER3D = 151,
|
||||
T_USAMPLERBUFFER = 152,
|
||||
T_USAMPLERCUBE = 153,
|
||||
T_USAMPLERCUBEARRAY = 154,
|
||||
T_UVEC2 = 155,
|
||||
T_UVEC3 = 156,
|
||||
T_UVEC4 = 157,
|
||||
T_VARYING = 158,
|
||||
T_VEC2 = 159,
|
||||
T_VEC3 = 160,
|
||||
T_VEC4 = 161,
|
||||
T_VERTICAL_BAR = 162,
|
||||
T_VOID = 163,
|
||||
T_WHILE = 164,
|
||||
T_XOR_ASSIGN = 165,
|
||||
T_XOR_OP = 166,
|
||||
|
||||
ACCEPT_STATE = 435,
|
||||
RULE_COUNT = 312,
|
||||
STATE_COUNT = 455,
|
||||
TERMINAL_COUNT = 170,
|
||||
NON_TERMINAL_COUNT = 82,
|
||||
|
||||
GOTO_INDEX_OFFSET = 455,
|
||||
GOTO_INFO_OFFSET = 4753,
|
||||
GOTO_CHECK_OFFSET = 4753
|
||||
};
|
||||
|
||||
static const char *const spell [];
|
||||
static const short lhs [];
|
||||
static const short rhs [];
|
||||
static const short goto_default [];
|
||||
static const short action_default [];
|
||||
static const short action_index [];
|
||||
static const short action_info [];
|
||||
static const short action_check [];
|
||||
|
||||
static inline int nt_action (int state, int nt)
|
||||
{
|
||||
const int yyn = action_index [GOTO_INDEX_OFFSET + state] + nt;
|
||||
if (yyn < 0 || action_check [GOTO_CHECK_OFFSET + yyn] != nt)
|
||||
return goto_default [nt];
|
||||
|
||||
return action_info [GOTO_INFO_OFFSET + yyn];
|
||||
}
|
||||
|
||||
static inline int t_action (int state, int token)
|
||||
{
|
||||
const int yyn = action_index [state] + token;
|
||||
|
||||
if (yyn < 0 || action_check [yyn] != token)
|
||||
return - action_default [state];
|
||||
|
||||
return action_info [yyn];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // GLSLPARSERTABLE_P_H
|
||||
|
||||
6
src/libs/glsl/make-parser.sh
Executable file
6
src/libs/glsl/make-parser.sh
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
me=$(dirname $0)
|
||||
cat $me/specs/glsl.g.in $me/specs/grammar.txt > $me/glsl.g
|
||||
qlalr --no-lines --no-debug $me/glsl.g
|
||||
|
||||
357
src/libs/glsl/specs/glsl.g.in
Normal file
357
src/libs/glsl/specs/glsl.g.in
Normal file
@@ -0,0 +1,357 @@
|
||||
-- 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 ERROR "error"
|
||||
|
||||
%start translation_unit
|
||||
|
||||
/:
|
||||
#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
|
||||
:/
|
||||
|
||||
/.
|
||||
#include "glslparser.h"
|
||||
#include <iostream>
|
||||
|
||||
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;
|
||||
}
|
||||
./
|
||||
134
src/libs/glsl/specs/glsl.keywords
Normal file
134
src/libs/glsl/specs/glsl.keywords
Normal file
@@ -0,0 +1,134 @@
|
||||
#include "glsllexer.h"
|
||||
#include "glslparser.h"
|
||||
|
||||
%no-enums
|
||||
%token-prefix=T_
|
||||
%toupper
|
||||
%namespace=Parser
|
||||
%lexer-class=Lexer
|
||||
%variant-prefix=Lexer::Variant_
|
||||
|
||||
using namespace GLSL;
|
||||
|
||||
%%
|
||||
|
||||
attribute %variant VertexShader
|
||||
bool
|
||||
break
|
||||
bvec2
|
||||
bvec3
|
||||
bvec4
|
||||
case %variant GLSL_150
|
||||
centroid %variant GLSL_120
|
||||
const
|
||||
continue
|
||||
default %variant GLSL_150
|
||||
discard %variant FragmentShader
|
||||
dmat2 %variant GLSL_400
|
||||
dmat2x2 %variant GLSL_400
|
||||
dmat2x3 %variant GLSL_400
|
||||
dmat2x4 %variant GLSL_400
|
||||
dmat3 %variant GLSL_400
|
||||
dmat3x2 %variant GLSL_400
|
||||
dmat3x3 %variant GLSL_400
|
||||
dmat3x4 %variant GLSL_400
|
||||
dmat4 %variant GLSL_400
|
||||
dmat4x2 %variant GLSL_400
|
||||
dmat4x3 %variant GLSL_400
|
||||
dmat4x4 %variant GLSL_400
|
||||
do
|
||||
double %variant GLSL_400
|
||||
dvec2 %variant GLSL_400
|
||||
dvec3 %variant GLSL_400
|
||||
dvec4 %variant GLSL_400
|
||||
else
|
||||
flat %variant GLSL_150
|
||||
float
|
||||
for
|
||||
highp %variant GLSL_Qt | GLSL_ES_100 | GLSL_400
|
||||
if
|
||||
in
|
||||
inout
|
||||
int
|
||||
invariant
|
||||
isampler1D %variant GLSL_150
|
||||
isampler1DArray %variant GLSL_150
|
||||
isampler2D %variant GLSL_150
|
||||
isampler2DArray %variant GLSL_150
|
||||
isampler2DMS %variant GLSL_150
|
||||
isampler2DMSArray %variant GLSL_150
|
||||
isampler2DRect %variant GLSL_150
|
||||
isampler3D %variant GLSL_150
|
||||
isamplerBuffer %variant GLSL_150
|
||||
isamplerCube %variant GLSL_150
|
||||
isamplerCubeArray %variant GLSL_400
|
||||
ivec2
|
||||
ivec3
|
||||
ivec4
|
||||
layout %variant GLSL_150
|
||||
lowp %variant GLSL_Qt | GLSL_ES_100 | GLSL_400
|
||||
mat2
|
||||
mat2x2 %variant GLSL_120
|
||||
mat2x3 %variant GLSL_120
|
||||
mat2x4 %variant GLSL_120
|
||||
mat3
|
||||
mat3x2 %variant GLSL_120
|
||||
mat3x3 %variant GLSL_120
|
||||
mat3x4 %variant GLSL_120
|
||||
mat4
|
||||
mat4x2 %variant GLSL_120
|
||||
mat4x3 %variant GLSL_120
|
||||
mat4x4 %variant GLSL_120
|
||||
mediump %variant GLSL_Qt | GLSL_ES_100 | GLSL_400
|
||||
noperspective %variant GLSL_150
|
||||
out
|
||||
patch %variant GLSL_400
|
||||
precision %variant GLSL_ES_100
|
||||
return
|
||||
sample %variant Reserved
|
||||
sampler1D %variant GLSL_120
|
||||
sampler1DArray %variant GLSL_150
|
||||
sampler1DArrayShadow %variant GLSL_150
|
||||
sampler1DShadow %variant GLSL_120
|
||||
sampler2D
|
||||
sampler2DArray %variant GLSL_150
|
||||
sampler2DArrayShadow %variant GLSL_150
|
||||
sampler2DMS %variant GLSL_150
|
||||
sampler2DMSArray %variant GLSL_150
|
||||
sampler2DRect %variang GLSL_150
|
||||
sampler2DRectShadow %variang GLSL_150
|
||||
sampler2DShadow %variant GLSL_120
|
||||
sampler3D %variant GLSL_120
|
||||
samplerBuffer %variant GLSL_150
|
||||
samplerCube
|
||||
samplerCubeArray %variant GLSL_400
|
||||
samplerCubeArrayShadow %variant GLSL_400
|
||||
samplerCubeShadow %variant GLSL_400
|
||||
smooth %variant GLSL_150
|
||||
struct
|
||||
subroutine %variant GLSL_400
|
||||
switch %variant GLSL_150
|
||||
uint %variant GLSL_150
|
||||
uniform
|
||||
usampler1D %variant GLSL_150
|
||||
usampler1DArray %variant GLSL_150
|
||||
usampler2D %variant GLSL_150
|
||||
usampler2DArray %variant GLSL_150
|
||||
usampler2DMS %variant GLSL_150
|
||||
usampler2DMSarray %variant GLSL_150
|
||||
usampler2DRect %variant GLSL_150
|
||||
usampler3D %variant GLSL_150
|
||||
usamplerBuffer %variant GLSL_150
|
||||
usamplerCube %variant GLSL_150
|
||||
usamplerCubeArray %variant GLSL_400
|
||||
uvec2 %variant GLSL_150
|
||||
uvec3 %variant GLSL_150
|
||||
uvec4 %variant GLSL_150
|
||||
varying
|
||||
vec2
|
||||
vec3
|
||||
vec4
|
||||
void
|
||||
while
|
||||
true
|
||||
false
|
||||
311
src/libs/glsl/specs/grammar.txt
Normal file
311
src/libs/glsl/specs/grammar.txt
Normal file
@@ -0,0 +1,311 @@
|
||||
variable_identifier ::= IDENTIFIER ;
|
||||
primary_expression ::= NUMBER ;
|
||||
primary_expression ::= TRUE ;
|
||||
primary_expression ::= FALSE ;
|
||||
primary_expression ::= variable_identifier ;
|
||||
primary_expression ::= LEFT_PAREN expression RIGHT_PAREN ;
|
||||
postfix_expression ::= primary_expression ;
|
||||
postfix_expression ::= postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET ;
|
||||
postfix_expression ::= function_call ;
|
||||
postfix_expression ::= postfix_expression DOT IDENTIFIER ;
|
||||
postfix_expression ::= postfix_expression INC_OP ;
|
||||
postfix_expression ::= postfix_expression DEC_OP ;
|
||||
integer_expression ::= expression ;
|
||||
function_call ::= function_call_or_method ;
|
||||
function_call_or_method ::= function_call_generic ;
|
||||
function_call_or_method ::= postfix_expression DOT function_call_generic ;
|
||||
function_call_generic ::= function_call_header_with_parameters RIGHT_PAREN ;
|
||||
function_call_generic ::= function_call_header_no_parameters RIGHT_PAREN ;
|
||||
function_call_header_no_parameters ::= function_call_header VOID ;
|
||||
function_call_header_no_parameters ::= function_call_header ;
|
||||
function_call_header_with_parameters ::= function_call_header assignment_expression ;
|
||||
function_call_header_with_parameters ::= function_call_header_with_parameters COMMA assignment_expression ;
|
||||
function_call_header ::= function_identifier LEFT_PAREN ;
|
||||
function_identifier ::= type_specifier ;
|
||||
function_identifier ::= IDENTIFIER ;
|
||||
unary_expression ::= postfix_expression ;
|
||||
unary_expression ::= INC_OP unary_expression ;
|
||||
unary_expression ::= DEC_OP unary_expression ;
|
||||
unary_expression ::= unary_operator unary_expression ;
|
||||
unary_operator ::= PLUS ;
|
||||
unary_operator ::= DASH ;
|
||||
unary_operator ::= BANG ;
|
||||
unary_operator ::= TILDE ;
|
||||
multiplicative_expression ::= unary_expression ;
|
||||
multiplicative_expression ::= multiplicative_expression STAR unary_expression ;
|
||||
multiplicative_expression ::= multiplicative_expression SLASH unary_expression ;
|
||||
multiplicative_expression ::= multiplicative_expression PERCENT unary_expression ;
|
||||
additive_expression ::= multiplicative_expression ;
|
||||
additive_expression ::= additive_expression PLUS multiplicative_expression ;
|
||||
additive_expression ::= additive_expression DASH multiplicative_expression ;
|
||||
shift_expression ::= additive_expression ;
|
||||
shift_expression ::= shift_expression LEFT_OP additive_expression ;
|
||||
shift_expression ::= shift_expression RIGHT_OP additive_expression ;
|
||||
relational_expression ::= shift_expression ;
|
||||
relational_expression ::= relational_expression LEFT_ANGLE shift_expression ;
|
||||
relational_expression ::= relational_expression RIGHT_ANGLE shift_expression ;
|
||||
relational_expression ::= relational_expression LE_OP shift_expression ;
|
||||
relational_expression ::= relational_expression GE_OP shift_expression ;
|
||||
equality_expression ::= relational_expression ;
|
||||
equality_expression ::= equality_expression EQ_OP relational_expression ;
|
||||
equality_expression ::= equality_expression NE_OP relational_expression ;
|
||||
and_expression ::= equality_expression ;
|
||||
and_expression ::= and_expression AMPERSAND equality_expression ;
|
||||
exclusive_or_expression ::= and_expression ;
|
||||
exclusive_or_expression ::= exclusive_or_expression CARET and_expression ;
|
||||
inclusive_or_expression ::= exclusive_or_expression ;
|
||||
inclusive_or_expression ::= inclusive_or_expression VERTICAL_BAR exclusive_or_expression ;
|
||||
logical_and_expression ::= inclusive_or_expression ;
|
||||
logical_and_expression ::= logical_and_expression AND_OP inclusive_or_expression ;
|
||||
logical_xor_expression ::= logical_and_expression ;
|
||||
logical_xor_expression ::= logical_xor_expression XOR_OP logical_and_expression ;
|
||||
logical_or_expression ::= logical_xor_expression ;
|
||||
logical_or_expression ::= logical_or_expression OR_OP logical_xor_expression ;
|
||||
conditional_expression ::= logical_or_expression ;
|
||||
conditional_expression ::= logical_or_expression QUESTION expression COLON assignment_expression ;
|
||||
assignment_expression ::= conditional_expression ;
|
||||
assignment_expression ::= unary_expression assignment_operator assignment_expression ;
|
||||
assignment_operator ::= EQUAL ;
|
||||
assignment_operator ::= MUL_ASSIGN ;
|
||||
assignment_operator ::= DIV_ASSIGN ;
|
||||
assignment_operator ::= MOD_ASSIGN ;
|
||||
assignment_operator ::= ADD_ASSIGN ;
|
||||
assignment_operator ::= SUB_ASSIGN ;
|
||||
assignment_operator ::= LEFT_ASSIGN ;
|
||||
assignment_operator ::= RIGHT_ASSIGN ;
|
||||
assignment_operator ::= AND_ASSIGN ;
|
||||
assignment_operator ::= XOR_ASSIGN ;
|
||||
assignment_operator ::= OR_ASSIGN ;
|
||||
expression ::= assignment_expression ;
|
||||
expression ::= expression COMMA assignment_expression ;
|
||||
constant_expression ::= conditional_expression ;
|
||||
declaration ::= function_prototype SEMICOLON ;
|
||||
declaration ::= init_declarator_list SEMICOLON ;
|
||||
declaration ::= PRECISION precision_qualifier type_specifier_no_prec SEMICOLON ;
|
||||
declaration ::= type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE SEMICOLON ;
|
||||
declaration ::= type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE IDENTIFIER SEMICOLON ;
|
||||
declaration ::= type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE IDENTIFIER LEFT_BRACKET RIGHT_BRACKET SEMICOLON ;
|
||||
declaration ::= type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET SEMICOLON ;
|
||||
declaration ::= type_qualifier SEMICOLON ;
|
||||
function_prototype ::= function_declarator RIGHT_PAREN ;
|
||||
function_declarator ::= function_header ;
|
||||
function_declarator ::= function_header_with_parameters ;
|
||||
function_header_with_parameters ::= function_header parameter_declaration ;
|
||||
function_header_with_parameters ::= function_header_with_parameters COMMA parameter_declaration ;
|
||||
function_header ::= fully_specified_type IDENTIFIER LEFT_PAREN ;
|
||||
parameter_declarator ::= type_specifier IDENTIFIER ;
|
||||
parameter_declarator ::= type_specifier IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET ;
|
||||
parameter_declaration ::= parameter_type_qualifier parameter_qualifier parameter_declarator ;
|
||||
parameter_declaration ::= parameter_qualifier parameter_declarator ;
|
||||
parameter_declaration ::= parameter_type_qualifier parameter_qualifier parameter_type_specifier ;
|
||||
parameter_declaration ::= parameter_qualifier parameter_type_specifier ;
|
||||
parameter_qualifier ::= ;
|
||||
parameter_qualifier ::= IN ;
|
||||
parameter_qualifier ::= OUT ;
|
||||
parameter_qualifier ::= INOUT ;
|
||||
parameter_type_specifier ::= type_specifier ;
|
||||
init_declarator_list ::= single_declaration ;
|
||||
init_declarator_list ::= init_declarator_list COMMA IDENTIFIER ;
|
||||
init_declarator_list ::= init_declarator_list COMMA IDENTIFIER LEFT_BRACKET RIGHT_BRACKET ;
|
||||
init_declarator_list ::= init_declarator_list COMMA IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET ;
|
||||
init_declarator_list ::= init_declarator_list COMMA IDENTIFIER LEFT_BRACKET RIGHT_BRACKET EQUAL initializer ;
|
||||
init_declarator_list ::= init_declarator_list COMMA IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer ;
|
||||
init_declarator_list ::= init_declarator_list COMMA IDENTIFIER EQUAL initializer ;
|
||||
single_declaration ::= fully_specified_type ;
|
||||
single_declaration ::= fully_specified_type IDENTIFIER ;
|
||||
single_declaration ::= fully_specified_type IDENTIFIER LEFT_BRACKET RIGHT_BRACKET ;
|
||||
single_declaration ::= fully_specified_type IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET ;
|
||||
single_declaration ::= fully_specified_type IDENTIFIER LEFT_BRACKET RIGHT_BRACKET EQUAL initializer ;
|
||||
single_declaration ::= fully_specified_type IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer ;
|
||||
single_declaration ::= fully_specified_type IDENTIFIER EQUAL initializer ;
|
||||
single_declaration ::= INVARIANT IDENTIFIER ;
|
||||
fully_specified_type ::= type_specifier ;
|
||||
fully_specified_type ::= type_qualifier type_specifier ;
|
||||
invariant_qualifier ::= INVARIANT ;
|
||||
interpolation_qualifier ::= SMOOTH ;
|
||||
interpolation_qualifier ::= FLAT ;
|
||||
interpolation_qualifier ::= NOPERSPECTIVE ;
|
||||
layout_qualifier ::= LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN ;
|
||||
layout_qualifier_id_list ::= layout_qualifier_id ;
|
||||
layout_qualifier_id_list ::= layout_qualifier_id_list COMMA layout_qualifier_id ;
|
||||
layout_qualifier_id ::= IDENTIFIER ;
|
||||
layout_qualifier_id ::= IDENTIFIER EQUAL NUMBER ;
|
||||
parameter_type_qualifier ::= CONST ;
|
||||
type_qualifier ::= storage_qualifier ;
|
||||
type_qualifier ::= layout_qualifier ;
|
||||
type_qualifier ::= layout_qualifier storage_qualifier ;
|
||||
type_qualifier ::= interpolation_qualifier storage_qualifier ;
|
||||
type_qualifier ::= interpolation_qualifier ;
|
||||
type_qualifier ::= invariant_qualifier storage_qualifier ;
|
||||
type_qualifier ::= invariant_qualifier interpolation_qualifier storage_qualifier ;
|
||||
type_qualifier ::= INVARIANT ;
|
||||
storage_qualifier ::= CONST ;
|
||||
storage_qualifier ::= ATTRIBUTE ;
|
||||
storage_qualifier ::= VARYING ;
|
||||
storage_qualifier ::= CENTROID VARYING ;
|
||||
storage_qualifier ::= IN ;
|
||||
storage_qualifier ::= OUT ;
|
||||
storage_qualifier ::= CENTROID IN ;
|
||||
storage_qualifier ::= CENTROID OUT ;
|
||||
storage_qualifier ::= PATCH IN ;
|
||||
storage_qualifier ::= PATCH OUT ;
|
||||
storage_qualifier ::= SAMPLE IN ;
|
||||
storage_qualifier ::= SAMPLE OUT ;
|
||||
storage_qualifier ::= UNIFORM ;
|
||||
type_specifier ::= type_specifier_no_prec ;
|
||||
type_specifier ::= precision_qualifier type_specifier_no_prec ;
|
||||
type_specifier_no_prec ::= type_specifier_nonarray ;
|
||||
type_specifier_no_prec ::= type_specifier_nonarray LEFT_BRACKET RIGHT_BRACKET ;
|
||||
type_specifier_no_prec ::= type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET ;
|
||||
type_specifier_nonarray ::= VOID ;
|
||||
type_specifier_nonarray ::= FLOAT ;
|
||||
type_specifier_nonarray ::= DOUBLE ;
|
||||
type_specifier_nonarray ::= INT ;
|
||||
type_specifier_nonarray ::= UINT ;
|
||||
type_specifier_nonarray ::= BOOL ;
|
||||
type_specifier_nonarray ::= VEC2 ;
|
||||
type_specifier_nonarray ::= VEC3 ;
|
||||
type_specifier_nonarray ::= VEC4 ;
|
||||
type_specifier_nonarray ::= DVEC2 ;
|
||||
type_specifier_nonarray ::= DVEC3 ;
|
||||
type_specifier_nonarray ::= DVEC4 ;
|
||||
type_specifier_nonarray ::= BVEC2 ;
|
||||
type_specifier_nonarray ::= BVEC3 ;
|
||||
type_specifier_nonarray ::= BVEC4 ;
|
||||
type_specifier_nonarray ::= IVEC2 ;
|
||||
type_specifier_nonarray ::= IVEC3 ;
|
||||
type_specifier_nonarray ::= IVEC4 ;
|
||||
type_specifier_nonarray ::= UVEC2 ;
|
||||
type_specifier_nonarray ::= UVEC3 ;
|
||||
type_specifier_nonarray ::= UVEC4 ;
|
||||
type_specifier_nonarray ::= MAT2 ;
|
||||
type_specifier_nonarray ::= MAT3 ;
|
||||
type_specifier_nonarray ::= MAT4 ;
|
||||
type_specifier_nonarray ::= MAT2X2 ;
|
||||
type_specifier_nonarray ::= MAT2X3 ;
|
||||
type_specifier_nonarray ::= MAT2X4 ;
|
||||
type_specifier_nonarray ::= MAT3X2 ;
|
||||
type_specifier_nonarray ::= MAT3X3 ;
|
||||
type_specifier_nonarray ::= MAT3X4 ;
|
||||
type_specifier_nonarray ::= MAT4X2 ;
|
||||
type_specifier_nonarray ::= MAT4X3 ;
|
||||
type_specifier_nonarray ::= MAT4X4 ;
|
||||
type_specifier_nonarray ::= DMAT2 ;
|
||||
type_specifier_nonarray ::= DMAT3 ;
|
||||
type_specifier_nonarray ::= DMAT4 ;
|
||||
type_specifier_nonarray ::= DMAT2X2 ;
|
||||
type_specifier_nonarray ::= DMAT2X3 ;
|
||||
type_specifier_nonarray ::= DMAT2X4 ;
|
||||
type_specifier_nonarray ::= DMAT3X2 ;
|
||||
type_specifier_nonarray ::= DMAT3X3 ;
|
||||
type_specifier_nonarray ::= DMAT3X4 ;
|
||||
type_specifier_nonarray ::= DMAT4X2 ;
|
||||
type_specifier_nonarray ::= DMAT4X3 ;
|
||||
type_specifier_nonarray ::= DMAT4X4 ;
|
||||
type_specifier_nonarray ::= SAMPLER1D ;
|
||||
type_specifier_nonarray ::= SAMPLER2D ;
|
||||
type_specifier_nonarray ::= SAMPLER3D ;
|
||||
type_specifier_nonarray ::= SAMPLERCUBE ;
|
||||
type_specifier_nonarray ::= SAMPLER1DSHADOW ;
|
||||
type_specifier_nonarray ::= SAMPLER2DSHADOW ;
|
||||
type_specifier_nonarray ::= SAMPLERCUBESHADOW ;
|
||||
type_specifier_nonarray ::= SAMPLER1DARRAY ;
|
||||
type_specifier_nonarray ::= SAMPLER2DARRAY ;
|
||||
type_specifier_nonarray ::= SAMPLER1DARRAYSHADOW ;
|
||||
type_specifier_nonarray ::= SAMPLER2DARRAYSHADOW ;
|
||||
type_specifier_nonarray ::= SAMPLERCUBEARRAY ;
|
||||
type_specifier_nonarray ::= SAMPLERCUBEARRAYSHADOW ;
|
||||
type_specifier_nonarray ::= ISAMPLER1D ;
|
||||
type_specifier_nonarray ::= ISAMPLER2D ;
|
||||
type_specifier_nonarray ::= ISAMPLER3D ;
|
||||
type_specifier_nonarray ::= ISAMPLERCUBE ;
|
||||
type_specifier_nonarray ::= ISAMPLER1DARRAY ;
|
||||
type_specifier_nonarray ::= ISAMPLER2DARRAY ;
|
||||
type_specifier_nonarray ::= ISAMPLERCUBEARRAY ;
|
||||
type_specifier_nonarray ::= USAMPLER1D ;
|
||||
type_specifier_nonarray ::= USAMPLER2D ;
|
||||
type_specifier_nonarray ::= USAMPLER3D ;
|
||||
type_specifier_nonarray ::= USAMPLERCUBE ;
|
||||
type_specifier_nonarray ::= USAMPLER1DARRAY ;
|
||||
type_specifier_nonarray ::= USAMPLER2DARRAY ;
|
||||
type_specifier_nonarray ::= USAMPLERCUBEARRAY ;
|
||||
type_specifier_nonarray ::= SAMPLER2DRECT ;
|
||||
type_specifier_nonarray ::= SAMPLER2DRECTSHADOW ;
|
||||
type_specifier_nonarray ::= ISAMPLER2DRECT ;
|
||||
type_specifier_nonarray ::= USAMPLER2DRECT ;
|
||||
type_specifier_nonarray ::= SAMPLERBUFFER ;
|
||||
type_specifier_nonarray ::= ISAMPLERBUFFER ;
|
||||
type_specifier_nonarray ::= USAMPLERBUFFER ;
|
||||
type_specifier_nonarray ::= SAMPLER2DMS ;
|
||||
type_specifier_nonarray ::= ISAMPLER2DMS ;
|
||||
type_specifier_nonarray ::= USAMPLER2DMS ;
|
||||
type_specifier_nonarray ::= SAMPLER2DMSARRAY ;
|
||||
type_specifier_nonarray ::= ISAMPLER2DMSARRAY ;
|
||||
type_specifier_nonarray ::= USAMPLER2DMSARRAY ;
|
||||
type_specifier_nonarray ::= struct_specifier ;
|
||||
type_specifier_nonarray ::= TYPE_NAME ;
|
||||
precision_qualifier ::= HIGHP ;
|
||||
precision_qualifier ::= MEDIUMP ;
|
||||
precision_qualifier ::= LOWP ;
|
||||
struct_specifier ::= STRUCT IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE ;
|
||||
struct_specifier ::= STRUCT LEFT_BRACE struct_declaration_list RIGHT_BRACE ;
|
||||
struct_declaration_list ::= struct_declaration ;
|
||||
struct_declaration_list ::= struct_declaration_list struct_declaration ;
|
||||
struct_declaration ::= type_specifier struct_declarator_list SEMICOLON ;
|
||||
struct_declaration ::= type_qualifier type_specifier struct_declarator_list SEMICOLON ;
|
||||
struct_declarator_list ::= struct_declarator ;
|
||||
struct_declarator_list ::= struct_declarator_list COMMA struct_declarator ;
|
||||
struct_declarator ::= IDENTIFIER ;
|
||||
struct_declarator ::= IDENTIFIER LEFT_BRACKET RIGHT_BRACKET ;
|
||||
struct_declarator ::= IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET ;
|
||||
initializer ::= assignment_expression ;
|
||||
declaration_statement ::= declaration ;
|
||||
statement ::= compound_statement ;
|
||||
statement ::= simple_statement ;
|
||||
simple_statement ::= declaration_statement ;
|
||||
simple_statement ::= expression_statement ;
|
||||
simple_statement ::= selection_statement ;
|
||||
simple_statement ::= switch_statement ;
|
||||
simple_statement ::= case_label ;
|
||||
simple_statement ::= iteration_statement ;
|
||||
simple_statement ::= jump_statement ;
|
||||
compound_statement ::= LEFT_BRACE RIGHT_BRACE ;
|
||||
compound_statement ::= LEFT_BRACE statement_list RIGHT_BRACE ;
|
||||
statement_no_new_scope ::= compound_statement_no_new_scope ;
|
||||
statement_no_new_scope ::= simple_statement ;
|
||||
compound_statement_no_new_scope ::= LEFT_BRACE RIGHT_BRACE ;
|
||||
compound_statement_no_new_scope ::= LEFT_BRACE statement_list RIGHT_BRACE ;
|
||||
statement_list ::= statement ;
|
||||
statement_list ::= statement_list statement ;
|
||||
expression_statement ::= SEMICOLON ;
|
||||
expression_statement ::= expression SEMICOLON ;
|
||||
selection_statement ::= IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement ;
|
||||
selection_rest_statement ::= statement ELSE statement ;
|
||||
selection_rest_statement ::= statement ;
|
||||
condition ::= expression ;
|
||||
condition ::= fully_specified_type IDENTIFIER EQUAL initializer ;
|
||||
switch_statement ::= SWITCH LEFT_PAREN expression RIGHT_PAREN LEFT_BRACE switch_statement_list RIGHT_BRACE ;
|
||||
switch_statement_list ::= ;
|
||||
switch_statement_list ::= statement_list ;
|
||||
case_label ::= CASE expression COLON ;
|
||||
case_label ::= DEFAULT COLON ;
|
||||
iteration_statement ::= WHILE LEFT_PAREN condition RIGHT_PAREN statement_no_new_scope ;
|
||||
iteration_statement ::= DO statement WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON ;
|
||||
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 ::= declaration_statement ;
|
||||
conditionopt ::= ;
|
||||
conditionopt ::= condition ;
|
||||
for_rest_statement ::= conditionopt SEMICOLON ;
|
||||
for_rest_statement ::= conditionopt SEMICOLON expression ;
|
||||
jump_statement ::= CONTINUE SEMICOLON ;
|
||||
jump_statement ::= BREAK SEMICOLON ;
|
||||
jump_statement ::= RETURN SEMICOLON ;
|
||||
jump_statement ::= RETURN expression SEMICOLON ;
|
||||
jump_statement ::= DISCARD SEMICOLON ;
|
||||
translation_unit ::= external_declaration ;
|
||||
translation_unit ::= translation_unit external_declaration ;
|
||||
external_declaration ::= function_definition ;
|
||||
external_declaration ::= declaration ;
|
||||
external_declaration ::= SEMICOLON ;
|
||||
function_definition ::= function_prototype compound_statement_no_new_scope ;
|
||||
70
src/libs/glsl/tests/main.cpp
Normal file
70
src/libs/glsl/tests/main.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
|
||||
#include "glslparser.h"
|
||||
#include "glsllexer.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string.h>
|
||||
|
||||
using namespace GLSL;
|
||||
|
||||
#ifndef EXIT_FAILURE
|
||||
#define EXIT_FAILURE 1
|
||||
#endif
|
||||
#ifndef EXIT_SUCCESS
|
||||
#define EXIT_SUCCESS 0
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int variant = 0;
|
||||
|
||||
while (argc > 1 && argv[1][0] == '-' && argv[1][1] == '-') {
|
||||
if (!strcmp(argv[1], "--version=1.20")) {
|
||||
variant |= Lexer::Variant_GLSL_120;
|
||||
} else if (!strcmp(argv[1], "--version=1.50")) {
|
||||
variant |= Lexer::Variant_GLSL_150;
|
||||
} else if (!strcmp(argv[1], "--version=4.00")) {
|
||||
variant |= Lexer::Variant_GLSL_400;
|
||||
} else if (!strcmp(argv[1], "--version=es")) {
|
||||
variant |= Lexer::Variant_GLSL_ES_100;
|
||||
} else if (!strcmp(argv[1], "--version=qt")) {
|
||||
variant |= Lexer::Variant_GLSL_ES_100 |
|
||||
Lexer::Variant_GLSL_Qt;
|
||||
} else if (!strcmp(argv[1], "--shader=vertex")) {
|
||||
variant |= Lexer::Variant_VertexShader;
|
||||
} else if (!strcmp(argv[1], "--shader=fragment")) {
|
||||
variant |= Lexer::Variant_FragmentShader;
|
||||
} else {
|
||||
std::cerr << "glsl: unknown option: " << argv[1] << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
++argv;
|
||||
--argc;
|
||||
}
|
||||
|
||||
if (argc != 2) {
|
||||
std::cerr << "glsl: no input file" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
std::ifstream fin(argv[1]);
|
||||
if (! fin) {
|
||||
std::cerr << "glsl: No such file or directory" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
fin.seekg(0, std::ios::end);
|
||||
size_t size = fin.tellg();
|
||||
fin.seekg(0, std::ios::beg);
|
||||
char *source = new char[size];
|
||||
fin.read(source, size);
|
||||
fin.close();
|
||||
if (!variant)
|
||||
variant = Lexer::Variant_Mask & ~Lexer::Variant_Reserved;
|
||||
else if ((variant & (Lexer::Variant_VertexShader | Lexer::Variant_FragmentShader)) == 0)
|
||||
variant |= Lexer::Variant_VertexShader | Lexer::Variant_FragmentShader;
|
||||
Parser parser(source, size, variant);
|
||||
std::cout << argv[1] << (parser.parse() ? " OK " : " KO ") << std::endl;
|
||||
delete source;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
385
src/libs/glsl/tools/kwgen.cpp
Normal file
385
src/libs/glsl/tools/kwgen.cpp
Normal file
@@ -0,0 +1,385 @@
|
||||
/*
|
||||
Copyright 2007 Roberto Raggi <roberto@kdevelop.org>
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided that
|
||||
the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <cstdlib>
|
||||
#include <cctype>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
|
||||
class State;
|
||||
class DottedItem;
|
||||
|
||||
typedef std::list<std::string> RuleList;
|
||||
typedef RuleList::iterator RulePtr;
|
||||
typedef std::list<State> StateList;
|
||||
typedef StateList::iterator StatePtr;
|
||||
typedef std::string::iterator Dot;
|
||||
typedef std::vector<DottedItem>::iterator DottedItemPtr;
|
||||
|
||||
class DottedItem {
|
||||
public:
|
||||
RulePtr rule;
|
||||
Dot dot;
|
||||
|
||||
DottedItem() {}
|
||||
|
||||
DottedItem(RulePtr rule, Dot dot):
|
||||
rule(rule), dot(dot) {}
|
||||
|
||||
bool operator == (const DottedItem &other) const {
|
||||
return rule == other.rule && dot == other.dot;
|
||||
}
|
||||
|
||||
bool operator != (const DottedItem &other) const {
|
||||
return ! operator == (other);
|
||||
}
|
||||
|
||||
bool terminal() const {
|
||||
return dot == rule->end();
|
||||
}
|
||||
|
||||
DottedItem next() const {
|
||||
DottedItem item;
|
||||
item.rule = rule;
|
||||
item.dot = dot;
|
||||
++item.dot;
|
||||
return item;
|
||||
}
|
||||
};
|
||||
|
||||
struct State {
|
||||
public:
|
||||
State() {}
|
||||
|
||||
template <typename _ForwardIterator>
|
||||
State(_ForwardIterator first, _ForwardIterator last) {
|
||||
_items.insert(_items.end(), first, last);
|
||||
}
|
||||
|
||||
static State &intern(const State &state) {
|
||||
StatePtr ptr = std::find(first_state(), last_state(), state);
|
||||
if (ptr == last_state())
|
||||
ptr = states().insert(last_state(), state);
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
State &next(char ch) {
|
||||
std::vector<DottedItem> n;
|
||||
for (DottedItemPtr it = first_item(); it != last_item(); ++it) {
|
||||
if (! it->terminal() && *it->dot == ch)
|
||||
n.push_back(it->next());
|
||||
}
|
||||
return intern(State(n.begin(), n.end()));
|
||||
}
|
||||
|
||||
std::set<char> firsts() {
|
||||
std::set<char> s;
|
||||
for (DottedItemPtr it = first_item(); it != last_item(); ++it) {
|
||||
if (! it->terminal())
|
||||
s.insert(*it->dot);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
size_t item_count() const { return _items.size(); }
|
||||
|
||||
DottedItemPtr first_item() { return _items.begin(); }
|
||||
DottedItemPtr last_item() { return _items.end(); }
|
||||
|
||||
static StatePtr first_state() { return states().begin(); }
|
||||
static StatePtr last_state() { return states().end(); }
|
||||
|
||||
bool operator == (const State &other) const { return _items == other._items; }
|
||||
bool operator != (const State &other) const { return _items != other._items; }
|
||||
|
||||
template <typename _Iterator>
|
||||
static State &start(_Iterator first, _Iterator last) {
|
||||
std::vector<DottedItem> items;
|
||||
for (; first != last; ++first)
|
||||
items.push_back(DottedItem(first, first->begin()));
|
||||
return intern(State(items.begin(), items.end()));
|
||||
}
|
||||
|
||||
static void reset() {
|
||||
states().clear();
|
||||
}
|
||||
|
||||
private:
|
||||
static StateList &states() {
|
||||
static StateList _states;
|
||||
return _states;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<DottedItem> _items;
|
||||
};
|
||||
|
||||
static bool option_no_enums = false;
|
||||
static bool option_toupper = false;
|
||||
static std::string option_namespace_name;
|
||||
static std::string option_class_name;
|
||||
static std::string option_token_prefix = "Token_";
|
||||
static std::string option_variant_prefix = "Variant_";
|
||||
static std::string option_char_type = "char";
|
||||
static std::string option_unicode_function = "";
|
||||
static std::map<std::string, std::string> variants;
|
||||
|
||||
std::string token_id(const std::string &id)
|
||||
{
|
||||
std::string token = option_token_prefix;
|
||||
|
||||
if (! option_toupper)
|
||||
token += id;
|
||||
else {
|
||||
for (size_t i = 0; i < id.size(); ++i)
|
||||
token += toupper(id[i]);
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
std::string variant_id(const std::string &id)
|
||||
{
|
||||
if (variants.find(id) == variants.end())
|
||||
return "";
|
||||
std::string variant = variants[id];
|
||||
size_t posn = 0;
|
||||
bool sep = true;
|
||||
std::string result;
|
||||
while (posn < variant.size()) {
|
||||
char ch = variant[posn++];
|
||||
if (isalnum(ch) || ch == '_') {
|
||||
if (sep) {
|
||||
result += " | " + option_variant_prefix;
|
||||
sep = false;
|
||||
}
|
||||
result += ch;
|
||||
} else if (!sep) {
|
||||
sep = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool starts_with(const std::string &line, const std::string &text) {
|
||||
if (text.length() < line.length()) {
|
||||
return std::equal(line.begin(), line.begin() + text.size(), text.begin());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void doit(State &state)
|
||||
{
|
||||
static int depth = 0;
|
||||
|
||||
++depth;
|
||||
|
||||
std::string indent(depth * 2, ' ');
|
||||
|
||||
std::set<char> firsts = state.firsts();
|
||||
for (std::set<char>::iterator it = firsts.begin(); it != firsts.end(); ++it) {
|
||||
std::string _else = it == firsts.begin() ? "" : "else ";
|
||||
std::cout << indent << _else << "if (s[" << (depth - 1) << "]" << option_unicode_function << " == '" << *it << "') {" << std::endl;
|
||||
State &next_state = state.next(*it);
|
||||
|
||||
bool found = false;
|
||||
for (DottedItemPtr item = next_state.first_item(); item != next_state.last_item(); ++item) {
|
||||
if (item->terminal()) {
|
||||
if (found) {
|
||||
std::cerr << "*** Error. Too many accepting states" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
found = true;
|
||||
std::cout << indent << " return " << option_namespace_name << token_id(*item->rule) << variant_id(*item->rule) << ";" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (! found)
|
||||
doit(next_state);
|
||||
|
||||
std::cout << indent << "}" << std::endl;
|
||||
}
|
||||
|
||||
--depth;
|
||||
}
|
||||
|
||||
void gen_classify_n(State &start_state, int N)
|
||||
{
|
||||
std::cout << "static inline int classify" << N << "(const " << option_char_type << " *s) {" << std::endl;
|
||||
doit(start_state);
|
||||
std::cout << " return " << option_namespace_name << token_id("identifier") << ";" << std::endl
|
||||
<< "}" << std::endl << std::endl;
|
||||
}
|
||||
|
||||
void gen_classify(const std::multimap<size_t, std::string> &keywords)
|
||||
{
|
||||
std::cout << "int " << option_class_name << "classify(const " << option_char_type << " *s, int n) {" << std::endl
|
||||
<< " switch (n) {" << std::endl;
|
||||
std::multimap<size_t, std::string>::const_iterator it = keywords.begin();
|
||||
while (it != keywords.end()) {
|
||||
size_t size = it->first;
|
||||
std::cout << " case " << size << ": return classify" << size << "(s);" << std::endl;
|
||||
do { ++it; } while (it != keywords.end() && it->first == size);
|
||||
}
|
||||
std::cout << " default: return " << option_namespace_name << token_id("identifier") << ";" << std::endl
|
||||
<< " } // switch" << std::endl
|
||||
<< "}" << std::endl << std::endl;
|
||||
}
|
||||
|
||||
void gen_enums(const std::multimap<size_t, std::string> &keywords)
|
||||
{
|
||||
std::cout << "enum {" << std::endl;
|
||||
std::multimap<size_t, std::string>::const_iterator it = keywords.begin();
|
||||
for (; it != keywords.end(); ++it) {
|
||||
std::cout << " " << token_id(it->second) << variant_id(it->second) << "," << std::endl;
|
||||
}
|
||||
std::cout << " " << token_id("identifier") << std::endl
|
||||
<< "};" << std::endl << std::endl;
|
||||
}
|
||||
|
||||
inline bool not_whitespace_p(char ch) {
|
||||
return ! std::isspace(ch);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
const std::string ns = "--namespace=";
|
||||
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
const std::string arg(argv[i]);
|
||||
if (arg == "--no-enums")
|
||||
option_no_enums = true;
|
||||
else if (starts_with(arg, ns)) {
|
||||
option_namespace_name.assign(arg.begin() + ns.size(), arg.end());
|
||||
option_namespace_name += "::";
|
||||
}
|
||||
}
|
||||
|
||||
std::multimap<size_t, std::string> keywords;
|
||||
std::string textline;
|
||||
|
||||
bool readKeywords = false;
|
||||
|
||||
const std::string opt_no_enums = "%no-enums";
|
||||
const std::string opt_toupper = "%toupper";
|
||||
const std::string opt_ns = "%namespace=";
|
||||
const std::string opt_class = "%lexer-class=";
|
||||
const std::string opt_tok_prefix = "%token-prefix=";
|
||||
const std::string opt_var_prefix = "%variant-prefix=";
|
||||
const std::string opt_char_type = "%char-type=";
|
||||
const std::string opt_unicode_function = "%unicode-function=";
|
||||
|
||||
while (getline(std::cin, textline)) {
|
||||
|
||||
// remove trailing spaces
|
||||
textline.assign(textline.begin(), std::find_if(textline.rbegin(), textline.rend(), not_whitespace_p).base());
|
||||
|
||||
if (! readKeywords) {
|
||||
if (textline.size() >= 2 && textline[0] == '%') {
|
||||
if (textline[1] == '%') {
|
||||
readKeywords = true;
|
||||
} else if (textline == opt_no_enums) {
|
||||
option_no_enums = true;
|
||||
} else if (textline == opt_toupper) {
|
||||
option_toupper = true;
|
||||
} else if (starts_with(textline, opt_tok_prefix)) {
|
||||
option_token_prefix.assign(textline.begin() + opt_tok_prefix.size(), textline.end());
|
||||
} else if (starts_with(textline, opt_var_prefix)) {
|
||||
option_variant_prefix.assign(textline.begin() + opt_var_prefix.size(), textline.end());
|
||||
} else if (starts_with(textline, opt_char_type)) {
|
||||
option_char_type.assign(textline.begin() + opt_char_type.size(), textline.end());
|
||||
} else if (starts_with(textline, opt_unicode_function)) {
|
||||
option_unicode_function.assign(textline.begin() + opt_unicode_function.size(), textline.end());
|
||||
} else if (starts_with(textline, opt_ns)) {
|
||||
option_namespace_name.assign(textline.begin() + opt_ns.size(), textline.end());
|
||||
option_namespace_name += "::";
|
||||
} else if (starts_with(textline, opt_class)) {
|
||||
option_class_name.assign(textline.begin() + opt_class.size(), textline.end());
|
||||
option_class_name += "::";
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
std::cout << textline << std::endl;
|
||||
} else {
|
||||
if (textline.empty())
|
||||
continue;
|
||||
|
||||
std::string::iterator start = textline.begin();
|
||||
while (start != textline.end() && std::isspace(*start))
|
||||
++start;
|
||||
|
||||
std::string::iterator stop = start;
|
||||
while (stop != textline.end() && (std::isalnum(*stop) || *stop == '_'))
|
||||
++stop;
|
||||
|
||||
if (start != stop) {
|
||||
std::string keyword(start, stop);
|
||||
if (keyword == "identifier") {
|
||||
std::cerr << "*** Error. `identifier' is reserved" << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
keywords.insert(std::make_pair(keyword.size(), keyword));
|
||||
|
||||
start = stop;
|
||||
while (start != textline.end() && std::isspace(*start))
|
||||
++start;
|
||||
|
||||
if (start != textline.end() && *start == '%') {
|
||||
++start;
|
||||
std::string::iterator stop = start;
|
||||
while (stop != textline.end() && (std::isalnum(*stop) || *stop == '_'))
|
||||
++stop;
|
||||
std::string directive(start, stop);
|
||||
if (directive == "variant") {
|
||||
while (stop != textline.end() && std::isspace(*stop))
|
||||
++stop;
|
||||
std::string variant(stop, textline.end());
|
||||
variants.insert(std::make_pair(keyword, variant));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (option_class_name.empty())
|
||||
option_class_name = option_namespace_name;
|
||||
|
||||
if (! option_no_enums)
|
||||
gen_enums(keywords);
|
||||
|
||||
std::multimap<size_t, std::string>::iterator it = keywords.begin();
|
||||
while (it != keywords.end()) {
|
||||
size_t size = it->first;
|
||||
RuleList rules;
|
||||
do { rules.push_back(it->second); ++it; }
|
||||
while (it != keywords.end() && it->first == size);
|
||||
gen_classify_n(State::start(rules.begin(), rules.end()), size);
|
||||
State::reset();
|
||||
}
|
||||
|
||||
gen_classify(keywords);
|
||||
}
|
||||
85
src/libs/glsl/tools/mkvisitor.py
Executable file
85
src/libs/glsl/tools/mkvisitor.py
Executable file
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
|
||||
try:
|
||||
file = open(sys.argv[1], "r")
|
||||
klass = sys.argv[2]
|
||||
except:
|
||||
print("Usage: mkvisitor.py grammar.txt classname")
|
||||
exit()
|
||||
|
||||
lines = file.readlines()
|
||||
ruleno = 0
|
||||
print("""
|
||||
#include "glslast.h"
|
||||
|
||||
namespace GLSL {
|
||||
|
||||
class %s
|
||||
{
|
||||
typedef void (%s::*dispatch_func)(AST *);
|
||||
static dispatch_func dispatch[];
|
||||
|
||||
public:
|
||||
void accept(AST *ast)
|
||||
{
|
||||
if (! ast)
|
||||
return;
|
||||
else if (Operator *op = ast->asOperator())
|
||||
(this->*dispatch[op->ruleno])(ast);
|
||||
}
|
||||
|
||||
template <typename It>
|
||||
void accept(It first, It last)
|
||||
{
|
||||
for (; first != last; ++first)
|
||||
accept(*first);
|
||||
}
|
||||
|
||||
private:""" % (klass, klass))
|
||||
|
||||
for line in lines:
|
||||
sections = line.split()
|
||||
if len(sections) and sections[1] == "::=":
|
||||
ruleno = ruleno + 1
|
||||
print(" void on_%s_%d(AST *);" % (sections[0], ruleno))
|
||||
|
||||
print("};")
|
||||
print("} // end of namespace GLSL")
|
||||
|
||||
print("""
|
||||
#include <iostream>
|
||||
|
||||
using namespace GLSL;
|
||||
|
||||
namespace {
|
||||
bool debug = false;
|
||||
}
|
||||
|
||||
""")
|
||||
|
||||
print("%s::dispatch_func %s::dispatch[] = {" % (klass, klass))
|
||||
|
||||
ruleno = 0
|
||||
for line in lines:
|
||||
sections = line.split()
|
||||
if len(sections) and sections[1] == "::=":
|
||||
ruleno = ruleno + 1
|
||||
print(" &%s::on_%s_%d," % (klass, sections[0], ruleno))
|
||||
|
||||
print("0, };\n")
|
||||
|
||||
ruleno = 0
|
||||
for line in lines:
|
||||
sections = line.split()
|
||||
if len(sections) and sections[1] == "::=":
|
||||
ruleno = ruleno + 1
|
||||
print("""// %svoid %s::on_%s_%d(AST *ast)
|
||||
{
|
||||
if (debug)
|
||||
std::cout << "%s" << std::endl;
|
||||
Operator *op = ast->asOperator();
|
||||
accept(op->begin(), op->end());
|
||||
}
|
||||
""" % (line, klass, sections[0], ruleno, line[:-3]))
|
||||
@@ -10,6 +10,7 @@ SUBDIRS = \
|
||||
utils/process_stub.pro \
|
||||
cplusplus \
|
||||
qmljs \
|
||||
glsl \
|
||||
qmleditorwidgets \
|
||||
symbianutils \
|
||||
3rdparty
|
||||
|
||||
Reference in New Issue
Block a user