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()