42 static const std::string kDirectiveDefine(
"define");
46 static const std::string kDirectiveIfndef(
"ifndef");
51 static const std::string kDirectivePragma(
"pragma");
52 static const std::string kDirectiveExtension(
"extension");
53 static const std::string kDirectiveVersion(
"version");
57 return DIRECTIVE_NONE;
59 if (token->
text == kDirectiveDefine)
60 return DIRECTIVE_DEFINE;
61 else if (token->
text == kDirectiveUndef)
62 return DIRECTIVE_UNDEF;
63 else if (token->
text == kDirectiveIf)
65 else if (token->
text == kDirectiveIfdef)
66 return DIRECTIVE_IFDEF;
67 else if (token->
text == kDirectiveIfndef)
68 return DIRECTIVE_IFNDEF;
69 else if (token->
text == kDirectiveElse)
70 return DIRECTIVE_ELSE;
71 else if (token->
text == kDirectiveElif)
72 return DIRECTIVE_ELIF;
73 else if (token->
text == kDirectiveEndif)
74 return DIRECTIVE_ENDIF;
75 else if (token->
text == kDirectiveError)
76 return DIRECTIVE_ERROR;
77 else if (token->
text == kDirectivePragma)
78 return DIRECTIVE_PRAGMA;
79 else if (token->
text == kDirectiveExtension)
80 return DIRECTIVE_EXTENSION;
81 else if (token->
text == kDirectiveVersion)
82 return DIRECTIVE_VERSION;
83 else if (token->
text == kDirectiveLine)
84 return DIRECTIVE_LINE;
86 return DIRECTIVE_NONE;
95 case DIRECTIVE_IFNDEF:
122 if (name.substr(0, 3) ==
"GL_")
126 if (name.find(
"__") != std::string::npos)
135 pp::MacroSet::const_iterator iter = macroSet.find(name);
136 return iter != macroSet.end() ? iter->second.predefined :
false;
142 class DefinedParser :
public Lexer
145 DefinedParser(Lexer* lexer,
147 Diagnostics* diagnostics) :
150 mDiagnostics(diagnostics)
155 virtual void lex(Token* token)
162 if (token->text != kDefined)
167 if (token->type ==
'(')
176 token->location, token->text);
180 MacroSet::const_iterator iter = mMacroSet->find(token->text);
181 std::string expression = iter != mMacroSet->end() ?
"1" :
"0";
186 if (token->type !=
')')
189 token->location, token->text);
198 token->text = expression;
204 Diagnostics* mDiagnostics;
211 mPastFirstStatement(
false),
212 mTokenizer(tokenizer),
214 mDiagnostics(diagnostics),
215 mDirectiveHandler(directiveHandler)
223 mTokenizer->
lex(token);
227 parseDirective(token);
228 mPastFirstStatement =
true;
233 if (!mConditionalStack.empty())
235 const ConditionalBlock& block = mConditionalStack.back();
237 block.location, block.type);
242 }
while (skipping() || (token->
type ==
'\n'));
244 mPastFirstStatement =
true;
247 void DirectiveParser::parseDirective(
Token* token)
251 mTokenizer->
lex(token);
275 case DIRECTIVE_DEFINE:
278 case DIRECTIVE_UNDEF:
284 case DIRECTIVE_IFDEF:
287 case DIRECTIVE_IFNDEF:
296 case DIRECTIVE_ENDIF:
299 case DIRECTIVE_ERROR:
302 case DIRECTIVE_PRAGMA:
305 case DIRECTIVE_EXTENSION:
306 parseExtension(token);
308 case DIRECTIVE_VERSION:
327 void DirectiveParser::parseDefine(Token* token)
331 mTokenizer->
lex(token);
335 token->location, token->text);
341 token->location, token->text);
347 token->location, token->text);
353 macro.name = token->text;
355 mTokenizer->
lex(token);
356 if (token->type ==
'(' && !token->hasLeadingSpace())
361 mTokenizer->
lex(token);
364 macro.parameters.push_back(token->text);
366 mTokenizer->
lex(token);
367 }
while (token->type ==
',');
369 if (token->type !=
')')
376 mTokenizer->
lex(token);
379 while ((token->type !=
'\n') && (token->type !=
Token::LAST))
384 token->location = SourceLocation();
385 macro.replacements.push_back(*token);
386 mTokenizer->
lex(token);
388 if (!macro.replacements.empty())
392 macro.replacements.front().setHasLeadingSpace(
false);
396 MacroSet::const_iterator iter = mMacroSet->find(macro.name);
397 if (iter != mMacroSet->end() && !macro.equals(iter->second))
404 mMacroSet->insert(std::make_pair(macro.name, macro));
407 void DirectiveParser::parseUndef(Token* token)
411 mTokenizer->
lex(token);
415 token->location, token->text);
419 MacroSet::iterator iter = mMacroSet->find(token->text);
420 if (iter != mMacroSet->end())
422 if (iter->second.predefined)
425 token->location, token->text);
429 mMacroSet->erase(iter);
433 mTokenizer->
lex(token);
436 void DirectiveParser::parseIf(Token* token)
439 parseConditionalIf(token);
442 void DirectiveParser::parseIfdef(Token* token)
445 parseConditionalIf(token);
448 void DirectiveParser::parseIfndef(Token* token)
451 parseConditionalIf(token);
454 void DirectiveParser::parseElse(Token* token)
458 if (mConditionalStack.empty())
461 token->location, token->text);
466 ConditionalBlock& block = mConditionalStack.back();
473 if (block.foundElseGroup)
476 token->location, token->text);
481 block.foundElseGroup =
true;
482 block.skipGroup = block.foundValidGroup;
483 block.foundValidGroup =
true;
486 mTokenizer->
lex(token);
490 token->location, token->text);
495 void DirectiveParser::parseElif(Token* token)
499 if (mConditionalStack.empty())
502 token->location, token->text);
507 ConditionalBlock& block = mConditionalStack.back();
514 if (block.foundElseGroup)
517 token->location, token->text);
521 if (block.foundValidGroup)
525 block.skipGroup =
true;
530 int expression = parseExpressionIf(token);
531 block.skipGroup = expression == 0;
532 block.foundValidGroup = expression != 0;
535 void DirectiveParser::parseEndif(Token* token)
539 if (mConditionalStack.empty())
542 token->location, token->text);
547 mConditionalStack.pop_back();
550 mTokenizer->
lex(token);
554 token->location, token->text);
559 void DirectiveParser::parseError(Token* token)
563 std::ostringstream
stream;
564 mTokenizer->
lex(token);
565 while ((token->type !=
'\n') && (token->type !=
Token::LAST))
568 mTokenizer->
lex(token);
570 mDirectiveHandler->
handleError(token->location, stream.str());
574 void DirectiveParser::parsePragma(Token* token)
588 int state = PRAGMA_NAME;
590 mTokenizer->
lex(token);
591 while ((token->type !=
'\n') && (token->type !=
Token::LAST))
600 valid = valid && (token->type ==
'(');
607 valid = valid && (token->type ==
')');
613 mTokenizer->
lex(token);
616 valid = valid && ((state == PRAGMA_NAME) ||
622 token->location, name);
624 else if (state > PRAGMA_NAME)
626 mDirectiveHandler->
handlePragma(token->location, name, value);
630 void DirectiveParser::parseExtension(Token* token)
643 int state = EXT_NAME;
645 mTokenizer->
lex(token);
646 while ((token->type !=
'\n') && (token->type !=
Token::LAST))
654 token->location, token->text);
657 if (valid) name = token->text;
660 if (valid && (token->type !=
':'))
663 token->location, token->text);
671 token->location, token->text);
674 if (valid) behavior = token->text;
680 token->location, token->text);
685 mTokenizer->
lex(token);
687 if (valid && (state != EXT_BEHAVIOR + 1))
690 token->location, token->text);
697 void DirectiveParser::parseVersion(Token* token)
701 if (mPastFirstStatement)
704 token->location, token->text);
716 int state = VERSION_NUMBER;
718 mTokenizer->
lex(token);
719 while ((token->type !=
'\n') && (token->type !=
Token::LAST))
727 token->location, token->text);
730 if (valid && !token->iValue(&version))
733 token->location, token->text);
741 token->location, token->text);
746 mTokenizer->
lex(token);
748 if (valid && (state != VERSION_NUMBER + 1))
751 token->location, token->text);
758 void DirectiveParser::parseLine(Token* token)
769 int line = 0,
file = 0;
770 int state = LINE_NUMBER;
772 MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics);
773 macroExpander.lex(token);
774 while ((token->type !=
'\n') && (token->type !=
Token::LAST))
782 token->location, token->text);
785 if (valid && !token->iValue(&line))
788 token->location, token->text);
796 token->location, token->text);
799 if (valid && !token->iValue(&
file))
802 token->location, token->text);
810 token->location, token->text);
815 macroExpander.lex(token);
818 if (valid && (state != FILE_NUMBER) && (state != FILE_NUMBER + 1))
821 token->location, token->text);
831 bool DirectiveParser::skipping()
const
833 if (mConditionalStack.empty())
return false;
835 const ConditionalBlock& block = mConditionalStack.back();
836 return block.skipBlock || block.skipGroup;
839 void DirectiveParser::parseConditionalIf(Token* token)
841 ConditionalBlock block;
842 block.type = token->text;
843 block.location = token->location;
852 block.skipBlock =
true;
862 expression = parseExpressionIf(token);
864 case DIRECTIVE_IFDEF:
865 expression = parseExpressionIfdef(token);
867 case DIRECTIVE_IFNDEF:
868 expression = parseExpressionIfdef(token) == 0 ? 1 : 0;
874 block.skipGroup = expression == 0;
875 block.foundValidGroup = expression != 0;
877 mConditionalStack.push_back(block);
880 int DirectiveParser::parseExpressionIf(Token* token)
885 DefinedParser definedParser(mTokenizer, mMacroSet, mDiagnostics);
886 MacroExpander macroExpander(&definedParser, mMacroSet, mDiagnostics);
887 ExpressionParser expressionParser(¯oExpander, mDiagnostics);
890 macroExpander.lex(token);
891 expressionParser.parse(token, &expression);
897 token->location, token->text);
904 int DirectiveParser::parseExpressionIfdef(Token* token)
909 mTokenizer->
lex(token);
913 token->location, token->text);
918 MacroSet::const_iterator iter = mMacroSet->find(token->text);
919 int expression = iter != mMacroSet->end() ? 1 : 0;
922 mTokenizer->
lex(token);
926 token->location, token->text);
virtual void handleError(const SourceLocation &loc, const std::string &msg)=0
virtual void handleExtension(const SourceLocation &loc, const std::string &name, const std::string &behavior)=0
static bool isMacroPredefined(const std::string &name, const pp::MacroSet ¯oSet)
virtual void handleVersion(const SourceLocation &loc, int version)=0
EGLImageKHR EGLint * name
void setFileNumber(int file)
void setLineNumber(int line)
static bool isConditionalDirective(DirectiveType directive)
static bool isMacroNameReserved(const std::string &name)
void report(ID id, const SourceLocation &loc, const std::string &text)
virtual void lex(Token *token)
static bool isEOD(const pp::Token *token)
std::map< std::string, Macro > MacroSet
EGLSurface EGLint void ** value
virtual void lex(Token *token)
static void skipUntilEOD(pp::Lexer *lexer, pp::Token *token)
GLsizei const GLcharARB ** string
virtual void lex(Token *token)=0
virtual void handlePragma(const SourceLocation &loc, const std::string &name, const std::string &value)=0
DirectiveParser(Tokenizer *tokenizer, MacroSet *macroSet, Diagnostics *diagnostics, DirectiveHandler *directiveHandler)
static DirectiveType getDirective(const pp::Token *token)