forked from qt-creator/qt-creator
Imported our new GLSL front-end.
This commit is contained in:
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;
|
||||
}
|
||||
Reference in New Issue
Block a user