Imported our new GLSL front-end.

This commit is contained in:
Roberto Raggi
2010-11-10 12:32:34 +01:00
parent 89eb27d231
commit bc70a68817
22 changed files with 12728 additions and 0 deletions

View 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
View 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
View 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
View File

@@ -0,0 +1,12 @@
#include "glslast.h"
using namespace GLSL;
AST::AST()
{
}
AST::~AST()
{
}

51
src/libs/glsl/glslast.h Normal file
View 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

File diff suppressed because it is too large Load Diff

3470
src/libs/glsl/glsldump.cpp Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

325
src/libs/glsl/glsllexer.cpp Normal file
View 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
View 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

View 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;
}

View 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

File diff suppressed because it is too large Load Diff

View 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
View 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

View 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;
}
./

View 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

View 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 ;

View 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;
}

View 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);
}

View 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]))

View File

@@ -10,6 +10,7 @@ SUBDIRS = \
utils/process_stub.pro \
cplusplus \
qmljs \
glsl \
qmleditorwidgets \
symbianutils \
3rdparty