Refactored glslang grammar files to make:
- lexer and parser reentrant
- line number handling automatic
Caveats:
- The preprocessor is still not thread-safe and full of bugs. I have another not-yet-ready patch to replace the preprocessor.
- The grammar files use options that are not supported by the old versions of flex and bison checked into compiler/tools. So I need to check-in the generated lexer-parser along with a shell script to generate them.
Review URL: http://codereview.appspot.com/2992041
git-svn-id: https://angleproject.googlecode.com/svn/trunk@475 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/compiler/ParseHelper.cpp b/src/compiler/ParseHelper.cpp
index 8cddc17..430ba53 100644
--- a/src/compiler/ParseHelper.cpp
+++ b/src/compiler/ParseHelper.cpp
@@ -9,9 +9,35 @@
#include <stdarg.h>
#include <stdio.h>
+#include "compiler/glslang.h"
#include "compiler/osinclude.h"
#include "compiler/InitializeParseContext.h"
+extern "C" {
+extern int InitPreprocessor();
+extern int FinalizePreprocessor();
+extern void PredefineIntMacro(const char *name, int value);
+}
+
+static void ReportInfo(TInfoSinkBase& sink,
+ TPrefixType type, TSourceLoc loc,
+ const char* reason, const char* token,
+ const char* extraInfo)
+{
+ /* VC++ format: file(linenum) : error #: 'token' : extrainfo */
+ sink.prefix(type);
+ sink.location(loc);
+ sink << "'" << token << "' : " << reason << " " << extraInfo << "\n";
+}
+
+static void DefineExtensionMacros(const TExtensionBehavior& extBehavior)
+{
+ for (TExtensionBehavior::const_iterator iter = extBehavior.begin();
+ iter != extBehavior.end(); ++iter) {
+ PredefineIntMacro(iter->first.c_str(), 1);
+ }
+}
+
///////////////////////////////////////////////////////////////////////
//
// Sub- vector and matrix fields
@@ -176,26 +202,34 @@
//
// Used by flex/bison to output all syntax and parsing errors.
//
-void TParseContext::error(TSourceLoc nLine, const char *szReason, const char *szToken,
- const char *szExtraInfoFormat, ...)
+void TParseContext::error(TSourceLoc loc,
+ const char* reason, const char* token,
+ const char* extraInfoFormat, ...)
{
- char szExtraInfo[400];
+ char extraInfo[512];
va_list marker;
+ va_start(marker, extraInfoFormat);
+ vsnprintf(extraInfo, sizeof(extraInfo), extraInfoFormat, marker);
- va_start(marker, szExtraInfoFormat);
-
- vsnprintf(szExtraInfo, sizeof(szExtraInfo), szExtraInfoFormat, marker);
-
- /* VC++ format: file(linenum) : error #: 'token' : extrainfo */
- infoSink.info.prefix(EPrefixError);
- infoSink.info.location(nLine);
- infoSink.info << "'" << szToken << "' : " << szReason << " " << szExtraInfo << "\n";
+ ReportInfo(infoSink.info, EPrefixError, loc, reason, token, extraInfo);
va_end(marker);
-
++numErrors;
}
+void TParseContext::warning(TSourceLoc loc,
+ const char* reason, const char* token,
+ const char* extraInfoFormat, ...) {
+ char extraInfo[512];
+ va_list marker;
+ va_start(marker, extraInfoFormat);
+ vsnprintf(extraInfo, sizeof(extraInfo), extraInfoFormat, marker);
+
+ ReportInfo(infoSink.info, EPrefixWarning, loc, reason, token, extraInfo);
+
+ va_end(marker);
+}
+
//
// Same error message for all places assignments don't work.
//
@@ -1380,6 +1414,32 @@
return typedNode;
}
+//
+// Parse an array of strings using yyparse.
+//
+// Returns 0 for success.
+//
+int PaParseStrings(int count, const char* const string[], const int length[],
+ TParseContext* context) {
+ if ((count == 0) || (string == NULL))
+ return 1;
+
+ // setup preprocessor.
+ if (InitPreprocessor())
+ return 1;
+ DefineExtensionMacros(context->extensionBehavior);
+
+ if (glslang_initialize(context))
+ return 1;
+
+ glslang_scan(count, string, length, context);
+ int error = glslang_parse(context);
+
+ glslang_finalize(context);
+ FinalizePreprocessor();
+ return (error == 0) && (context->numErrors == 0) ? 0 : 1;
+}
+
OS_TLSIndex GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
bool InitializeParseContextIndex()