Reframe the preprocessor as a C++ class, with instances, removing all C code, removing all global variables. Upgrade bison version to pass a parse context on through to the preprocessor. All the basic things to make something thread safe.
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@22291 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
@@ -36,7 +36,6 @@
|
|||||||
|
|
||||||
#include "InitializeDll.h"
|
#include "InitializeDll.h"
|
||||||
#include "Include/InitializeGlobals.h"
|
#include "Include/InitializeGlobals.h"
|
||||||
#include "Include/InitializeParseContext.h"
|
|
||||||
|
|
||||||
#include "Public/ShaderLang.h"
|
#include "Public/ShaderLang.h"
|
||||||
|
|
||||||
@@ -58,18 +57,13 @@ bool InitProcess()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! InitializePoolIndex()) {
|
||||||
if (!InitializePoolIndex()) {
|
|
||||||
assert(0 && "InitProcess(): Failed to initalize global pool");
|
assert(0 && "InitProcess(): Failed to initalize global pool");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!InitializeParseContextIndex()) {
|
|
||||||
assert(0 && "InitProcess(): Failed to initalize parse context");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
InitThread();
|
InitThread();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,10 +83,7 @@ bool InitThread()
|
|||||||
|
|
||||||
InitializeGlobalPools();
|
InitializeGlobalPools();
|
||||||
|
|
||||||
if (!InitializeThreadParseContext())
|
if (! OS_SetTLSValue(ThreadInitializeIndex, (void *)1)) {
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)1)) {
|
|
||||||
assert(0 && "InitThread(): Unable to set init flag.");
|
assert(0 && "InitThread(): Unable to set init flag.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -119,8 +110,6 @@ bool DetachThread()
|
|||||||
|
|
||||||
FreeGlobalPools();
|
FreeGlobalPools();
|
||||||
|
|
||||||
if (!FreeParseContext())
|
|
||||||
success = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
@@ -139,9 +128,6 @@ bool DetachProcess()
|
|||||||
|
|
||||||
FreePoolIndex();
|
FreePoolIndex();
|
||||||
|
|
||||||
if (!FreeParseContextIndex())
|
|
||||||
success = false;
|
|
||||||
|
|
||||||
OS_FreeTLSIndex(ThreadInitializeIndex);
|
OS_FreeTLSIndex(ThreadInitializeIndex);
|
||||||
ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
|
ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
|
||||||
|
|
||||||
|
|||||||
@@ -150,9 +150,18 @@ xcopy /y $(IntDir)$(TargetName)$(TargetExt) Test</Command>
|
|||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="glslang\MachineIndependent\Constant.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\Constant.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\glslang_tab.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\glslang_tab.cpp">
|
||||||
|
<DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">4065</DisableSpecificWarnings>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="glslang\MachineIndependent\InfoSink.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\InfoSink.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\Initialize.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\Initialize.cpp" />
|
||||||
|
<ClCompile Include="glslang\MachineIndependent\preprocessor\Pp.cpp" />
|
||||||
|
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpAtom.cpp" />
|
||||||
|
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpMemory.cpp" />
|
||||||
|
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpScanner.cpp" />
|
||||||
|
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpContext.cpp" />
|
||||||
|
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpSymbols.cpp" />
|
||||||
|
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpTokens.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\Scan.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\Scan.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\Versions.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\Versions.cpp" />
|
||||||
<ClCompile Include="OGLCompilersDLL\InitializeDll.cpp" />
|
<ClCompile Include="OGLCompilersDLL\InitializeDll.cpp" />
|
||||||
@@ -166,13 +175,6 @@ xcopy /y $(IntDir)$(TargetName)$(TargetExt) Test</Command>
|
|||||||
<ClCompile Include="glslang\MachineIndependent\SymbolTable.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\SymbolTable.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\intermOut.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\intermOut.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\parseConst.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\parseConst.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\atom.c" />
|
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\cpp.c" />
|
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\cppstruct.c" />
|
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\memory.c" />
|
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\scanner.c" />
|
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\symbols.c" />
|
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\tokens.c" />
|
|
||||||
<ClCompile Include="glslang\OSDependent\Windows\main.cpp" />
|
<ClCompile Include="glslang\OSDependent\Windows\main.cpp" />
|
||||||
<ClCompile Include="glslang\OSDependent\Windows\ossource.cpp" />
|
<ClCompile Include="glslang\OSDependent\Windows\ossource.cpp" />
|
||||||
<ClCompile Include="glslang\OSDependent\Linux\ossource.cpp">
|
<ClCompile Include="glslang\OSDependent\Linux\ossource.cpp">
|
||||||
@@ -187,18 +189,11 @@ xcopy /y $(IntDir)$(TargetName)$(TargetExt) Test</Command>
|
|||||||
<ClInclude Include="glslang\MachineIndependent\Initialize.h" />
|
<ClInclude Include="glslang\MachineIndependent\Initialize.h" />
|
||||||
<ClInclude Include="glslang\MachineIndependent\MMap.h" />
|
<ClInclude Include="glslang\MachineIndependent\MMap.h" />
|
||||||
<ClInclude Include="glslang\MachineIndependent\ParseHelper.h" />
|
<ClInclude Include="glslang\MachineIndependent\ParseHelper.h" />
|
||||||
|
<ClInclude Include="glslang\MachineIndependent\preprocessor\PpContext.h" />
|
||||||
|
<ClInclude Include="glslang\MachineIndependent\preprocessor\PpTokens.h" />
|
||||||
<ClInclude Include="glslang\MachineIndependent\QualifierAlive.h" />
|
<ClInclude Include="glslang\MachineIndependent\QualifierAlive.h" />
|
||||||
<ClInclude Include="glslang\MachineIndependent\RemoveTree.h" />
|
<ClInclude Include="glslang\MachineIndependent\RemoveTree.h" />
|
||||||
<ClInclude Include="glslang\MachineIndependent\localintermediate.h" />
|
<ClInclude Include="glslang\MachineIndependent\localintermediate.h" />
|
||||||
<ClInclude Include="glslang\MachineIndependent\preprocessor\atom.h" />
|
|
||||||
<ClInclude Include="glslang\MachineIndependent\preprocessor\cpp.h" />
|
|
||||||
<ClInclude Include="glslang\MachineIndependent\preprocessor\memory.h" />
|
|
||||||
<ClInclude Include="glslang\MachineIndependent\preprocessor\parser.h" />
|
|
||||||
<ClInclude Include="glslang\MachineIndependent\preprocessor\preprocess.h" />
|
|
||||||
<ClInclude Include="glslang\MachineIndependent\preprocessor\scanner.h" />
|
|
||||||
<ClInclude Include="glslang\MachineIndependent\preprocessor\slglobals.h" />
|
|
||||||
<ClInclude Include="glslang\MachineIndependent\preprocessor\symbols.h" />
|
|
||||||
<ClInclude Include="glslang\MachineIndependent\preprocessor\tokens.h" />
|
|
||||||
<ClInclude Include="glslang\Include\BaseTypes.h" />
|
<ClInclude Include="glslang\Include\BaseTypes.h" />
|
||||||
<ClInclude Include="glslang\Include\Common.h" />
|
<ClInclude Include="glslang\Include\Common.h" />
|
||||||
<ClInclude Include="glslang\Include\ConstantUnion.h" />
|
<ClInclude Include="glslang\Include\ConstantUnion.h" />
|
||||||
@@ -208,7 +203,6 @@ xcopy /y $(IntDir)$(TargetName)$(TargetExt) Test</Command>
|
|||||||
<ClInclude Include="glslang\MachineIndependent\Versions.h" />
|
<ClInclude Include="glslang\MachineIndependent\Versions.h" />
|
||||||
<ClInclude Include="OGLCompilersDLL\InitializeDll.h" />
|
<ClInclude Include="OGLCompilersDLL\InitializeDll.h" />
|
||||||
<ClInclude Include="glslang\Include\InitializeGlobals.h" />
|
<ClInclude Include="glslang\Include\InitializeGlobals.h" />
|
||||||
<ClInclude Include="glslang\Include\InitializeParseContext.h" />
|
|
||||||
<ClInclude Include="glslang\Include\PoolAlloc.h" />
|
<ClInclude Include="glslang\Include\PoolAlloc.h" />
|
||||||
<ClInclude Include="glslang\Include\ResourceLimits.h" />
|
<ClInclude Include="glslang\Include\ResourceLimits.h" />
|
||||||
<ClInclude Include="glslang\Include\ShHandle.h" />
|
<ClInclude Include="glslang\Include\ShHandle.h" />
|
||||||
|
|||||||
@@ -8,9 +8,6 @@
|
|||||||
<Filter Include="Machine Independent\Generated Source">
|
<Filter Include="Machine Independent\Generated Source">
|
||||||
<UniqueIdentifier>{564543b5-6302-49ab-9d24-bd6bef91274a}</UniqueIdentifier>
|
<UniqueIdentifier>{564543b5-6302-49ab-9d24-bd6bef91274a}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter Include="Machine Independent\CPP">
|
|
||||||
<UniqueIdentifier>{5d320e20-4d64-4db1-9d8c-e7fdc234be36}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Header Files">
|
<Filter Include="Header Files">
|
||||||
<UniqueIdentifier>{d4faa328-f693-4b77-9fcb-9629ca0d8ee8}</UniqueIdentifier>
|
<UniqueIdentifier>{d4faa328-f693-4b77-9fcb-9629ca0d8ee8}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
@@ -26,6 +23,9 @@
|
|||||||
<Filter Include="OSDependent\Linux">
|
<Filter Include="OSDependent\Linux">
|
||||||
<UniqueIdentifier>{0c27903f-6ef2-4725-9d9c-70f50aeaa7a1}</UniqueIdentifier>
|
<UniqueIdentifier>{0c27903f-6ef2-4725-9d9c-70f50aeaa7a1}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="Machine Independent\Preprocessor">
|
||||||
|
<UniqueIdentifier>{f25a01e9-79ce-49bf-b79a-d10de89a0fec}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="glslang\MachineIndependent\InfoSink.cpp">
|
<ClCompile Include="glslang\MachineIndependent\InfoSink.cpp">
|
||||||
@@ -67,27 +67,6 @@
|
|||||||
<ClCompile Include="glslang\MachineIndependent\parseConst.cpp">
|
<ClCompile Include="glslang\MachineIndependent\parseConst.cpp">
|
||||||
<Filter>Machine Independent</Filter>
|
<Filter>Machine Independent</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\atom.c">
|
|
||||||
<Filter>Machine Independent\CPP</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\cpp.c">
|
|
||||||
<Filter>Machine Independent\CPP</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\cppstruct.c">
|
|
||||||
<Filter>Machine Independent\CPP</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\memory.c">
|
|
||||||
<Filter>Machine Independent\CPP</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\scanner.c">
|
|
||||||
<Filter>Machine Independent\CPP</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\symbols.c">
|
|
||||||
<Filter>Machine Independent\CPP</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\tokens.c">
|
|
||||||
<Filter>Machine Independent\CPP</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="glslang\OSDependent\Windows\main.cpp">
|
<ClCompile Include="glslang\OSDependent\Windows\main.cpp">
|
||||||
<Filter>OSDependent\Windows</Filter>
|
<Filter>OSDependent\Windows</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -109,6 +88,27 @@
|
|||||||
<ClCompile Include="glslang\MachineIndependent\Scan.cpp">
|
<ClCompile Include="glslang\MachineIndependent\Scan.cpp">
|
||||||
<Filter>Machine Independent</Filter>
|
<Filter>Machine Independent</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="glslang\MachineIndependent\preprocessor\Pp.cpp">
|
||||||
|
<Filter>Machine Independent\Preprocessor</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpAtom.cpp">
|
||||||
|
<Filter>Machine Independent\Preprocessor</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpMemory.cpp">
|
||||||
|
<Filter>Machine Independent\Preprocessor</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpScanner.cpp">
|
||||||
|
<Filter>Machine Independent\Preprocessor</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpSymbols.cpp">
|
||||||
|
<Filter>Machine Independent\Preprocessor</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpTokens.cpp">
|
||||||
|
<Filter>Machine Independent\Preprocessor</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpContext.cpp">
|
||||||
|
<Filter>Machine Independent\Preprocessor</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="glslang\MachineIndependent\Initialize.h">
|
<ClInclude Include="glslang\MachineIndependent\Initialize.h">
|
||||||
@@ -129,33 +129,6 @@
|
|||||||
<ClInclude Include="glslang\MachineIndependent\localintermediate.h">
|
<ClInclude Include="glslang\MachineIndependent\localintermediate.h">
|
||||||
<Filter>Machine Independent</Filter>
|
<Filter>Machine Independent</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="glslang\MachineIndependent\preprocessor\atom.h">
|
|
||||||
<Filter>Machine Independent\CPP</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="glslang\MachineIndependent\preprocessor\cpp.h">
|
|
||||||
<Filter>Machine Independent\CPP</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="glslang\MachineIndependent\preprocessor\memory.h">
|
|
||||||
<Filter>Machine Independent\CPP</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="glslang\MachineIndependent\preprocessor\parser.h">
|
|
||||||
<Filter>Machine Independent\CPP</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="glslang\MachineIndependent\preprocessor\preprocess.h">
|
|
||||||
<Filter>Machine Independent\CPP</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="glslang\MachineIndependent\preprocessor\scanner.h">
|
|
||||||
<Filter>Machine Independent\CPP</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="glslang\MachineIndependent\preprocessor\slglobals.h">
|
|
||||||
<Filter>Machine Independent\CPP</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="glslang\MachineIndependent\preprocessor\symbols.h">
|
|
||||||
<Filter>Machine Independent\CPP</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="glslang\MachineIndependent\preprocessor\tokens.h">
|
|
||||||
<Filter>Machine Independent\CPP</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="glslang\Include\BaseTypes.h">
|
<ClInclude Include="glslang\Include\BaseTypes.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -174,9 +147,6 @@
|
|||||||
<ClInclude Include="glslang\Include\InitializeGlobals.h">
|
<ClInclude Include="glslang\Include\InitializeGlobals.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="glslang\Include\InitializeParseContext.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="glslang\Include\PoolAlloc.h">
|
<ClInclude Include="glslang\Include\PoolAlloc.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -219,6 +189,12 @@
|
|||||||
<ClInclude Include="glslang\MachineIndependent\ScanContext.h">
|
<ClInclude Include="glslang\MachineIndependent\ScanContext.h">
|
||||||
<Filter>Machine Independent</Filter>
|
<Filter>Machine Independent</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="glslang\MachineIndependent\preprocessor\PpContext.h">
|
||||||
|
<Filter>Machine Independent\Preprocessor</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="glslang\MachineIndependent\preprocessor\PpTokens.h">
|
||||||
|
<Filter>Machine Independent\Preprocessor</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<CustomBuild Include="glslang\MachineIndependent\glslang.y">
|
<CustomBuild Include="glslang\MachineIndependent\glslang.y">
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
//
|
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
|
||||||
//All rights reserved.
|
|
||||||
//
|
|
||||||
//Redistribution and use in source and binary forms, with or without
|
|
||||||
//modification, are permitted provided that the following conditions
|
|
||||||
//are met:
|
|
||||||
//
|
|
||||||
// Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following
|
|
||||||
// disclaimer in the documentation and/or other materials provided
|
|
||||||
// with the distribution.
|
|
||||||
//
|
|
||||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived
|
|
||||||
// from this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef __INITIALIZE_PARSE_CONTEXT_INCLUDED_
|
|
||||||
#define __INITIALIZE_PARSE_CONTEXT_INCLUDED_
|
|
||||||
#include "osinclude.h"
|
|
||||||
|
|
||||||
bool InitializeParseContextIndex();
|
|
||||||
bool InitializeThreadParseContext();
|
|
||||||
bool FreeParseContext();
|
|
||||||
bool FreeParseContextIndex();
|
|
||||||
|
|
||||||
|
|
||||||
#endif // __INITIALIZE_PARSE_CONTEXT_INCLUDED_
|
|
||||||
@@ -13,7 +13,7 @@ OBJECTS= Initialize.o IntermTraverse.o \
|
|||||||
RemoveTree.o ShaderLang.o intermOut.o parseConst.o SymbolTable.o \
|
RemoveTree.o ShaderLang.o intermOut.o parseConst.o SymbolTable.o \
|
||||||
InfoSink.o Versions.o Constant.o Scan.o
|
InfoSink.o Versions.o Constant.o Scan.o
|
||||||
|
|
||||||
SRCS= gen_glslang.cpp gen_glslang_tab.cpp Initialize.cpp IntermTraverse.cpp \
|
SRCS= gen_glslang_tab.cpp Initialize.cpp IntermTraverse.cpp \
|
||||||
Intermediate.cpp ParseHelper.cpp PoolAlloc.cp QualifierAlive.cpp \
|
Intermediate.cpp ParseHelper.cpp PoolAlloc.cp QualifierAlive.cpp \
|
||||||
RemoveTree.cpp ShaderLang.cpp SymbolTable.cpp intermOut.cpp \
|
RemoveTree.cpp ShaderLang.cpp SymbolTable.cpp intermOut.cpp \
|
||||||
parseConst.cpp InfoSink.cpp Versions.cpp Constant.cpp Scan.cpp
|
parseConst.cpp InfoSink.cpp Versions.cpp Constant.cpp Scan.cpp
|
||||||
@@ -24,21 +24,13 @@ default: all
|
|||||||
|
|
||||||
all: $(SHAREDOBJECT)
|
all: $(SHAREDOBJECT)
|
||||||
|
|
||||||
$(SHAREDOBJECT): gen_glslang.o gen_glslang_tab.o $(OBJECTS) \
|
$(SHAREDOBJECT): gen_glslang_tab.o $(OBJECTS) \
|
||||||
$(LIBPREPROCESSOR) $(LIBCODEGEN) $(LIBOSDEPENDENT) $(LIBINITIALISATION)
|
$(LIBPREPROCESSOR) $(LIBCODEGEN) $(LIBOSDEPENDENT) $(LIBINITIALISATION)
|
||||||
$(CC) -fPIC -shared -o $@ -rdynamic -Wl,-whole-archive $(OBJECTS) $(LIBPREPROCESSOR) $(LIBCODEGEN) $(LIBOSDEPENDENT) $(LIBINITIALISATION) gen_glslang.o gen_glslang_tab.o -Wl,-no-whole-archive
|
$(CC) -fPIC -shared -o $@ -rdynamic -Wl,-whole-archive $(OBJECTS) $(LIBPREPROCESSOR) $(LIBCODEGEN) $(LIBOSDEPENDENT) $(LIBINITIALISATION) gen_glslang_tab.o -Wl,-no-whole-archive
|
||||||
|
|
||||||
gen_glslang.o : gen_glslang.cpp glslang_tab.h
|
|
||||||
$(CC) -fPIC -c $(INCLUDE) gen_glslang.cpp -o $@
|
|
||||||
|
|
||||||
gen_glslang_tab.o : gen_glslang_tab.cpp
|
gen_glslang_tab.o : gen_glslang_tab.cpp
|
||||||
$(CC) -fPIC -c $(INCLUDE) gen_glslang_tab.cpp -o $@
|
$(CC) -fPIC -c $(INCLUDE) gen_glslang_tab.cpp -o $@
|
||||||
|
|
||||||
gen_glslang.cpp: glslang.l
|
|
||||||
@echo Generating gen_glslang.cpp
|
|
||||||
@dos2unix glslang.l
|
|
||||||
flex glslang.l
|
|
||||||
|
|
||||||
gen_glslang_tab.cpp glslang_tab.h: glslang.y
|
gen_glslang_tab.cpp glslang_tab.h: glslang.y
|
||||||
@echo Generating gen_glslang_tab.cpp
|
@echo Generating gen_glslang_tab.cpp
|
||||||
@dos2unix glslang.y
|
@dos2unix glslang.y
|
||||||
@@ -72,7 +64,7 @@ depend:
|
|||||||
#
|
#
|
||||||
.PHONY : clean
|
.PHONY : clean
|
||||||
clean :
|
clean :
|
||||||
$(RM) *.o *.a gen_glslang_tab.cpp glslang_tab.cpp glslang_tab.cpp.h gen_glslang.cpp glslang_tab.h glslang.output
|
$(RM) *.o *.a gen_glslang_tab.cpp glslang_tab.cpp glslang_tab.cpp.h glslang_tab.h glslang.output
|
||||||
$(RM) ./lib/*.so
|
$(RM) ./lib/*.so
|
||||||
cd $(INCPREPROCESSOR); make clean
|
cd $(INCPREPROCESSOR); make clean
|
||||||
cd $(INCCODEGEN); make clean
|
cd $(INCCODEGEN); make clean
|
||||||
@@ -81,19 +73,6 @@ clean :
|
|||||||
|
|
||||||
# DO NOT DELETE
|
# DO NOT DELETE
|
||||||
|
|
||||||
gen_glslang.o: ParseHelper.h ../Include/ShHandle.h
|
|
||||||
gen_glslang.o: ../Public/ShaderLang.h ../Include/InfoSink.h
|
|
||||||
gen_glslang.o: ../Include/Common.h ../Include/PoolAlloc.h SymbolTable.h
|
|
||||||
gen_glslang.o: ../Include/Common.h ../Include/intermediate.h
|
|
||||||
gen_glslang.o: ../Include/Types.h ../Include/BaseTypes.h
|
|
||||||
gen_glslang.o: ../Include/ConstantUnion.h ../Include/InfoSink.h
|
|
||||||
gen_glslang.o: localintermediate.h ../Include/intermediate.h
|
|
||||||
gen_glslang.o: ../Public/ShaderLang.h glslang_tab.h ./unistd.h
|
|
||||||
gen_glslang.o: ./preprocessor/preprocess.h ./preprocessor/slglobals.h
|
|
||||||
gen_glslang.o: ./preprocessor/memory.h ./preprocessor/atom.h
|
|
||||||
gen_glslang.o: ./preprocessor/scanner.h ./preprocessor/parser.h
|
|
||||||
gen_glslang.o: ./preprocessor/cpp.h ./preprocessor/tokens.h
|
|
||||||
gen_glslang.o: ./preprocessor/symbols.h ./preprocessor/compile.h
|
|
||||||
gen_glslang_tab.o: SymbolTable.h ../Include/Common.h
|
gen_glslang_tab.o: SymbolTable.h ../Include/Common.h
|
||||||
gen_glslang_tab.o: ../Include/intermediate.h ../Include/Common.h
|
gen_glslang_tab.o: ../Include/intermediate.h ../Include/Common.h
|
||||||
gen_glslang_tab.o: ../Include/PoolAlloc.h ../Include/Types.h
|
gen_glslang_tab.o: ../Include/PoolAlloc.h ../Include/Types.h
|
||||||
@@ -126,10 +105,15 @@ ParseHelper.o: ../Include/Common.h ../Include/intermediate.h
|
|||||||
ParseHelper.o: ../Include/Types.h ../Include/BaseTypes.h
|
ParseHelper.o: ../Include/Types.h ../Include/BaseTypes.h
|
||||||
ParseHelper.o: ../Include/ConstantUnion.h ../Include/InfoSink.h
|
ParseHelper.o: ../Include/ConstantUnion.h ../Include/InfoSink.h
|
||||||
ParseHelper.o: localintermediate.h ../Include/intermediate.h
|
ParseHelper.o: localintermediate.h ../Include/intermediate.h
|
||||||
ParseHelper.o: ../Public/ShaderLang.h ../Include/InitializeParseContext.h
|
ParseHelper.o: ../Public/ShaderLang.h
|
||||||
ParseHelper.o: ../OSDependent/Linux/osinclude.h
|
ParseHelper.o: ../OSDependent/Linux/osinclude.h
|
||||||
ParseHelper.o: ../Include/InitializeGlobals.h ../Include/PoolAlloc.h
|
ParseHelper.o: ../Include/InitializeGlobals.h ../Include/PoolAlloc.h
|
||||||
QualifierAlive.o: ../Include/intermediate.h
|
QualifierAlive.o: ../Include/intermediate.h
|
||||||
|
Scan.o: Scan.h
|
||||||
|
Scan.o: ParseHelper.h SymbolTable.h
|
||||||
|
Scan.o: glslang_tab.cpp.h
|
||||||
|
Scan.o: ../Include/Types.h
|
||||||
|
Scan.o: ScanContext.h preprocessor/PpContext.h preprocessor/PpTokens.h
|
||||||
RemoveTree.o: ../Include/intermediate.h RemoveTree.h
|
RemoveTree.o: ../Include/intermediate.h RemoveTree.h
|
||||||
ShaderLang.o: SymbolTable.h ../Include/Common.h ../Include/intermediate.h
|
ShaderLang.o: SymbolTable.h ../Include/Common.h ../Include/intermediate.h
|
||||||
ShaderLang.o: ../Include/Common.h ../Include/PoolAlloc.h ../Include/Types.h
|
ShaderLang.o: ../Include/Common.h ../Include/PoolAlloc.h ../Include/Types.h
|
||||||
@@ -161,4 +145,3 @@ parseConst.o: ../Public/ShaderLang.h
|
|||||||
InfoSink.o: ../Include/InfoSink.h
|
InfoSink.o: ../Include/InfoSink.h
|
||||||
Versions.o: ParseHelper.h Versions.h ../Include/ShHandle.h SymbolTable.h localintermediate.h
|
Versions.o: ParseHelper.h Versions.h ../Include/ShHandle.h SymbolTable.h localintermediate.h
|
||||||
Constant.o: localintermediate.h ../Include/intermediate.h ../Public/ShaderLang.h SymbolTable.h Versions.h
|
Constant.o: localintermediate.h ../Include/intermediate.h ../Public/ShaderLang.h SymbolTable.h Versions.h
|
||||||
Scan.o: Scan.h Versions.h
|
|
||||||
|
|||||||
@@ -35,14 +35,11 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "ParseHelper.h"
|
#include "ParseHelper.h"
|
||||||
#include "Include/InitializeParseContext.h"
|
|
||||||
#include "osinclude.h"
|
#include "osinclude.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
extern "C" {
|
#include "preprocessor/PpContext.h"
|
||||||
#include "./preprocessor/preprocess.h"
|
|
||||||
}
|
|
||||||
|
|
||||||
TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb, int v, EProfile p, EShLanguage L, TInfoSink& is,
|
TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb, int v, EProfile p, EShLanguage L, TInfoSink& is,
|
||||||
bool fc, EShMessages m) :
|
bool fc, EShMessages m) :
|
||||||
@@ -50,8 +47,11 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb,
|
|||||||
numErrors(0), loopNestingLevel(0),
|
numErrors(0), loopNestingLevel(0),
|
||||||
structNestingLevel(0), inTypeParen(false), parsingBuiltins(pb),
|
structNestingLevel(0), inTypeParen(false), parsingBuiltins(pb),
|
||||||
version(v), profile(p), forwardCompatible(fc), messages(m),
|
version(v), profile(p), forwardCompatible(fc), messages(m),
|
||||||
contextPragma(true, false)
|
contextPragma(true, false), afterEOF(false), tokensBeforeEOF(false)
|
||||||
{
|
{
|
||||||
|
currentLoc.line = 1;
|
||||||
|
currentLoc.string = 0;
|
||||||
|
|
||||||
// set all precision defaults to EpqNone, which is correct for all desktop types
|
// set all precision defaults to EpqNone, which is correct for all desktop types
|
||||||
// and for ES types that don't have defaults (thus getting an error on use)
|
// and for ES types that don't have defaults (thus getting an error on use)
|
||||||
for (int type = 0; type < EbtNumTypes; ++type)
|
for (int type = 0; type < EbtNumTypes; ++type)
|
||||||
@@ -104,24 +104,20 @@ const char* TParseContext::getPreamble()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TSourceLoc currentLine; // TODO: thread: get this into the scan context, sort out with return from PP
|
extern int yyparse(void*);
|
||||||
#ifdef _WIN32
|
|
||||||
extern int yyparse(TParseContext&);
|
|
||||||
#else
|
|
||||||
extern int yyparse(void*);
|
|
||||||
#define parseContext (*((TParseContext*)(parseContextLocal)))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Parse an array of strings using yyparse. We set up globals used by
|
// Parse an array of strings using yyparse, going through the
|
||||||
// yywrap.
|
// preprocessor to tokenize the shader strings, then through
|
||||||
|
// the GLSL scanner.
|
||||||
//
|
//
|
||||||
// Returns true for success, false for failure.
|
// Returns true for successful acceptance of the shader, false if any errors.
|
||||||
//
|
//
|
||||||
bool TParseContext::parseShaderStrings(char* strings[], int strLen[], int numStrings)
|
bool TParseContext::parseShaderStrings(TPpContext& ppContext, char* strings[], int lengths[], int numStrings)
|
||||||
{
|
{
|
||||||
if (! strings || numStrings == 0)
|
// empty shaders are okay
|
||||||
return false;
|
if (! strings || numStrings == 0 || lengths[0] == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
for (int i = 0; i < numStrings; ++i) {
|
for (int i = 0; i < numStrings; ++i) {
|
||||||
if (! strings[i]) {
|
if (! strings[i]) {
|
||||||
@@ -134,36 +130,9 @@ bool TParseContext::parseShaderStrings(char* strings[], int strLen[], int numStr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set up all the cpp fields...
|
if (getPreamble())
|
||||||
// TODO: thread safety: don't move 'this' into the global
|
ppContext.setPreamble(getPreamble(), strlen(getPreamble()));
|
||||||
cpp->pC = (void*)this;
|
ppContext.setShaderStrings(strings, lengths, numStrings);
|
||||||
const char* preamble = getPreamble();
|
|
||||||
char *writeablePreamble = 0;
|
|
||||||
if (preamble) {
|
|
||||||
// preAmble could be a hard-coded string; make writable copy
|
|
||||||
// TODO: efficiency PP: make it not need writable strings
|
|
||||||
int size = strlen(preamble) + 1;
|
|
||||||
writeablePreamble = new char[size];
|
|
||||||
memcpy(writeablePreamble, preamble, size);
|
|
||||||
ScanFromString(writeablePreamble);
|
|
||||||
cpp->PaWhichStr = -1;
|
|
||||||
} else {
|
|
||||||
ScanFromString(strings[0]);
|
|
||||||
cpp->PaWhichStr = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
afterEOF = false;
|
|
||||||
cpp->PaArgv = strings;
|
|
||||||
cpp->PaArgc = numStrings;
|
|
||||||
int string0len;
|
|
||||||
if (! strLen) {
|
|
||||||
string0len = (int) strlen(strings[0]);
|
|
||||||
cpp->PaStrLen = &string0len;
|
|
||||||
} else
|
|
||||||
cpp->PaStrLen = strLen;
|
|
||||||
cpp->notAVersionToken = 0;
|
|
||||||
currentLine.string = 0;
|
|
||||||
currentLine.line = 1;
|
|
||||||
|
|
||||||
// TODO: desktop PP: a shader containing nothing but white space and comments is valid, even though it has no parse tokens
|
// TODO: desktop PP: a shader containing nothing but white space and comments is valid, even though it has no parse tokens
|
||||||
int len = 0;
|
int len = 0;
|
||||||
@@ -171,170 +140,73 @@ bool TParseContext::parseShaderStrings(char* strings[], int strLen[], int numStr
|
|||||||
strings[0][len] == '\t' ||
|
strings[0][len] == '\t' ||
|
||||||
strings[0][len] == '\n' ||
|
strings[0][len] == '\n' ||
|
||||||
strings[0][len] == '\r') {
|
strings[0][len] == '\r') {
|
||||||
if (++len >= strLen[0]) {
|
if (++len >= lengths[0])
|
||||||
delete writeablePreamble;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*cpp->PaStrLen > 0) {
|
|
||||||
int ret;
|
|
||||||
#ifdef _WIN32
|
|
||||||
ret = yyparse(*this);
|
|
||||||
#else
|
|
||||||
ret = yyparse((void*)this);
|
|
||||||
#endif
|
|
||||||
delete writeablePreamble;
|
|
||||||
if (cpp->CompileError == 1 || numErrors > 0)
|
|
||||||
return false;
|
|
||||||
else
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete writeablePreamble;
|
yyparse((void*)this);
|
||||||
|
|
||||||
return true;
|
return numErrors == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: fix this for threads
|
// This is called from bison when it has a parse (syntax) error
|
||||||
void yyerror(const char *s)
|
void TParseContext::parserError(const char *s)
|
||||||
{
|
{
|
||||||
TParseContext& pc = *((TParseContext *)cpp->pC);
|
if (afterEOF) {
|
||||||
|
if (tokensBeforeEOF == 1)
|
||||||
if (pc.afterEOF) {
|
error(currentLoc, "", "pre-mature EOF", s, "");
|
||||||
if (cpp->tokensBeforeEOF == 1)
|
|
||||||
ThreadLocalParseContext()->error(currentLine, "", "pre-mature EOF", s, "");
|
|
||||||
} else
|
} else
|
||||||
ThreadLocalParseContext()->error(currentLine, "", "", s, "");
|
error(currentLoc, "", "", s, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TParseContext::handlePragma(const char **tokens, int numTokens)
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
// Communications with the preprocess.
|
|
||||||
// TODO: threads: this all needs redoing for thread safety
|
|
||||||
|
|
||||||
void ShPpDebugLogMsg(const char *msg)
|
|
||||||
{
|
{
|
||||||
TParseContext& pc = *((TParseContext *)cpp->pC);
|
|
||||||
|
|
||||||
pc.infoSink.debug.message(EPrefixNone, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShPpWarningToInfoLog(const char *msg)
|
|
||||||
{
|
|
||||||
TParseContext& pc = *((TParseContext *)cpp->pC);
|
|
||||||
|
|
||||||
pc.warn(currentLine, msg, "Preprocessor", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShPpErrorToInfoLog(const char *msg)
|
|
||||||
{
|
|
||||||
TParseContext& pc = *((TParseContext *)cpp->pC);
|
|
||||||
|
|
||||||
pc.error(currentLine, msg, "Preprocessor", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
// return 1 if error
|
|
||||||
// return 0 if no error
|
|
||||||
int ShPpMacrosMustBeDefinedError()
|
|
||||||
{
|
|
||||||
TParseContext& pc = *((TParseContext *)cpp->pC);
|
|
||||||
|
|
||||||
if (pc.profile == EEsProfile) {
|
|
||||||
if (pc.messages & EShMsgRelaxedErrors)
|
|
||||||
ShPpWarningToInfoLog("undefined macro in expression not allowed in es profile");
|
|
||||||
else {
|
|
||||||
ShPpErrorToInfoLog("undefined macro in expression");
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: PP/threads: integrate this with location from token
|
|
||||||
void SetLineNumber(int line)
|
|
||||||
{
|
|
||||||
currentLine.line = line;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetStringNumber(int string)
|
|
||||||
{
|
|
||||||
currentLine.string = string;
|
|
||||||
}
|
|
||||||
|
|
||||||
int GetStringNumber(void)
|
|
||||||
{
|
|
||||||
return currentLine.string;
|
|
||||||
}
|
|
||||||
|
|
||||||
int GetLineNumber(void)
|
|
||||||
{
|
|
||||||
return currentLine.line;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IncLineNumber(void)
|
|
||||||
{
|
|
||||||
++currentLine.line;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DecLineNumber(void)
|
|
||||||
{
|
|
||||||
--currentLine.line;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandlePragma(const char **tokens, int numTokens)
|
|
||||||
{
|
|
||||||
TParseContext& pc = *((TParseContext *)cpp->pC);
|
|
||||||
|
|
||||||
if (!strcmp(tokens[0], "optimize")) {
|
if (!strcmp(tokens[0], "optimize")) {
|
||||||
if (numTokens != 4) {
|
if (numTokens != 4) {
|
||||||
ShPpErrorToInfoLog("optimize pragma syntax is incorrect");
|
error(currentLoc, "optimize pragma syntax is incorrect", "#pragma", "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(tokens[1], "(")) {
|
if (strcmp(tokens[1], "(")) {
|
||||||
ShPpErrorToInfoLog("\"(\" expected after 'optimize' keyword");
|
error(currentLoc, "\"(\" expected after 'optimize' keyword", "#pragma", "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(tokens[2], "on"))
|
if (!strcmp(tokens[2], "on"))
|
||||||
pc.contextPragma.optimize = true;
|
contextPragma.optimize = true;
|
||||||
else if (!strcmp(tokens[2], "off"))
|
else if (!strcmp(tokens[2], "off"))
|
||||||
pc.contextPragma.optimize = false;
|
contextPragma.optimize = false;
|
||||||
else {
|
else {
|
||||||
ShPpErrorToInfoLog("\"on\" or \"off\" expected after '(' for 'optimize' pragma");
|
error(currentLoc, "\"on\" or \"off\" expected after '(' for 'optimize' pragma", "#pragma", "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(tokens[3], ")")) {
|
if (strcmp(tokens[3], ")")) {
|
||||||
ShPpErrorToInfoLog("\")\" expected to end 'optimize' pragma");
|
error(currentLoc, "\")\" expected to end 'optimize' pragma", "#pragma", "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (!strcmp(tokens[0], "debug")) {
|
} else if (!strcmp(tokens[0], "debug")) {
|
||||||
if (numTokens != 4) {
|
if (numTokens != 4) {
|
||||||
ShPpErrorToInfoLog("debug pragma syntax is incorrect");
|
error(currentLoc, "debug pragma syntax is incorrect", "#pragma", "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(tokens[1], "(")) {
|
if (strcmp(tokens[1], "(")) {
|
||||||
ShPpErrorToInfoLog("\"(\" expected after 'debug' keyword");
|
error(currentLoc, "\"(\" expected after 'debug' keyword", "#pragma", "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(tokens[2], "on"))
|
if (!strcmp(tokens[2], "on"))
|
||||||
pc.contextPragma.debug = true;
|
contextPragma.debug = true;
|
||||||
else if (!strcmp(tokens[2], "off"))
|
else if (!strcmp(tokens[2], "off"))
|
||||||
pc.contextPragma.debug = false;
|
contextPragma.debug = false;
|
||||||
else {
|
else {
|
||||||
ShPpErrorToInfoLog("\"on\" or \"off\" expected after '(' for 'debug' pragma");
|
error(currentLoc, "\"on\" or \"off\" expected after '(' for 'debug' pragma", "#pragma", "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(tokens[3], ")")) {
|
if (strcmp(tokens[3], ")")) {
|
||||||
ShPpErrorToInfoLog("\")\" expected to end 'debug' pragma");
|
error(currentLoc, "\")\" expected to end 'debug' pragma", "#pragma", "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -371,47 +243,7 @@ void HandlePragma(const char **tokens, int numTokens)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StoreStr(const char *string)
|
TBehavior TParseContext::getExtensionBehavior(const char* behavior)
|
||||||
{
|
|
||||||
TParseContext& pc = *((TParseContext *)cpp->pC);
|
|
||||||
|
|
||||||
TString strSrc;
|
|
||||||
strSrc = TString(string);
|
|
||||||
|
|
||||||
pc.HashErrMsg = pc.HashErrMsg + " " + strSrc;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* GetStrfromTStr(void)
|
|
||||||
{
|
|
||||||
TParseContext& pc = *((TParseContext *)cpp->pC);
|
|
||||||
|
|
||||||
cpp->ErrMsg = pc.HashErrMsg.c_str();
|
|
||||||
return cpp->ErrMsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResetTString(void)
|
|
||||||
{
|
|
||||||
TParseContext& pc = *((TParseContext *)cpp->pC);
|
|
||||||
|
|
||||||
pc.HashErrMsg = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetVersion(int version)
|
|
||||||
{
|
|
||||||
// called by the CPP, but this functionality is currently
|
|
||||||
// taken over by ScanVersion() before parsing starts
|
|
||||||
|
|
||||||
// CPP should still report errors in semantics
|
|
||||||
}
|
|
||||||
|
|
||||||
int GetShaderVersion(void* cppPc)
|
|
||||||
{
|
|
||||||
TParseContext& pc = *((TParseContext *)cppPc);
|
|
||||||
|
|
||||||
return pc.version;
|
|
||||||
}
|
|
||||||
|
|
||||||
TBehavior GetBehavior(const char* behavior)
|
|
||||||
{
|
{
|
||||||
if (!strcmp("require", behavior))
|
if (!strcmp("require", behavior))
|
||||||
return EBhRequire;
|
return EBhRequire;
|
||||||
@@ -422,38 +254,37 @@ TBehavior GetBehavior(const char* behavior)
|
|||||||
else if (!strcmp("warn", behavior))
|
else if (!strcmp("warn", behavior))
|
||||||
return EBhWarn;
|
return EBhWarn;
|
||||||
else {
|
else {
|
||||||
ShPpErrorToInfoLog((TString("behavior '") + behavior + "' is not supported").c_str());
|
error(currentLoc, "behavior not supported", "#extension", behavior);
|
||||||
return EBhDisable;
|
return EBhDisable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateExtensionBehavior(const char* extName, const char* behavior)
|
void TParseContext::updateExtensionBehavior(const char* extName, const char* behavior)
|
||||||
{
|
{
|
||||||
TParseContext& pc = *((TParseContext *)cpp->pC);
|
TBehavior behaviorVal = getExtensionBehavior(behavior);
|
||||||
TBehavior behaviorVal = GetBehavior(behavior);
|
|
||||||
TMap<TString, TBehavior>:: iterator iter;
|
TMap<TString, TBehavior>:: iterator iter;
|
||||||
TString msg;
|
TString msg;
|
||||||
|
|
||||||
// special cased for all extension
|
// special cased for all extension
|
||||||
if (!strcmp(extName, "all")) {
|
if (!strcmp(extName, "all")) {
|
||||||
if (behaviorVal == EBhRequire || behaviorVal == EBhEnable) {
|
if (behaviorVal == EBhRequire || behaviorVal == EBhEnable) {
|
||||||
ShPpErrorToInfoLog("extension 'all' cannot have 'require' or 'enable' behavior");
|
error(currentLoc, "extension 'all' cannot have 'require' or 'enable' behavior", "#extension", "");
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
for (iter = pc.extensionBehavior.begin(); iter != pc.extensionBehavior.end(); ++iter)
|
for (iter = extensionBehavior.begin(); iter != extensionBehavior.end(); ++iter)
|
||||||
iter->second = behaviorVal;
|
iter->second = behaviorVal;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
iter = pc.extensionBehavior.find(TString(extName));
|
iter = extensionBehavior.find(TString(extName));
|
||||||
if (iter == pc.extensionBehavior.end()) {
|
if (iter == extensionBehavior.end()) {
|
||||||
switch (behaviorVal) {
|
switch (behaviorVal) {
|
||||||
case EBhRequire:
|
case EBhRequire:
|
||||||
ShPpErrorToInfoLog((TString("extension '") + extName + "' is not supported").c_str());
|
error(currentLoc, "extension not supported", "#extension", extName);
|
||||||
break;
|
break;
|
||||||
case EBhEnable:
|
case EBhEnable:
|
||||||
case EBhWarn:
|
case EBhWarn:
|
||||||
case EBhDisable:
|
case EBhDisable:
|
||||||
pc.warn(currentLine, "extension not supported", extName, "");
|
warn(currentLoc, "extension not supported", "#extension", extName);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0 && "unexpected behaviorVal");
|
assert(0 && "unexpected behaviorVal");
|
||||||
@@ -465,9 +296,6 @@ void updateExtensionBehavior(const char* extName, const char* behavior)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // extern "C"
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Sub- vector and matrix fields
|
// Sub- vector and matrix fields
|
||||||
@@ -2383,89 +2211,3 @@ void TParseContext::initializeExtensionBehavior()
|
|||||||
extensionBehavior["GL_ARB_texture_rectangle"] = EBhDisable;
|
extensionBehavior["GL_ARB_texture_rectangle"] = EBhDisable;
|
||||||
extensionBehavior["GL_3DL_array_objects"] = EBhDisable;
|
extensionBehavior["GL_3DL_array_objects"] = EBhDisable;
|
||||||
}
|
}
|
||||||
|
|
||||||
OS_TLSIndex GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
|
|
||||||
|
|
||||||
bool InitializeParseContextIndex()
|
|
||||||
{
|
|
||||||
if (GlobalParseContextIndex != OS_INVALID_TLS_INDEX) {
|
|
||||||
assert(0 && "InitializeParseContextIndex(): Parse Context already initialised");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Allocate a TLS index.
|
|
||||||
//
|
|
||||||
GlobalParseContextIndex = OS_AllocTLSIndex();
|
|
||||||
|
|
||||||
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
|
|
||||||
assert(0 && "InitializeParseContextIndex(): Parse Context already initialised");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InitializeThreadParseContext()
|
|
||||||
{
|
|
||||||
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
|
|
||||||
assert(0 && "InitializeThreadParseContext(): Parse Context index not initialized");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
|
|
||||||
if (lpParseContext != 0) {
|
|
||||||
assert(0 && "InitializeParseContextIndex(): Parse Context already initialized");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
TThreadParseContext *lpThreadData = new TThreadParseContext();
|
|
||||||
if (lpThreadData == 0) {
|
|
||||||
assert(0 && "InitializeThreadParseContext(): Unable to create thread parse context");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
lpThreadData->lpGlobalParseContext = 0;
|
|
||||||
OS_SetTLSValue(GlobalParseContextIndex, lpThreadData);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
TParseContextPointer& ThreadLocalParseContext()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Minimal error checking for speed
|
|
||||||
//
|
|
||||||
|
|
||||||
TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
|
|
||||||
|
|
||||||
return lpParseContext->lpGlobalParseContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FreeParseContext()
|
|
||||||
{
|
|
||||||
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
|
|
||||||
assert(0 && "FreeParseContext(): Parse Context index not initialized");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
|
|
||||||
if (lpParseContext)
|
|
||||||
delete lpParseContext;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FreeParseContextIndex()
|
|
||||||
{
|
|
||||||
OS_TLSIndex tlsiIndex = GlobalParseContextIndex;
|
|
||||||
|
|
||||||
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
|
|
||||||
assert(0 && "FreeParseContextIndex(): Parse Context index not initialized");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
|
|
||||||
|
|
||||||
return OS_FreeTLSIndex(tlsiIndex);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ struct TPragma {
|
|||||||
TPragmaTable pragmaTable;
|
TPragmaTable pragmaTable;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TPpContext;
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
class TScanContext;
|
class TScanContext;
|
||||||
};
|
};
|
||||||
@@ -63,10 +65,13 @@ namespace glslang {
|
|||||||
// The following are extra variables needed during parsing, grouped together so
|
// The following are extra variables needed during parsing, grouped together so
|
||||||
// they can be passed to the parser without needing a global.
|
// they can be passed to the parser without needing a global.
|
||||||
//
|
//
|
||||||
struct TParseContext {
|
class TParseContext {
|
||||||
|
public:
|
||||||
TParseContext(TSymbolTable&, TIntermediate&, bool parsingBuiltins, int version, EProfile, EShLanguage, TInfoSink&,
|
TParseContext(TSymbolTable&, TIntermediate&, bool parsingBuiltins, int version, EProfile, EShLanguage, TInfoSink&,
|
||||||
bool forwardCompatible = false, EShMessages messages = EShMsgDefault);
|
bool forwardCompatible = false, EShMessages messages = EShMsgDefault);
|
||||||
glslang::TScanContext *scanContext;
|
|
||||||
|
glslang::TScanContext* scanContext;
|
||||||
|
TPpContext* ppContext;
|
||||||
TIntermediate& intermediate; // to hold and build a parse tree
|
TIntermediate& intermediate; // to hold and build a parse tree
|
||||||
TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile
|
TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile
|
||||||
TInfoSink& infoSink;
|
TInfoSink& infoSink;
|
||||||
@@ -92,8 +97,9 @@ struct TParseContext {
|
|||||||
TPrecisionQualifier defaultPrecision[EbtNumTypes];
|
TPrecisionQualifier defaultPrecision[EbtNumTypes];
|
||||||
static const int maxSamplerIndex = EsdNumDims * (EbtNumTypes * (2 * 2)); // see computeSamplerTypeIndex()
|
static const int maxSamplerIndex = EsdNumDims * (EbtNumTypes * (2 * 2)); // see computeSamplerTypeIndex()
|
||||||
TPrecisionQualifier defaultSamplerPrecision[maxSamplerIndex];
|
TPrecisionQualifier defaultSamplerPrecision[maxSamplerIndex];
|
||||||
TString HashErrMsg;
|
|
||||||
bool afterEOF;
|
bool afterEOF;
|
||||||
|
bool tokensBeforeEOF;
|
||||||
|
TSourceLoc currentLoc;
|
||||||
const TString* blockName;
|
const TString* blockName;
|
||||||
TQualifier globalUniformDefaults;
|
TQualifier globalUniformDefaults;
|
||||||
TQualifier globalInputDefaults;
|
TQualifier globalInputDefaults;
|
||||||
@@ -102,7 +108,12 @@ struct TParseContext {
|
|||||||
|
|
||||||
void initializeExtensionBehavior();
|
void initializeExtensionBehavior();
|
||||||
const char* getPreamble();
|
const char* getPreamble();
|
||||||
bool parseShaderStrings(char* strings[], int strLen[], int numStrings);
|
bool parseShaderStrings(TPpContext&, char* strings[], int strLen[], int numStrings);
|
||||||
|
void parserError(const char *s);
|
||||||
|
|
||||||
|
void handlePragma(const char **tokens, int numTokens);
|
||||||
|
TBehavior getExtensionBehavior(const char* behavior);
|
||||||
|
void updateExtensionBehavior(const char* extName, const char* behavior);
|
||||||
|
|
||||||
void C_DECL error(TSourceLoc, const char *szReason, const char *szToken,
|
void C_DECL error(TSourceLoc, const char *szReason, const char *szToken,
|
||||||
const char *szExtraInfoFormat, ...);
|
const char *szExtraInfoFormat, ...);
|
||||||
@@ -183,13 +194,4 @@ struct TParseContext {
|
|||||||
void doubleCheck(TSourceLoc, const char* op);
|
void doubleCheck(TSourceLoc, const char* op);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef TParseContext* TParseContextPointer;
|
|
||||||
TParseContextPointer& ThreadLocalParseContext();
|
|
||||||
|
|
||||||
// TODO: threading:
|
|
||||||
typedef struct TThreadParseContextRec
|
|
||||||
{
|
|
||||||
TParseContext *lpGlobalParseContext;
|
|
||||||
} TThreadParseContext;
|
|
||||||
|
|
||||||
#endif // _PARSER_HELPER_INCLUDED_
|
#endif // _PARSER_HELPER_INCLUDED_
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ OS_TLSIndex PoolIndex;
|
|||||||
|
|
||||||
void InitializeGlobalPools()
|
void InitializeGlobalPools()
|
||||||
{
|
{
|
||||||
TThreadGlobalPools* globalPools= static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
|
TThreadGlobalPools* globalPools = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
|
||||||
if (globalPools)
|
if (globalPools)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -48,10 +48,8 @@
|
|||||||
#include "ScanContext.h"
|
#include "ScanContext.h"
|
||||||
|
|
||||||
// preprocessor includes
|
// preprocessor includes
|
||||||
extern "C" {
|
#include "preprocessor/PpContext.h"
|
||||||
#include "preprocessor/parser.h"
|
#include "preprocessor/PpTokens.h"
|
||||||
#include "preprocessor/preprocess.h"
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
@@ -236,12 +234,6 @@ bool ScanVersion(TInputScanner& input, int& version, EProfile& profile)
|
|||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
// This gets filled in by the preprocessor scanner.
|
|
||||||
class TPpToken{
|
|
||||||
public:
|
|
||||||
yystypepp lexer;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Fill this in when doing glslang-level scanning, to hand back to the parser.
|
// Fill this in when doing glslang-level scanning, to hand back to the parser.
|
||||||
class TParserToken {
|
class TParserToken {
|
||||||
public:
|
public:
|
||||||
@@ -257,7 +249,7 @@ int yylex(YYSTYPE* glslangTokenDesc, TParseContext& parseContext)
|
|||||||
{
|
{
|
||||||
glslang::TParserToken token(*glslangTokenDesc);
|
glslang::TParserToken token(*glslangTokenDesc);
|
||||||
|
|
||||||
return parseContext.scanContext->tokenize(token);
|
return parseContext.scanContext->tokenize(parseContext.ppContext, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -487,17 +479,15 @@ void TScanContext::fillInKeywordMap()
|
|||||||
ReservedSet->insert("using");
|
ReservedSet->insert("using");
|
||||||
}
|
}
|
||||||
|
|
||||||
int TScanContext::tokenize(TParserToken& token)
|
int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
|
||||||
{
|
{
|
||||||
parserToken = &token;
|
parserToken = &token;
|
||||||
TPpToken ppTokenStorage;
|
TPpToken ppToken;
|
||||||
ppToken = &ppTokenStorage;
|
tokenText = pp->tokenize(&ppToken);
|
||||||
tokenText = PpTokenize(&ppToken->lexer);
|
|
||||||
|
|
||||||
loc.string = cpp->tokenLoc->file;
|
loc = ppToken.loc;
|
||||||
loc.line = cpp->tokenLoc->line;
|
|
||||||
parserToken->sType.lex.loc = loc;
|
parserToken->sType.lex.loc = loc;
|
||||||
switch (ppToken->lexer.ppToken) {
|
switch (ppToken.ppToken) {
|
||||||
case ';': afterType = false; return SEMICOLON;
|
case ';': afterType = false; return SEMICOLON;
|
||||||
case ',': afterType = false; return COMMA;
|
case ',': afterType = false; return COMMA;
|
||||||
case ':': return COLON;
|
case ':': return COLON;
|
||||||
@@ -545,10 +535,10 @@ int TScanContext::tokenize(TParserToken& token)
|
|||||||
case CPP_OR_ASSIGN: return OR_ASSIGN;
|
case CPP_OR_ASSIGN: return OR_ASSIGN;
|
||||||
case CPP_XOR_ASSIGN: return XOR_ASSIGN;
|
case CPP_XOR_ASSIGN: return XOR_ASSIGN;
|
||||||
|
|
||||||
case CPP_INTCONSTANT: parserToken->sType.lex.i = ppToken->lexer.sc_int; return INTCONSTANT;
|
case CPP_INTCONSTANT: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT;
|
||||||
case CPP_UINTCONSTANT: parserToken->sType.lex.i = ppToken->lexer.sc_int; return UINTCONSTANT;
|
case CPP_UINTCONSTANT: parserToken->sType.lex.i = ppToken.ival; return UINTCONSTANT;
|
||||||
case CPP_FLOATCONSTANT: parserToken->sType.lex.d = ppToken->lexer.sc_dval; return FLOATCONSTANT;
|
case CPP_FLOATCONSTANT: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT;
|
||||||
case CPP_DOUBLECONSTANT: parserToken->sType.lex.d = ppToken->lexer.sc_dval; return DOUBLECONSTANT;
|
case CPP_DOUBLECONSTANT: parserToken->sType.lex.d = ppToken.dval; return DOUBLECONSTANT;
|
||||||
case CPP_IDENTIFIER: return tokenizeIdentifier();
|
case CPP_IDENTIFIER: return tokenizeIdentifier();
|
||||||
|
|
||||||
case EOF: return 0;
|
case EOF: return 0;
|
||||||
@@ -896,7 +886,7 @@ int TScanContext::identifierOrType()
|
|||||||
|
|
||||||
int TScanContext::reservedWord()
|
int TScanContext::reservedWord()
|
||||||
{
|
{
|
||||||
ThreadLocalParseContext()->error(loc, "Reserved word.", tokenText, "", "");
|
parseContext.error(loc, "Reserved word.", tokenText, "", "");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,10 +40,12 @@
|
|||||||
|
|
||||||
#include "ParseHelper.h"
|
#include "ParseHelper.h"
|
||||||
|
|
||||||
|
class TPpContext;
|
||||||
|
class TPpToken;
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
class TParserToken;
|
class TParserToken;
|
||||||
class TPpToken;
|
|
||||||
|
|
||||||
class TScanContext {
|
class TScanContext {
|
||||||
public:
|
public:
|
||||||
@@ -51,7 +53,7 @@ public:
|
|||||||
virtual ~TScanContext() { }
|
virtual ~TScanContext() { }
|
||||||
|
|
||||||
static void fillInKeywordMap();
|
static void fillInKeywordMap();
|
||||||
int tokenize(TParserToken&);
|
int tokenize(TPpContext*, TParserToken&);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int tokenizeIdentifier();
|
int tokenizeIdentifier();
|
||||||
|
|||||||
@@ -49,9 +49,7 @@
|
|||||||
#include "../Include/ShHandle.h"
|
#include "../Include/ShHandle.h"
|
||||||
#include "InitializeDll.h"
|
#include "InitializeDll.h"
|
||||||
|
|
||||||
extern "C" {
|
#include "preprocessor/PpContext.h"
|
||||||
#include "preprocessor/preprocess.h"
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SH_EXPORTING
|
#define SH_EXPORTING
|
||||||
#include "../Public/ShaderLang.h"
|
#include "../Public/ShaderLang.h"
|
||||||
@@ -87,7 +85,6 @@ const int VersionCount = 12;
|
|||||||
// Each has a different set of built-ins, and we want to preserve that from
|
// Each has a different set of built-ins, and we want to preserve that from
|
||||||
// compile to compile.
|
// compile to compile.
|
||||||
//
|
//
|
||||||
// TODO: quality: thread safety: ensure the built-in symbol table levels are read only.
|
|
||||||
TSymbolTable* SharedSymbolTables[VersionCount][EProfileCount][EShLangCount] = {};
|
TSymbolTable* SharedSymbolTables[VersionCount][EProfileCount][EShLangCount] = {};
|
||||||
|
|
||||||
TPoolAllocator* PerProcessGPA = 0;
|
TPoolAllocator* PerProcessGPA = 0;
|
||||||
@@ -104,9 +101,10 @@ bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, int version, EProfil
|
|||||||
symbolTable = &symbolTables[language];
|
symbolTable = &symbolTables[language];
|
||||||
|
|
||||||
TParseContext parseContext(*symbolTable, intermediate, true, version, profile, language, infoSink);
|
TParseContext parseContext(*symbolTable, intermediate, true, version, profile, language, infoSink);
|
||||||
ThreadLocalParseContext() = &parseContext;
|
TPpContext ppContext(parseContext);
|
||||||
glslang::TScanContext scanContext(parseContext);
|
glslang::TScanContext scanContext(parseContext);
|
||||||
parseContext.scanContext = &scanContext;
|
parseContext.scanContext = &scanContext;
|
||||||
|
parseContext.ppContext = &ppContext;
|
||||||
|
|
||||||
assert(symbolTable->isEmpty() || symbolTable->atSharedBuiltInLevel());
|
assert(symbolTable->isEmpty() || symbolTable->atSharedBuiltInLevel());
|
||||||
|
|
||||||
@@ -121,14 +119,6 @@ bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, int version, EProfil
|
|||||||
|
|
||||||
symbolTable->push();
|
symbolTable->push();
|
||||||
|
|
||||||
|
|
||||||
//Initialize the Preprocessor
|
|
||||||
int ret = InitPreprocessor();
|
|
||||||
if (ret) {
|
|
||||||
infoSink.info.message(EPrefixInternalError, "Unable to intialize the Preprocessor");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (TBuiltInStrings::iterator i = BuiltInStrings[parseContext.language].begin();
|
for (TBuiltInStrings::iterator i = BuiltInStrings[parseContext.language].begin();
|
||||||
i != BuiltInStrings[parseContext.language].end(); ++i) {
|
i != BuiltInStrings[parseContext.language].end(); ++i) {
|
||||||
const char* builtInShaders[1];
|
const char* builtInShaders[1];
|
||||||
@@ -136,14 +126,13 @@ bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, int version, EProfil
|
|||||||
|
|
||||||
builtInShaders[0] = (*i).c_str();
|
builtInShaders[0] = (*i).c_str();
|
||||||
builtInLengths[0] = (int) (*i).size();
|
builtInLengths[0] = (int) (*i).size();
|
||||||
if (! parseContext.parseShaderStrings(const_cast<char**>(builtInShaders), builtInLengths, 1) != 0) {
|
if (! parseContext.parseShaderStrings(ppContext, const_cast<char**>(builtInShaders), builtInLengths, 1) != 0) {
|
||||||
infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
|
infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
|
||||||
printf("Unable to parse built-ins\n");
|
printf("Unable to parse built-ins\n");
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FinalizePreprocessor();
|
|
||||||
|
|
||||||
if (resources) {
|
if (resources) {
|
||||||
IdentifyBuiltIns(version, profile, parseContext.language, *symbolTable, *resources);
|
IdentifyBuiltIns(version, profile, parseContext.language, *symbolTable, *resources);
|
||||||
@@ -418,7 +407,9 @@ int ShCompile(
|
|||||||
|
|
||||||
TParseContext parseContext(symbolTable, intermediate, false, version, profile, compiler->getLanguage(), compiler->infoSink, forwardCompatible, messages);
|
TParseContext parseContext(symbolTable, intermediate, false, version, profile, compiler->getLanguage(), compiler->infoSink, forwardCompatible, messages);
|
||||||
glslang::TScanContext scanContext(parseContext);
|
glslang::TScanContext scanContext(parseContext);
|
||||||
|
TPpContext ppContext(parseContext);
|
||||||
parseContext.scanContext = &scanContext;
|
parseContext.scanContext = &scanContext;
|
||||||
|
parseContext.ppContext = &ppContext;
|
||||||
|
|
||||||
TSourceLoc beginning;
|
TSourceLoc beginning;
|
||||||
beginning.line = 1;
|
beginning.line = 1;
|
||||||
@@ -433,10 +424,6 @@ int ShCompile(
|
|||||||
else if (profile == EEsProfile && version >= 300 && versionNotFirst)
|
else if (profile == EEsProfile && version >= 300 && versionNotFirst)
|
||||||
parseContext.error(beginning, "statement must appear first in ESSL shader; before comments or newlines", "#version", "");
|
parseContext.error(beginning, "statement must appear first in ESSL shader; before comments or newlines", "#version", "");
|
||||||
|
|
||||||
ThreadLocalParseContext() = &parseContext;
|
|
||||||
|
|
||||||
InitPreprocessor();
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Parse the application's shaders. All the following symbol table
|
// Parse the application's shaders. All the following symbol table
|
||||||
// work will be throw-away, so push a new allocation scope that can
|
// work will be throw-away, so push a new allocation scope that can
|
||||||
@@ -451,7 +438,7 @@ int ShCompile(
|
|||||||
if (parseContext.insertBuiltInArrayAtGlobalLevel())
|
if (parseContext.insertBuiltInArrayAtGlobalLevel())
|
||||||
success = false;
|
success = false;
|
||||||
|
|
||||||
bool ret = parseContext.parseShaderStrings(const_cast<char**>(shaderStrings), lengths, numStrings);
|
bool ret = parseContext.parseShaderStrings(ppContext, const_cast<char**>(shaderStrings), lengths, numStrings);
|
||||||
if (! ret)
|
if (! ret)
|
||||||
success = false;
|
success = false;
|
||||||
intermediate.addSymbolLinkageNodes(parseContext.treeRoot, parseContext.linkage, parseContext.language, symbolTable);
|
intermediate.addSymbolLinkageNodes(parseContext.treeRoot, parseContext.linkage, parseContext.language, symbolTable);
|
||||||
@@ -490,7 +477,6 @@ int ShCompile(
|
|||||||
while (! symbolTable.atSharedBuiltInLevel())
|
while (! symbolTable.atSharedBuiltInLevel())
|
||||||
symbolTable.pop(0);
|
symbolTable.pop(0);
|
||||||
|
|
||||||
FinalizePreprocessor();
|
|
||||||
//
|
//
|
||||||
// Throw away all the temporary memory used by the compilation process.
|
// Throw away all the temporary memory used by the compilation process.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -59,20 +59,6 @@ Jutta Degener, 1995
|
|||||||
#include "ParseHelper.h"
|
#include "ParseHelper.h"
|
||||||
#include "../Public/ShaderLang.h"
|
#include "../Public/ShaderLang.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#define YYPARSE_PARAM parseContext
|
|
||||||
#define YYPARSE_PARAM_DECL TParseContext&
|
|
||||||
#define YY_DECL int yylex(YYSTYPE* pyylval, TParseContext& parseContext)
|
|
||||||
#define YYLEX_PARAM parseContext
|
|
||||||
#else
|
|
||||||
#define YYPARSE_PARAM parseContextLocal
|
|
||||||
#define parseContext (*((TParseContext*)(parseContextLocal)))
|
|
||||||
#define YY_DECL int yylex(YYSTYPE* pyylval, void* parseContextLocal)
|
|
||||||
#define YYLEX_PARAM (void*)(parseContextLocal)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern void yyerror(const char*);
|
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
@@ -109,13 +95,18 @@ extern void yyerror(const char*);
|
|||||||
}
|
}
|
||||||
|
|
||||||
%{
|
%{
|
||||||
#ifndef _WIN32
|
|
||||||
extern int yylex(YYSTYPE*, void*);
|
#define YYPARSE_PARAM voidParseContext
|
||||||
#endif
|
#define parseContext (*(TParseContext*)voidParseContext)
|
||||||
|
#define YYLEX_PARAM parseContext
|
||||||
|
#define yyerror(msg) parseContext.parserError(msg)
|
||||||
|
|
||||||
|
extern int yylex(YYSTYPE*, TParseContext&);
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%pure_parser /* Just in case is called from multiple threads */
|
%pure_parser // enable thread safety
|
||||||
%expect 1 /* One shift reduce conflict because of if | else */
|
%expect 1 // One shift reduce conflict because of if | else
|
||||||
|
|
||||||
%token <lex> ATTRIBUTE VARYING
|
%token <lex> ATTRIBUTE VARYING
|
||||||
%token <lex> CONST BOOL FLOAT DOUBLE INT UINT
|
%token <lex> CONST BOOL FLOAT DOUBLE INT UINT
|
||||||
|
|||||||
@@ -3,9 +3,10 @@ CC = gcc
|
|||||||
|
|
||||||
CPPFLAGS=$(DEFINE) $(INCLUDE) -fPIC
|
CPPFLAGS=$(DEFINE) $(INCLUDE) -fPIC
|
||||||
|
|
||||||
OBJECTS = atom.o cpp.o cppstruct.o memory.o scanner.o symbols.o tokens.o
|
OBJECTS = PpAtom.o PpScanner.o PpTokens.o Pp.o PpContext.o PpMemory.o PpSymbols.o
|
||||||
AR=ar
|
AR=ar
|
||||||
SRCS=scanner.c atom.c memory.c tokens. cpp.c cppstruct.c symbols.c
|
SRCS = PpAtom.cpp PpScanner.cpp PpTokens.cpp Pp.cpp PpContext.cpp PpMemory.cpp PpSymbols.cpp
|
||||||
|
|
||||||
|
|
||||||
default: all
|
default: all
|
||||||
all : libPreprocessor.a
|
all : libPreprocessor.a
|
||||||
@@ -28,14 +29,10 @@ depend:
|
|||||||
|
|
||||||
# DO NOT DELETE
|
# DO NOT DELETE
|
||||||
|
|
||||||
scanner.o: slglobals.h memory.h atom.h scanner.h parser.h cpp.h tokens.h
|
PpAtom.o: PpContext.h PpToken.h
|
||||||
scanner.o: symbols.h compile.h
|
PpScanner.o: PpContext.h PpToken.h
|
||||||
atom.o: slglobals.h memory.h atom.h scanner.h parser.h cpp.h tokens.h
|
PpTokens.o: PpContext.h PpToken.h
|
||||||
atom.o: symbols.h compile.h
|
Pp.o: PpContext.h PpToken.h
|
||||||
memory.o: memory.h
|
PpContext.o: PpContext.h PpToken.h
|
||||||
cpp.o: slglobals.h memory.h atom.h scanner.h parser.h cpp.h tokens.h
|
PpMemory.o: PpContext.h PpToken.h
|
||||||
cpp.o: symbols.h compile.h
|
PpSymbols.o: PpContext.h PpToken.h
|
||||||
cppstruct.o: slglobals.h memory.h atom.h scanner.h parser.h cpp.h tokens.h
|
|
||||||
cppstruct.o: symbols.h compile.h
|
|
||||||
symbols.o: slglobals.h memory.h atom.h scanner.h parser.h cpp.h tokens.h
|
|
||||||
symbols.o: symbols.h compile.h
|
|
||||||
|
|||||||
1076
glslang/MachineIndependent/preprocessor/Pp.cpp
Normal file
1076
glslang/MachineIndependent/preprocessor/Pp.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
|||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
|
//Copyright (C) 2013 LunarG, Inc.
|
||||||
//All rights reserved.
|
//All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
//Redistribution and use in source and binary forms, with or without
|
||||||
@@ -86,7 +87,8 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "slglobals.h"
|
#include "PpContext.h"
|
||||||
|
#include "PpTokens.h"
|
||||||
|
|
||||||
#undef malloc
|
#undef malloc
|
||||||
#undef realloc
|
#undef realloc
|
||||||
@@ -129,18 +131,12 @@ static const struct {
|
|||||||
|
|
||||||
#define INIT_STRING_TABLE_SIZE 16384
|
#define INIT_STRING_TABLE_SIZE 16384
|
||||||
|
|
||||||
typedef struct StringTable_Rec {
|
|
||||||
char *strings;
|
|
||||||
int nextFree;
|
|
||||||
int size;
|
|
||||||
} StringTable;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* InitStringTable() - Initialize the string table.
|
* InitStringTable() - Initialize the string table.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int InitStringTable(StringTable *stable)
|
int InitStringTable(TPpContext::StringTable *stable)
|
||||||
{
|
{
|
||||||
stable->strings = (char *) malloc(INIT_STRING_TABLE_SIZE);
|
stable->strings = (char *) malloc(INIT_STRING_TABLE_SIZE);
|
||||||
if (!stable->strings)
|
if (!stable->strings)
|
||||||
@@ -152,11 +148,11 @@ static int InitStringTable(StringTable *stable)
|
|||||||
} // InitStringTable
|
} // InitStringTable
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FreeStringTable() - Free the string table.
|
* FreeStringTable() - Free the string table.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void FreeStringTable(StringTable *stable)
|
void FreeStringTable(TPpContext::StringTable *stable)
|
||||||
{
|
{
|
||||||
if (stable->strings)
|
if (stable->strings)
|
||||||
free(stable->strings);
|
free(stable->strings);
|
||||||
@@ -166,9 +162,9 @@ static void FreeStringTable(StringTable *stable)
|
|||||||
} // FreeStringTable
|
} // FreeStringTable
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* HashString() - Hash a string with the base hash function.
|
* HashString() - Hash a string with the base hash function.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int HashString(const char *s)
|
static int HashString(const char *s)
|
||||||
{
|
{
|
||||||
@@ -182,9 +178,9 @@ static int HashString(const char *s)
|
|||||||
} // HashString
|
} // HashString
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* HashString2() - Hash a string with the incrimenting hash function.
|
* HashString2() - Hash a string with the incrimenting hash function.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int HashString2(const char *s)
|
static int HashString2(const char *s)
|
||||||
{
|
{
|
||||||
@@ -198,11 +194,11 @@ static int HashString2(const char *s)
|
|||||||
} // HashString2
|
} // HashString2
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AddString() - Add a string to a string table. Return it's offset.
|
* AddString() - Add a string to a string table. Return it's offset.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int AddString(StringTable *stable, const char *s)
|
static int AddString(TPpContext::StringTable *stable, const char *s)
|
||||||
{
|
{
|
||||||
int len, loc;
|
int len, loc;
|
||||||
char *str;
|
char *str;
|
||||||
@@ -226,31 +222,18 @@ static int AddString(StringTable *stable, const char *s)
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#define INIT_HASH_TABLE_SIZE 2047
|
#define INIT_HASH_TABLE_SIZE 2047
|
||||||
#define HASH_TABLE_MAX_COLLISIONS 3
|
|
||||||
|
|
||||||
typedef struct HashEntry_Rec {
|
|
||||||
int index; // String table offset of string representation
|
|
||||||
int value; // Atom (symbol) value
|
|
||||||
} HashEntry;
|
|
||||||
|
|
||||||
typedef struct HashTable_Rec {
|
|
||||||
HashEntry *entry;
|
|
||||||
int size;
|
|
||||||
int entries;
|
|
||||||
int counts[HASH_TABLE_MAX_COLLISIONS + 1];
|
|
||||||
} HashTable;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* InitHashTable() - Initialize the hash table.
|
* InitHashTable() - Initialize the hash table.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int InitHashTable(HashTable *htable, int fsize)
|
static int InitHashTable(TPpContext::HashTable *htable, int fsize)
|
||||||
{
|
{
|
||||||
int ii;
|
int ii;
|
||||||
|
|
||||||
htable->entry = (HashEntry *) malloc(sizeof(HashEntry)*fsize);
|
htable->entry = (TPpContext::HashEntry *) malloc(sizeof(TPpContext::HashEntry)*fsize);
|
||||||
if (!htable->entry)
|
if (! htable->entry)
|
||||||
return 0;
|
return 0;
|
||||||
htable->size = fsize;
|
htable->size = fsize;
|
||||||
for (ii = 0; ii < fsize; ii++) {
|
for (ii = 0; ii < fsize; ii++) {
|
||||||
@@ -258,17 +241,17 @@ static int InitHashTable(HashTable *htable, int fsize)
|
|||||||
htable->entry[ii].value = 0;
|
htable->entry[ii].value = 0;
|
||||||
}
|
}
|
||||||
htable->entries = 0;
|
htable->entries = 0;
|
||||||
for (ii = 0; ii <= HASH_TABLE_MAX_COLLISIONS; ii++)
|
for (ii = 0; ii <= TPpContext::hashTableMaxCollisions; ii++)
|
||||||
htable->counts[ii] = 0;
|
htable->counts[ii] = 0;
|
||||||
return 1;
|
return 1;
|
||||||
} // InitHashTable
|
} // InitHashTable
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FreeHashTable() - Free the hash table.
|
* FreeHashTable() - Free the hash table.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void FreeHashTable(HashTable *htable)
|
static void FreeHashTable(TPpContext::HashTable *htable)
|
||||||
{
|
{
|
||||||
if (htable->entry)
|
if (htable->entry)
|
||||||
free(htable->entry);
|
free(htable->entry);
|
||||||
@@ -278,11 +261,11 @@ static void FreeHashTable(HashTable *htable)
|
|||||||
} // FreeHashTable
|
} // FreeHashTable
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Empty() - See if a hash table entry is empty.
|
* Empty() - See if a hash table entry is empty.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int Empty(HashTable *htable, int hashloc)
|
static int Empty(TPpContext::HashTable *htable, int hashloc)
|
||||||
{
|
{
|
||||||
assert(hashloc >= 0 && hashloc < htable->size);
|
assert(hashloc >= 0 && hashloc < htable->size);
|
||||||
if (htable->entry[hashloc].index == 0) {
|
if (htable->entry[hashloc].index == 0) {
|
||||||
@@ -293,11 +276,11 @@ static int Empty(HashTable *htable, int hashloc)
|
|||||||
} // Empty
|
} // Empty
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Match() - See if a hash table entry is matches a string.
|
* Match() - See if a hash table entry is matches a string.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int Match(HashTable *htable, StringTable *stable, const char *s, int hashloc)
|
static int Match(TPpContext::HashTable *htable, TPpContext::StringTable *stable, const char *s, int hashloc)
|
||||||
{
|
{
|
||||||
int strloc;
|
int strloc;
|
||||||
|
|
||||||
@@ -315,34 +298,12 @@ static int Match(HashTable *htable, StringTable *stable, const char *s, int hash
|
|||||||
|
|
||||||
#define INIT_ATOM_TABLE_SIZE 1024
|
#define INIT_ATOM_TABLE_SIZE 1024
|
||||||
|
|
||||||
|
|
||||||
struct AtomTable_Rec {
|
|
||||||
StringTable stable; // String table.
|
|
||||||
HashTable htable; // Hashes string to atom number and token value. Multiple strings can
|
|
||||||
// have the same token value but each unique string is a unique atom.
|
|
||||||
int *amap; // Maps atom value to offset in string table. Atoms all map to unique
|
|
||||||
// strings except for some undefined values in the lower, fixed part
|
|
||||||
// of the atom table that map to "<undefined>". The lowest 256 atoms
|
|
||||||
// correspond to single character ASCII values except for alphanumeric
|
|
||||||
// characters and '_', which can be other tokens. Next come the
|
|
||||||
// language tokens with their atom values equal to the token value.
|
|
||||||
// Then come predefined atoms, followed by user specified identifiers.
|
|
||||||
int *arev; // Reversed atom for symbol table use.
|
|
||||||
int nextFree;
|
|
||||||
int size;
|
|
||||||
};
|
|
||||||
|
|
||||||
static AtomTable latable = { { 0 } };
|
|
||||||
AtomTable *atable = &latable;
|
|
||||||
|
|
||||||
static int AddAtomFixed(AtomTable *atable, const char *s, int atom);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GrowAtomTable() - Grow the atom table to at least "size" if it's smaller.
|
* GrowAtomTable() - Grow the atom table to at least "size" if it's smaller.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int GrowAtomTable(AtomTable *atable, int size)
|
int GrowAtomTable(TPpContext::AtomTable *atable, int size)
|
||||||
{
|
{
|
||||||
int *newmap, *newrev;
|
int *newmap, *newrev;
|
||||||
|
|
||||||
@@ -373,9 +334,9 @@ static int GrowAtomTable(AtomTable *atable, int size)
|
|||||||
} // GrowAtomTable
|
} // GrowAtomTable
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* lReverse() - Reverse the bottom 20 bits of a 32 bit int.
|
* lReverse() - Reverse the bottom 20 bits of a 32 bit int.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int lReverse(int fval)
|
static int lReverse(int fval)
|
||||||
{
|
{
|
||||||
@@ -398,11 +359,11 @@ static int lReverse(int fval)
|
|||||||
} // lReverse
|
} // lReverse
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AllocateAtom() - Allocate a new atom. Associated with the "undefined" value of -1.
|
* AllocateAtom() - Allocate a new atom. Associated with the "undefined" value of -1.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int AllocateAtom(AtomTable *atable)
|
int AllocateAtom(TPpContext::AtomTable *atable)
|
||||||
{
|
{
|
||||||
if (atable->nextFree >= atable->size)
|
if (atable->nextFree >= atable->size)
|
||||||
GrowAtomTable(atable, atable->nextFree*2);
|
GrowAtomTable(atable, atable->nextFree*2);
|
||||||
@@ -413,26 +374,26 @@ static int AllocateAtom(AtomTable *atable)
|
|||||||
} // AllocateAtom
|
} // AllocateAtom
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SetAtomValue() - Allocate a new atom associated with "hashindex".
|
* SetAtomValue() - Allocate a new atom associated with "hashindex".
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void SetAtomValue(AtomTable *atable, int atomnumber, int hashindex)
|
void SetAtomValue(TPpContext::AtomTable *atable, int atomnumber, int hashindex)
|
||||||
{
|
{
|
||||||
atable->amap[atomnumber] = atable->htable.entry[hashindex].index;
|
atable->amap[atomnumber] = atable->htable.entry[hashindex].index;
|
||||||
atable->htable.entry[hashindex].value = atomnumber;
|
atable->htable.entry[hashindex].value = atomnumber;
|
||||||
} // SetAtomValue
|
} // SetAtomValue
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FindHashLoc() - Find the hash location for this string. Return -1 it hash table is full.
|
* FindHashLoc() - Find the hash location for this string. Return -1 it hash table is full.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int FindHashLoc(AtomTable *atable, const char *s)
|
int FindHashLoc(TPpContext::AtomTable *atable, const char *s)
|
||||||
{
|
{
|
||||||
int hashloc, hashdelta, count;
|
int hashloc, hashdelta, count;
|
||||||
int FoundEmptySlot = 0;
|
int FoundEmptySlot = 0;
|
||||||
int collision[HASH_TABLE_MAX_COLLISIONS + 1];
|
int collision[TPpContext::hashTableMaxCollisions + 1];
|
||||||
|
|
||||||
hashloc = HashString(s) % atable->htable.size;
|
hashloc = HashString(s) % atable->htable.size;
|
||||||
if (!Empty(&atable->htable, hashloc)) {
|
if (!Empty(&atable->htable, hashloc)) {
|
||||||
@@ -441,7 +402,7 @@ static int FindHashLoc(AtomTable *atable, const char *s)
|
|||||||
collision[0] = hashloc;
|
collision[0] = hashloc;
|
||||||
hashdelta = HashString2(s);
|
hashdelta = HashString2(s);
|
||||||
count = 0;
|
count = 0;
|
||||||
while (count < HASH_TABLE_MAX_COLLISIONS) {
|
while (count < TPpContext::hashTableMaxCollisions) {
|
||||||
hashloc = ((hashloc + hashdelta) & 0x7fffffff) % atable->htable.size;
|
hashloc = ((hashloc + hashdelta) & 0x7fffffff) % atable->htable.size;
|
||||||
if (!Empty(&atable->htable, hashloc)) {
|
if (!Empty(&atable->htable, hashloc)) {
|
||||||
if (Match(&atable->htable, &atable->stable, s, hashloc)) {
|
if (Match(&atable->htable, &atable->stable, s, hashloc)) {
|
||||||
@@ -455,22 +416,20 @@ static int FindHashLoc(AtomTable *atable, const char *s)
|
|||||||
collision[count] = hashloc;
|
collision[count] = hashloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FoundEmptySlot) {
|
if (! FoundEmptySlot) {
|
||||||
if (cpp->options.DumpAtomTable) {
|
#ifdef DUMP_TABLE
|
||||||
|
{
|
||||||
int ii;
|
int ii;
|
||||||
char str[200];
|
char str[200];
|
||||||
sprintf(str, "*** Hash failed with more than %d collisions. Must increase hash table size. ***",
|
printf(str, "*** Hash failed with more than %d collisions. Must increase hash table size. ***",
|
||||||
HASH_TABLE_MAX_COLLISIONS);
|
hashTableMaxCollisions);
|
||||||
ShPpErrorToInfoLog(str);
|
printf(str, "*** New string \"%s\", hash=%04x, delta=%04x", s, collision[0], hashdelta);
|
||||||
|
for (ii = 0; ii <= hashTableMaxCollisions; ii++) {
|
||||||
sprintf(str, "*** New string \"%s\", hash=%04x, delta=%04x", s, collision[0], hashdelta);
|
printf(str, "*** Collides on try %d at hash entry %04x with \"%s\"",
|
||||||
ShPpErrorToInfoLog(str);
|
|
||||||
for (ii = 0; ii <= HASH_TABLE_MAX_COLLISIONS; ii++) {
|
|
||||||
sprintf(str, "*** Collides on try %d at hash entry %04x with \"%s\"",
|
|
||||||
ii + 1, collision[ii], GetAtomString(atable, atable->htable.entry[collision[ii]].value));
|
ii + 1, collision[ii], GetAtomString(atable, atable->htable.entry[collision[ii]].value));
|
||||||
ShPpErrorToInfoLog(str);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
atable->htable.counts[count]++;
|
atable->htable.counts[count]++;
|
||||||
@@ -480,11 +439,11 @@ static int FindHashLoc(AtomTable *atable, const char *s)
|
|||||||
} // FindHashLoc
|
} // FindHashLoc
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IncreaseHashTableSize()
|
* IncreaseHashTableSize()
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int IncreaseHashTableSize(AtomTable *atable)
|
int TPpContext::IncreaseHashTableSize(AtomTable *atable)
|
||||||
{
|
{
|
||||||
int ii, strloc, oldhashloc, value, size;
|
int ii, strloc, oldhashloc, value, size;
|
||||||
AtomTable oldtable;
|
AtomTable oldtable;
|
||||||
@@ -494,7 +453,7 @@ static int IncreaseHashTableSize(AtomTable *atable)
|
|||||||
|
|
||||||
oldtable = *atable;
|
oldtable = *atable;
|
||||||
size = oldtable.htable.size*2 + 1;
|
size = oldtable.htable.size*2 + 1;
|
||||||
if (!InitAtomTable(atable, size))
|
if (! InitAtomTable(atable, size))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Add all the existing values to the new atom table preserving their atom values:
|
// Add all the existing values to the new atom table preserving their atom values:
|
||||||
@@ -508,15 +467,16 @@ static int IncreaseHashTableSize(AtomTable *atable)
|
|||||||
AddAtomFixed(atable, s, value);
|
AddAtomFixed(atable, s, value);
|
||||||
}
|
}
|
||||||
FreeAtomTable(&oldtable);
|
FreeAtomTable(&oldtable);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
} // IncreaseHashTableSize
|
} // IncreaseHashTableSize
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LookUpAddStringHash() - Lookup a string in the hash table. If it's not there, add it and
|
* LookUpAddStringHash() - Lookup a string in the hash table. If it's not there, add it and
|
||||||
* initialize the atom value in the hash table to 0. Return the hash table index.
|
* initialize the atom value in the hash table to 0. Return the hash table index.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int LookUpAddStringHash(AtomTable *atable, const char *s)
|
int TPpContext::LookUpAddStringHash(AtomTable *atable, const char *s)
|
||||||
{
|
{
|
||||||
int hashloc, strloc;
|
int hashloc, strloc;
|
||||||
|
|
||||||
@@ -537,12 +497,12 @@ static int LookUpAddStringHash(AtomTable *atable, const char *s)
|
|||||||
} // LookUpAddStringHash
|
} // LookUpAddStringHash
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LookUpAddString() - Lookup a string in the hash table. If it's not there, add it and
|
* LookUpAddString() - Lookup a string in the hash table. If it's not there, add it and
|
||||||
* initialize the atom value in the hash table to the next atom number.
|
* initialize the atom value in the hash table to the next atom number.
|
||||||
* Return the atom value of string.
|
* Return the atom value of string.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int LookUpAddString(AtomTable *atable, const char *s)
|
int TPpContext::LookUpAddString(AtomTable *atable, const char *s)
|
||||||
{
|
{
|
||||||
int hashindex, atom;
|
int hashindex, atom;
|
||||||
|
|
||||||
@@ -556,11 +516,11 @@ int LookUpAddString(AtomTable *atable, const char *s)
|
|||||||
} // LookUpAddString
|
} // LookUpAddString
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GetAtomString()
|
* GetAtomString()
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const char *GetAtomString(AtomTable *atable, int atom)
|
const char *TPpContext::GetAtomString(AtomTable *atable, int atom)
|
||||||
{
|
{
|
||||||
int soffset;
|
int soffset;
|
||||||
|
|
||||||
@@ -585,38 +545,35 @@ const char *GetAtomString(AtomTable *atable, int atom)
|
|||||||
} // GetAtomString
|
} // GetAtomString
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GetReversedAtom()
|
* GetReversedAtom()
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int GetReversedAtom(AtomTable *atable, int atom)
|
int TPpContext::GetReversedAtom(TPpContext::AtomTable *atable, int atom)
|
||||||
{
|
{
|
||||||
if (atom > 0 && atom < atable->nextFree) {
|
if (atom > 0 && atom < atable->nextFree)
|
||||||
return atable->arev[atom];
|
return atable->arev[atom];
|
||||||
} else {
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
} // GetReversedAtom
|
} // GetReversedAtom
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AddAtom() - Add a string to the atom, hash and string tables if it isn't already there.
|
* AddAtom() - Add a string to the atom, hash and string tables if it isn't already there.
|
||||||
* Return it's atom index.
|
* Return it's atom index.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int AddAtom(AtomTable *atable, const char *s)
|
int TPpContext::AddAtom(TPpContext::AtomTable *atable, const char *s)
|
||||||
{
|
{
|
||||||
int atom;
|
int atom = LookUpAddString(atable, s);
|
||||||
|
|
||||||
atom = LookUpAddString(atable, s);
|
|
||||||
return atom;
|
return atom;
|
||||||
} // AddAtom
|
} // AddAtom
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AddAtomFixed() - Add an atom to the hash and string tables if it isn't already there.
|
* AddAtomFixed() - Add an atom to the hash and string tables if it isn't already there.
|
||||||
* Assign it the atom value of "atom".
|
* Assign it the atom value of "atom".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int AddAtomFixed(AtomTable *atable, const char *s, int atom)
|
int TPpContext::AddAtomFixed(AtomTable *atable, const char *s, int atom)
|
||||||
{
|
{
|
||||||
int hashindex, lsize;
|
int hashindex, lsize;
|
||||||
|
|
||||||
@@ -639,23 +596,24 @@ static int AddAtomFixed(AtomTable *atable, const char *s, int atom)
|
|||||||
} // AddAtomFixed
|
} // AddAtomFixed
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* InitAtomTable() - Initialize the atom table.
|
* InitAtomTable() - Initialize the atom table.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int InitAtomTable(AtomTable *atable, int htsize)
|
int TPpContext::InitAtomTable(AtomTable *atable, int htsize)
|
||||||
{
|
{
|
||||||
int ii;
|
int ii;
|
||||||
|
|
||||||
htsize = htsize <= 0 ? INIT_HASH_TABLE_SIZE : htsize;
|
htsize = htsize <= 0 ? INIT_HASH_TABLE_SIZE : htsize;
|
||||||
if (!InitStringTable(&atable->stable))
|
if (! InitStringTable(&atable->stable))
|
||||||
return 0;
|
return 0;
|
||||||
if (!InitHashTable(&atable->htable, htsize))
|
if (! InitHashTable(&atable->htable, htsize))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
atable->nextFree = 0;
|
atable->nextFree = 0;
|
||||||
atable->amap = NULL;
|
atable->amap = NULL;
|
||||||
atable->size = 0;
|
atable->size = 0;
|
||||||
|
atable->arev = 0;
|
||||||
GrowAtomTable(atable, INIT_ATOM_TABLE_SIZE);
|
GrowAtomTable(atable, INIT_ATOM_TABLE_SIZE);
|
||||||
if (!atable->amap)
|
if (!atable->amap)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -685,11 +643,6 @@ int InitAtomTable(AtomTable *atable, int htsize)
|
|||||||
for (ii = 0; ii < sizeof(tokens)/sizeof(tokens[0]); ii++)
|
for (ii = 0; ii < sizeof(tokens)/sizeof(tokens[0]); ii++)
|
||||||
AddAtomFixed(atable, tokens[ii].str, tokens[ii].val);
|
AddAtomFixed(atable, tokens[ii].str, tokens[ii].val);
|
||||||
|
|
||||||
// Add error symbol if running in error mode:
|
|
||||||
|
|
||||||
if (cpp->options.ErrorMode)
|
|
||||||
AddAtomFixed(atable, "error", CPP_ERROR_SY);
|
|
||||||
|
|
||||||
AddAtom(atable, "<*** end fixed atoms ***>");
|
AddAtom(atable, "<*** end fixed atoms ***>");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -700,36 +653,33 @@ int InitAtomTable(AtomTable *atable, int htsize)
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PrintAtomTable()
|
* PrintAtomTable()
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void PrintAtomTable(AtomTable *atable)
|
void TPpContext::PrintAtomTable(AtomTable *atable)
|
||||||
{
|
{
|
||||||
int ii;
|
int ii;
|
||||||
char str[200];
|
char str[200];
|
||||||
|
|
||||||
for (ii = 0; ii < atable->nextFree; ii++) {
|
for (ii = 0; ii < atable->nextFree; ii++) {
|
||||||
sprintf(str, "%d: \"%s\"", ii, &atable->stable.strings[atable->amap[ii]]);
|
printf(str, "%d: \"%s\"", ii, &atable->stable.strings[atable->amap[ii]]);
|
||||||
ShPpDebugLogMsg(str);
|
|
||||||
}
|
}
|
||||||
sprintf(str, "Hash table: size=%d, entries=%d, collisions=",
|
printf(str, "Hash table: size=%d, entries=%d, collisions=",
|
||||||
atable->htable.size, atable->htable.entries);
|
atable->htable.size, atable->htable.entries);
|
||||||
ShPpDebugLogMsg(str);
|
for (ii = 0; ii < hashTableMaxCollisions; ii++) {
|
||||||
for (ii = 0; ii < HASH_TABLE_MAX_COLLISIONS; ii++) {
|
printf(str, " %d", atable->htable.counts[ii]);
|
||||||
sprintf(str, " %d", atable->htable.counts[ii]);
|
|
||||||
ShPpDebugLogMsg(str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // PrintAtomTable
|
} // PrintAtomTable
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GetStringOfAtom()
|
* GetStringOfAtom()
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
char* GetStringOfAtom(AtomTable *atable, int atom)
|
char* TPpContext::GetStringOfAtom(AtomTable *atable, int atom)
|
||||||
{
|
{
|
||||||
char* chr_str;
|
char* chr_str;
|
||||||
chr_str=&atable->stable.strings[atable->amap[atom]];
|
chr_str=&atable->stable.strings[atable->amap[atom]];
|
||||||
@@ -737,11 +687,11 @@ char* GetStringOfAtom(AtomTable *atable, int atom)
|
|||||||
} // GetStringOfAtom
|
} // GetStringOfAtom
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FreeAtomTable() - Free the atom table and associated memory
|
* FreeAtomTable() - Free the atom table and associated memory
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void FreeAtomTable(AtomTable *atable)
|
void TPpContext::FreeAtomTable(AtomTable *atable)
|
||||||
{
|
{
|
||||||
FreeStringTable(&atable->stable);
|
FreeStringTable(&atable->stable);
|
||||||
FreeHashTable(&atable->htable);
|
FreeHashTable(&atable->htable);
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
|
//Copyright (C) 2013 LunarG, Inc.
|
||||||
//All rights reserved.
|
//All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
//Redistribution and use in source and binary forms, with or without
|
||||||
@@ -74,36 +75,52 @@ NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
|
|||||||
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
|
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
|
||||||
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
\****************************************************************************/
|
\****************************************************************************/
|
||||||
//
|
|
||||||
// scanner.h
|
|
||||||
//
|
|
||||||
|
|
||||||
#if !defined(__SCANNER_H)
|
#include <stdio.h>
|
||||||
#define __SCANNER_H 1
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "preprocess.h"
|
#include "PpContext.h"
|
||||||
#include "parser.h"
|
|
||||||
|
|
||||||
// Not really atom table stuff but needed first...
|
TPpContext::TPpContext(TParseContext& pc) :
|
||||||
#ifdef __cplusplus
|
parseContext(pc), preamble(0), strings(0), notAVersionToken(false),
|
||||||
extern "C" {
|
ScopeList(0), CurrentScope(0), GlobalScope(0)
|
||||||
#endif
|
{
|
||||||
|
InitAtomTable(&atomTable, 0);
|
||||||
|
InitScanner(this);
|
||||||
|
|
||||||
int yyparse (void);
|
ifdepth = 0;
|
||||||
|
for (elsetracker = 0; elsetracker < maxIfNesting; elsetracker++)
|
||||||
int InitScanner(CPPStruct *cpp); // Intialise the cpp scanner.
|
elsedepth[elsetracker] = 0;
|
||||||
int ScanFromString(char *); // Start scanning the input from the string mentioned.
|
elsetracker = 0;
|
||||||
int check_EOF(int); // check if we hit a EOF abruptly
|
|
||||||
void ShPpErrorToInfoLog(const char *); // sticking the msg,line into the Shader's.Info.log
|
|
||||||
void SetLineNumber(int);
|
|
||||||
void SetStringNumber(int);
|
|
||||||
void IncLineNumber(void);
|
|
||||||
void DecLineNumber(void);
|
|
||||||
int FreeScanner(void); // Free the cpp scanner
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // !(defined(__SCANNER_H)
|
TPpContext::~TPpContext()
|
||||||
|
{
|
||||||
|
delete [] preamble;
|
||||||
|
FreeAtomTable(&atomTable);
|
||||||
|
FreeScanner();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TPpContext::setPreamble(const char* p, int l)
|
||||||
|
{
|
||||||
|
if (p && l > 0) {
|
||||||
|
// preAmble could be a hard-coded string; make writable copy
|
||||||
|
// TODO: efficiency PP: make it not need writable strings
|
||||||
|
preambleLength = l;
|
||||||
|
preamble = new char[preambleLength + 1];
|
||||||
|
memcpy(preamble, p, preambleLength + 1); // TODO: PP: assuming nul-terminated strings
|
||||||
|
ScanFromString(preamble);
|
||||||
|
currentString = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TPpContext::setShaderStrings(char* s[], int l[], int n)
|
||||||
|
{
|
||||||
|
strings = s;
|
||||||
|
lengths = l;
|
||||||
|
numStrings = n;
|
||||||
|
if (! preamble) {
|
||||||
|
ScanFromString(strings[0]);
|
||||||
|
currentString = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
389
glslang/MachineIndependent/preprocessor/PpContext.h
Normal file
389
glslang/MachineIndependent/preprocessor/PpContext.h
Normal file
@@ -0,0 +1,389 @@
|
|||||||
|
//
|
||||||
|
//Copyright (C) 2013 LunarG, Inc.
|
||||||
|
//All rights reserved.
|
||||||
|
//
|
||||||
|
//Redistribution and use in source and binary forms, with or without
|
||||||
|
//modification, are permitted provided that the following conditions
|
||||||
|
//are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
//POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
/****************************************************************************\
|
||||||
|
Copyright (c) 2002, NVIDIA Corporation.
|
||||||
|
|
||||||
|
NVIDIA Corporation("NVIDIA") supplies this software to you in
|
||||||
|
consideration of your agreement to the following terms, and your use,
|
||||||
|
installation, modification or redistribution of this NVIDIA software
|
||||||
|
constitutes acceptance of these terms. If you do not agree with these
|
||||||
|
terms, please do not use, install, modify or redistribute this NVIDIA
|
||||||
|
software.
|
||||||
|
|
||||||
|
In consideration of your agreement to abide by the following terms, and
|
||||||
|
subject to these terms, NVIDIA grants you a personal, non-exclusive
|
||||||
|
license, under NVIDIA's copyrights in this original NVIDIA software (the
|
||||||
|
"NVIDIA Software"), to use, reproduce, modify and redistribute the
|
||||||
|
NVIDIA Software, with or without modifications, in source and/or binary
|
||||||
|
forms; provided that if you redistribute the NVIDIA Software, you must
|
||||||
|
retain the copyright notice of NVIDIA, this notice and the following
|
||||||
|
text and disclaimers in all such redistributions of the NVIDIA Software.
|
||||||
|
Neither the name, trademarks, service marks nor logos of NVIDIA
|
||||||
|
Corporation may be used to endorse or promote products derived from the
|
||||||
|
NVIDIA Software without specific prior written permission from NVIDIA.
|
||||||
|
Except as expressly stated in this notice, no other rights or licenses
|
||||||
|
express or implied, are granted by NVIDIA herein, including but not
|
||||||
|
limited to any patent rights that may be infringed by your derivative
|
||||||
|
works or by other works in which the NVIDIA Software may be
|
||||||
|
incorporated. No hardware is licensed hereunder.
|
||||||
|
|
||||||
|
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
||||||
|
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||||
|
INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
|
||||||
|
NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
|
||||||
|
ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
|
||||||
|
PRODUCTS.
|
||||||
|
|
||||||
|
IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
|
||||||
|
INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||||
|
TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
|
||||||
|
OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
|
||||||
|
NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
|
||||||
|
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
|
||||||
|
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
\****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef PPCONTEXT_H
|
||||||
|
#define PPCONTEXT_H
|
||||||
|
|
||||||
|
#include "../ParseHelper.h"
|
||||||
|
|
||||||
|
class TPpToken {
|
||||||
|
public:
|
||||||
|
static const int maxTokenLength = 1024;
|
||||||
|
|
||||||
|
TSourceLoc loc;
|
||||||
|
int ppToken;
|
||||||
|
int ival;
|
||||||
|
double dval;
|
||||||
|
int atom;
|
||||||
|
char name[maxTokenLength+1];
|
||||||
|
};
|
||||||
|
|
||||||
|
// This class is the result of turning a huge pile of C code communicating through globals
|
||||||
|
// into a class. This was done to allowing instancing to attain thread safety.
|
||||||
|
// Don't expect too much in terms of OO design.
|
||||||
|
class TPpContext {
|
||||||
|
public:
|
||||||
|
TPpContext(TParseContext&);
|
||||||
|
virtual ~TPpContext();
|
||||||
|
|
||||||
|
void setPreamble(const char* preamble, int length);
|
||||||
|
void setShaderStrings(char* strings[], int lengths[], int numStrings);
|
||||||
|
|
||||||
|
const char* tokenize(TPpToken* yylvalpp);
|
||||||
|
|
||||||
|
struct InputSrc {
|
||||||
|
struct InputSrc *prev;
|
||||||
|
int (*scan)(TPpContext*, struct InputSrc *, TPpToken *);
|
||||||
|
int (*getch)(TPpContext*, struct InputSrc *, TPpToken *);
|
||||||
|
void (*ungetch)(TPpContext*, struct InputSrc *, int, TPpToken *);
|
||||||
|
int name; /* atom */
|
||||||
|
int line;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TokenBlock {
|
||||||
|
TokenBlock *next;
|
||||||
|
int current;
|
||||||
|
int count;
|
||||||
|
int max;
|
||||||
|
unsigned char *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TokenStream {
|
||||||
|
TokenStream *next;
|
||||||
|
char *name;
|
||||||
|
TokenBlock *head;
|
||||||
|
TokenBlock *current;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MemoryPool {
|
||||||
|
struct chunk *next;
|
||||||
|
uintptr_t free, end;
|
||||||
|
size_t chunksize;
|
||||||
|
uintptr_t alignmask;
|
||||||
|
struct cleanup *cleanup;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// From PpAtom.cpp
|
||||||
|
//
|
||||||
|
struct StringTable {
|
||||||
|
char *strings;
|
||||||
|
int nextFree;
|
||||||
|
int size;
|
||||||
|
};
|
||||||
|
typedef struct HashEntry_Rec {
|
||||||
|
int index; // String table offset of string representation
|
||||||
|
int value; // Atom (symbol) value
|
||||||
|
} HashEntry;
|
||||||
|
|
||||||
|
static const int hashTableMaxCollisions = 3;
|
||||||
|
|
||||||
|
typedef struct HashTable_Rec {
|
||||||
|
HashEntry *entry;
|
||||||
|
int size;
|
||||||
|
int entries;
|
||||||
|
int counts[hashTableMaxCollisions + 1];
|
||||||
|
} HashTable;
|
||||||
|
struct AtomTable {
|
||||||
|
StringTable stable; // String table.
|
||||||
|
HashTable htable; // Hashes string to atom number and token value. Multiple strings can
|
||||||
|
// have the same token value but each unique string is a unique atom.
|
||||||
|
int *amap; // Maps atom value to offset in string table. Atoms all map to unique
|
||||||
|
// strings except for some undefined values in the lower, fixed part
|
||||||
|
// of the atom table that map to "<undefined>". The lowest 256 atoms
|
||||||
|
// correspond to single character ASCII values except for alphanumeric
|
||||||
|
// characters and '_', which can be other tokens. Next come the
|
||||||
|
// language tokens with their atom values equal to the token value.
|
||||||
|
// Then come predefined atoms, followed by user specified identifiers.
|
||||||
|
int *arev; // Reversed atom for symbol table use.
|
||||||
|
int nextFree;
|
||||||
|
int size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MacroSymbol {
|
||||||
|
int argc;
|
||||||
|
int *args;
|
||||||
|
TokenStream *body;
|
||||||
|
unsigned busy:1;
|
||||||
|
unsigned undef:1;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum symbolkind {
|
||||||
|
MACRO_S
|
||||||
|
} symbolkind;
|
||||||
|
|
||||||
|
struct Symbol {
|
||||||
|
Symbol *left, *right;
|
||||||
|
Symbol *next;
|
||||||
|
int name; // Name atom
|
||||||
|
TSourceLoc loc;
|
||||||
|
symbolkind kind;
|
||||||
|
union {
|
||||||
|
MacroSymbol mac;
|
||||||
|
} details;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct SymbolList {
|
||||||
|
struct SymbolList_Rec *next;
|
||||||
|
Symbol *symb;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Scope {
|
||||||
|
Scope *next, *prev; // doubly-linked list of all scopes
|
||||||
|
Scope *parent;
|
||||||
|
Scope *funScope; // Points to base scope of enclosing function
|
||||||
|
MemoryPool *pool; // pool used for allocation in this scope
|
||||||
|
Symbol *symbols;
|
||||||
|
|
||||||
|
int level; // 0 = super globals, 1 = globals, etc.
|
||||||
|
|
||||||
|
// Only used at global scope (level 1):
|
||||||
|
SymbolList *programs; // List of programs for this compilation.
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
char* preamble; // string to parse, all before line 1 of string 0, it is 0 if no preamble
|
||||||
|
int preambleLength;
|
||||||
|
char** strings; // official strings of shader, starting a string 0 line 1
|
||||||
|
int* lengths;
|
||||||
|
int numStrings; // how many official strings there are
|
||||||
|
int currentString; // which string we're currently parsing (-1 for preamble)
|
||||||
|
|
||||||
|
// Scanner data:
|
||||||
|
int mostRecentToken; // Most recent token seen by the scanner
|
||||||
|
int previous_token;
|
||||||
|
bool notAVersionToken; // used to make sure that #version is the first token seen in the file, if present
|
||||||
|
TParseContext& parseContext;
|
||||||
|
|
||||||
|
static const int maxMacroArgs = 64;
|
||||||
|
static const int maxIfNesting = 64;
|
||||||
|
|
||||||
|
int ifdepth; // current #if-#else-#endif nesting in the cpp.c file (pre-processor)
|
||||||
|
int elsedepth[maxIfNesting]; // Keep a track of #if depth..Max allowed is 64.
|
||||||
|
int elsetracker; // #if-#else and #endif constructs...Counter.
|
||||||
|
const char *ErrMsg;
|
||||||
|
|
||||||
|
typedef struct MacroInputSrc {
|
||||||
|
InputSrc base;
|
||||||
|
MacroSymbol *mac;
|
||||||
|
TokenStream **args;
|
||||||
|
} MacroInputSrc;
|
||||||
|
|
||||||
|
InputSrc *currentInput;
|
||||||
|
|
||||||
|
//
|
||||||
|
// from Pp.cpp
|
||||||
|
//
|
||||||
|
int bindAtom;
|
||||||
|
int constAtom;
|
||||||
|
int defaultAtom;
|
||||||
|
int defineAtom;
|
||||||
|
int definedAtom;
|
||||||
|
int elseAtom;
|
||||||
|
int elifAtom;
|
||||||
|
int endifAtom;
|
||||||
|
int ifAtom;
|
||||||
|
int ifdefAtom;
|
||||||
|
int ifndefAtom;
|
||||||
|
int includeAtom;
|
||||||
|
int lineAtom;
|
||||||
|
int pragmaAtom;
|
||||||
|
int texunitAtom;
|
||||||
|
int undefAtom;
|
||||||
|
int errorAtom;
|
||||||
|
int __LINE__Atom;
|
||||||
|
int __FILE__Atom;
|
||||||
|
int __VERSION__Atom;
|
||||||
|
int versionAtom;
|
||||||
|
int coreAtom;
|
||||||
|
int compatibilityAtom;
|
||||||
|
int esAtom;
|
||||||
|
int extensionAtom;
|
||||||
|
Scope *macros;
|
||||||
|
TSourceLoc ifloc; /* outermost #if */
|
||||||
|
|
||||||
|
int InitCPP();
|
||||||
|
int FreeCPP();
|
||||||
|
int FinalCPP();
|
||||||
|
int CPPdefine(TPpToken * yylvalpp);
|
||||||
|
int CPPundef(TPpToken * yylvalpp);
|
||||||
|
int CPPelse(int matchelse, TPpToken * yylvalpp);
|
||||||
|
int eval(int token, int prec, int *res, int *err, TPpToken * yylvalpp);
|
||||||
|
int CPPif (TPpToken * yylvalpp);
|
||||||
|
int CPPifdef(int defined, TPpToken * yylvalpp);
|
||||||
|
int CPPline(TPpToken * yylvalpp);
|
||||||
|
int CPPerror(TPpToken * yylvalpp);
|
||||||
|
int CPPpragma(TPpToken * yylvalpp);
|
||||||
|
int CPPversion(TPpToken * yylvalpp);
|
||||||
|
int CPPextension(TPpToken * yylvalpp);
|
||||||
|
int readCPPline(TPpToken * yylvalpp);
|
||||||
|
void FreeMacro(MacroSymbol *s);
|
||||||
|
void PushEofSrc();
|
||||||
|
void PopEofSrc();
|
||||||
|
TokenStream* PrescanMacroArg(TokenStream *a, TPpToken * yylvalpp);
|
||||||
|
static int macro_scan(TPpContext* pp, InputSrc *inInput, TPpToken * yylvalpp);
|
||||||
|
static int zero_scan(TPpContext* pp, InputSrc *inInput, TPpToken * yylvalpp);
|
||||||
|
int MacroExpand(int atom, TPpToken* yylvalpp, int expandUndef);
|
||||||
|
int ChkCorrectElseNesting();
|
||||||
|
|
||||||
|
//
|
||||||
|
// from PpSymbols.cpp
|
||||||
|
//
|
||||||
|
Scope *ScopeList;
|
||||||
|
Scope *CurrentScope;
|
||||||
|
Scope *GlobalScope;
|
||||||
|
|
||||||
|
Scope *NewScopeInPool(MemoryPool *pool);
|
||||||
|
void PushScope(Scope *fScope);
|
||||||
|
Scope *PopScope(void);
|
||||||
|
Symbol *NewSymbol(TSourceLoc *loc, Scope *fScope, int name, symbolkind kind);
|
||||||
|
void lAddToTree(Symbol **fSymbols, Symbol *fSymb, AtomTable *atable);
|
||||||
|
Symbol *AddSymbol(TSourceLoc *loc, Scope *fScope, int atom, symbolkind kind);
|
||||||
|
Symbol *LookUpLocalSymbol(Scope *fScope, int atom);
|
||||||
|
Symbol *LookUpSymbol(Scope *fScope, int atom);
|
||||||
|
|
||||||
|
//
|
||||||
|
// From PpTokens.cpp
|
||||||
|
//
|
||||||
|
char* idstr(const char *fstr, MemoryPool *pool);
|
||||||
|
TPpContext::TokenBlock* lNewBlock(TokenStream *fTok, MemoryPool *pool);
|
||||||
|
void lAddByte(TokenStream *fTok, unsigned char fVal);
|
||||||
|
int lReadByte(TokenStream *pTok);
|
||||||
|
TokenStream *NewTokenStream(const char *name, MemoryPool *pool);
|
||||||
|
void DeleteTokenStream(TokenStream *pTok);
|
||||||
|
void RecordToken(TokenStream *pTok, int token, TPpToken * yylvalpp);
|
||||||
|
void RewindTokenStream(TokenStream *pTok);
|
||||||
|
int ReadToken(TokenStream *pTok, TPpToken * yylvalpp);
|
||||||
|
int ReadFromTokenStream(TokenStream *ts, int name, int (*final)(TPpContext *));
|
||||||
|
void UngetToken(int token, TPpToken * yylvalpp);
|
||||||
|
void DumpTokenStream(FILE *fp, TokenStream *s, TPpToken * yylvalpp);
|
||||||
|
struct TokenInputSrc {
|
||||||
|
InputSrc base;
|
||||||
|
TokenStream *tokens;
|
||||||
|
int (*final)(TPpContext *);
|
||||||
|
};
|
||||||
|
static int scan_token(TPpContext*, TokenInputSrc *in, TPpToken * yylvalpp);
|
||||||
|
struct UngotToken {
|
||||||
|
InputSrc base;
|
||||||
|
int token;
|
||||||
|
TPpToken lval;
|
||||||
|
};
|
||||||
|
static int reget_token(TPpContext *, UngotToken *t, TPpToken * yylvalpp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// From PpScanner.cpp
|
||||||
|
//
|
||||||
|
struct StringInputSrc {
|
||||||
|
InputSrc base;
|
||||||
|
char *p;
|
||||||
|
};
|
||||||
|
int InitScanner(TPpContext *cpp);
|
||||||
|
int FreeScanner(void);
|
||||||
|
static int str_getch(TPpContext*, StringInputSrc *in);
|
||||||
|
static void str_ungetch(TPpContext*, StringInputSrc *in, int ch, TPpToken *type);
|
||||||
|
int ScanFromString(char *s);
|
||||||
|
int check_EOF(int token);
|
||||||
|
int lFloatConst(char *str, int len, int ch, TPpToken * yylvalpp);
|
||||||
|
static int byte_scan(TPpContext*, InputSrc *in, TPpToken * yylvalpp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// From PpAtom.cpp
|
||||||
|
//
|
||||||
|
AtomTable atomTable;
|
||||||
|
int InitAtomTable(AtomTable *atable, int htsize);
|
||||||
|
void FreeAtomTable(AtomTable *atable);
|
||||||
|
int AddAtom(AtomTable *atable, const char *s);
|
||||||
|
int AddAtomFixed(AtomTable *atable, const char *s, int atom);
|
||||||
|
void PrintAtomTable(AtomTable *atable);
|
||||||
|
int IncreaseHashTableSize(TPpContext::AtomTable *atable);
|
||||||
|
int LookUpAddStringHash(AtomTable *atable, const char *s);
|
||||||
|
int LookUpAddString(AtomTable *atable, const char *s);
|
||||||
|
const char *GetAtomString(AtomTable *atable, int atom);
|
||||||
|
int GetReversedAtom(AtomTable *atable, int atom);
|
||||||
|
char* GetStringOfAtom(AtomTable *atable, int atom);
|
||||||
|
|
||||||
|
//
|
||||||
|
// From PpMemory.cpp
|
||||||
|
//
|
||||||
|
MemoryPool *mem_CreatePool(size_t chunksize, unsigned align);
|
||||||
|
void mem_FreePool(MemoryPool *);
|
||||||
|
void *mem_Alloc(MemoryPool *p, size_t size);
|
||||||
|
int mem_AddCleanup(MemoryPool *p, void (*fn)(void *, void*), void *arg1, void* arg2);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PPCONTEXT_H
|
||||||
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
|
//Copyright (C) 2013 LunarG, Inc.
|
||||||
//All rights reserved.
|
//All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
//Redistribution and use in source and binary forms, with or without
|
||||||
@@ -80,7 +81,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "memory.h"
|
#include "PpContext.h"
|
||||||
|
|
||||||
// default alignment and chunksize, if called with 0 arguments
|
// default alignment and chunksize, if called with 0 arguments
|
||||||
#define CHUNKSIZE (64*1024)
|
#define CHUNKSIZE (64*1024)
|
||||||
@@ -96,28 +97,28 @@ struct chunk {
|
|||||||
|
|
||||||
struct cleanup {
|
struct cleanup {
|
||||||
struct cleanup *next;
|
struct cleanup *next;
|
||||||
void (*fn)(void *);
|
void (*fn)(void *, void *);
|
||||||
void *arg;
|
void *arg1;
|
||||||
|
void *arg2;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MemoryPool_rec {
|
TPpContext::MemoryPool* TPpContext::mem_CreatePool(size_t chunksize, unsigned int align)
|
||||||
struct chunk *next;
|
|
||||||
uintptr_t free, end;
|
|
||||||
size_t chunksize;
|
|
||||||
uintptr_t alignmask;
|
|
||||||
struct cleanup *cleanup;
|
|
||||||
};
|
|
||||||
|
|
||||||
MemoryPool *mem_CreatePool(size_t chunksize, unsigned int align)
|
|
||||||
{
|
{
|
||||||
MemoryPool *pool;
|
MemoryPool *pool;
|
||||||
|
|
||||||
if (align == 0) align = ALIGN;
|
if (align == 0)
|
||||||
if (chunksize == 0) chunksize = CHUNKSIZE;
|
align = ALIGN;
|
||||||
if (align & (align-1)) return 0;
|
if (chunksize == 0)
|
||||||
if (chunksize < sizeof(MemoryPool)) return 0;
|
chunksize = CHUNKSIZE;
|
||||||
if (chunksize & (align-1)) return 0;
|
if (align & (align-1))
|
||||||
if (!(pool = (MemoryPool*)malloc(chunksize))) return 0;
|
return 0;
|
||||||
|
if (chunksize < sizeof(MemoryPool))
|
||||||
|
return 0;
|
||||||
|
if (chunksize & (align-1))
|
||||||
|
return 0;
|
||||||
|
if (!(pool = (MemoryPool*)malloc(chunksize)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
pool->next = 0;
|
pool->next = 0;
|
||||||
pool->chunksize = chunksize;
|
pool->chunksize = chunksize;
|
||||||
pool->alignmask = (uintptr_t)(align)-1;
|
pool->alignmask = (uintptr_t)(align)-1;
|
||||||
@@ -127,13 +128,13 @@ MemoryPool *mem_CreatePool(size_t chunksize, unsigned int align)
|
|||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mem_FreePool(MemoryPool *pool)
|
void TPpContext::mem_FreePool(MemoryPool *pool)
|
||||||
{
|
{
|
||||||
struct cleanup *cleanup;
|
struct cleanup *cleanup;
|
||||||
struct chunk *p, *next;
|
struct chunk *p, *next;
|
||||||
|
|
||||||
for (cleanup = pool->cleanup; cleanup; cleanup = cleanup->next) {
|
for (cleanup = pool->cleanup; cleanup; cleanup = cleanup->next) {
|
||||||
cleanup->fn(cleanup->arg);
|
cleanup->fn(cleanup->arg1, cleanup->arg2);
|
||||||
}
|
}
|
||||||
for (p = (struct chunk *)pool; p; p = next) {
|
for (p = (struct chunk *)pool; p; p = next) {
|
||||||
next = p->next;
|
next = p->next;
|
||||||
@@ -141,7 +142,7 @@ void mem_FreePool(MemoryPool *pool)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *mem_Alloc(MemoryPool *pool, size_t size)
|
void* TPpContext::mem_Alloc(MemoryPool *pool, size_t size)
|
||||||
{
|
{
|
||||||
struct chunk *ch;
|
struct chunk *ch;
|
||||||
void *rv = (void *)pool->free;
|
void *rv = (void *)pool->free;
|
||||||
@@ -149,8 +150,7 @@ void *mem_Alloc(MemoryPool *pool, size_t size)
|
|||||||
if (size <= 0) size = pool->alignmask;
|
if (size <= 0) size = pool->alignmask;
|
||||||
pool->free += size;
|
pool->free += size;
|
||||||
if (pool->free > pool->end || pool->free < (uintptr_t)rv) {
|
if (pool->free > pool->end || pool->free < (uintptr_t)rv) {
|
||||||
size_t minreq = (size + sizeof(struct chunk) + pool->alignmask)
|
size_t minreq = (size + sizeof(struct chunk) + pool->alignmask) & ~pool->alignmask;
|
||||||
& ~pool->alignmask;
|
|
||||||
pool->free = (uintptr_t)rv;
|
pool->free = (uintptr_t)rv;
|
||||||
if (minreq >= pool->chunksize) {
|
if (minreq >= pool->chunksize) {
|
||||||
// request size is too big for the chunksize, so allocate it as
|
// request size is too big for the chunksize, so allocate it as
|
||||||
@@ -170,7 +170,8 @@ void *mem_Alloc(MemoryPool *pool, size_t size)
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mem_AddCleanup(MemoryPool *pool, void (*fn)(void *), void *arg) {
|
int TPpContext::mem_AddCleanup(MemoryPool *pool, void (*fn)(void *, void*), void* arg1, void* arg2)
|
||||||
|
{
|
||||||
struct cleanup *cleanup;
|
struct cleanup *cleanup;
|
||||||
|
|
||||||
pool->free = (pool->free + sizeof(void *) - 1) & ~(sizeof(void *)-1);
|
pool->free = (pool->free + sizeof(void *) - 1) & ~(sizeof(void *)-1);
|
||||||
@@ -178,7 +179,8 @@ int mem_AddCleanup(MemoryPool *pool, void (*fn)(void *), void *arg) {
|
|||||||
if (!cleanup) return -1;
|
if (!cleanup) return -1;
|
||||||
cleanup->next = pool->cleanup;
|
cleanup->next = pool->cleanup;
|
||||||
cleanup->fn = fn;
|
cleanup->fn = fn;
|
||||||
cleanup->arg = arg;
|
cleanup->arg1 = arg1;
|
||||||
|
cleanup->arg2 = arg2;
|
||||||
pool->cleanup = cleanup;
|
pool->cleanup = cleanup;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
|
//Copyright (C) 2013 LunarG, Inc.
|
||||||
//All rights reserved.
|
//All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
//Redistribution and use in source and binary forms, with or without
|
||||||
@@ -86,129 +87,93 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#include <ieeefp.h>
|
#include <ieeefp.h>
|
||||||
#else
|
#else
|
||||||
#define isinff(x) (((*(int *)&(x) & 0x7f800000L)==0x7f800000L) && \
|
#define isinff(x) (((*(int *)&(x) & 0x7f800000L)==0x7f800000L) && \
|
||||||
((*(int *)&(x) & 0x007fffffL)==0000000000L))
|
((*(int *)&(x) & 0x007fffffL)==0000000000L))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "slglobals.h"
|
#include "PpContext.h"
|
||||||
|
#include "PpTokens.h"
|
||||||
|
|
||||||
|
static int eof_scan(TPpContext*, TPpContext::InputSrc*, TPpToken*)
|
||||||
typedef struct StringInputSrc {
|
|
||||||
InputSrc base;
|
|
||||||
char *p;
|
|
||||||
} StringInputSrc;
|
|
||||||
|
|
||||||
static int eof_scan(InputSrc *is, yystypepp * yylvalpp)
|
|
||||||
{
|
{
|
||||||
return EOF;
|
return EOF;
|
||||||
} // eof_scan
|
} // eof_scan
|
||||||
|
|
||||||
static void noop(InputSrc *in, int ch, yystypepp * yylvalpp) {}
|
static void noop(TPpContext*, TPpContext::InputSrc *in, int ch, TPpToken * yylvalpp) {}
|
||||||
|
static TPpContext::InputSrc eof_inputsrc = { 0, &eof_scan, &eof_scan, &noop };
|
||||||
|
|
||||||
static InputSrc eof_inputsrc = { 0, &eof_scan, &eof_scan, &noop };
|
int TPpContext::InitScanner(TPpContext *cpp)
|
||||||
|
|
||||||
static int byte_scan(InputSrc *, yystypepp * yylvalpp);
|
|
||||||
|
|
||||||
#define EOL_SY '\n'
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
#define DBG_BREAKPOINT() __asm int 3
|
|
||||||
#elif defined(_M_AMD64)
|
|
||||||
#define DBG_BREAKPOINT() assert(!"Dbg_Breakpoint");
|
|
||||||
#else
|
|
||||||
#define DBG_BREAKPOINT()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(_M_AMD64)
|
|
||||||
__int64 RDTSC ( void ) {
|
|
||||||
|
|
||||||
__int64 v;
|
|
||||||
|
|
||||||
__asm __emit 0x0f
|
|
||||||
__asm __emit 0x31
|
|
||||||
__asm mov dword ptr v, eax
|
|
||||||
__asm mov dword ptr v+4, edx
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
int InitScanner(CPPStruct *cpp)
|
|
||||||
{
|
{
|
||||||
// Add various atoms needed by the CPP line scanner:
|
// Add various atoms needed by the CPP line scanner:
|
||||||
if (!InitCPP())
|
if (!InitCPP())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cpp->mostRecentToken = 0;
|
mostRecentToken = 0;
|
||||||
cpp->tokenLoc = &cpp->ltokenLoc;
|
currentInput = &eof_inputsrc;
|
||||||
|
previous_token = '\n';
|
||||||
cpp->ltokenLoc.file = 0;
|
notAVersionToken = false;
|
||||||
cpp->ltokenLoc.line = 0;
|
|
||||||
|
|
||||||
cpp->currentInput = &eof_inputsrc;
|
|
||||||
cpp->previous_token = '\n';
|
|
||||||
cpp->notAVersionToken = 0;
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
} // InitScanner
|
} // InitScanner
|
||||||
|
|
||||||
int FreeScanner(void)
|
int TPpContext::FreeScanner(void)
|
||||||
{
|
{
|
||||||
return (FreeCPP());
|
return (FreeCPP());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* str_getch()
|
* str_getch()
|
||||||
* takes care of reading from multiple strings.
|
* takes care of reading from multiple strings.
|
||||||
* returns the next-char from the input stream.
|
* returns the next-char from the input stream.
|
||||||
* returns EOF when the complete shader is parsed.
|
* returns EOF when the complete shader is parsed.
|
||||||
*/
|
*/
|
||||||
static int str_getch(StringInputSrc *in)
|
int TPpContext::str_getch(TPpContext* pp, StringInputSrc *in)
|
||||||
{
|
{
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if (*in->p) {
|
if (*in->p) {
|
||||||
if (*in->p == '\n') {
|
if (*in->p == '\n') {
|
||||||
in->base.line++;
|
in->base.line++;
|
||||||
IncLineNumber();
|
++pp->parseContext.currentLoc.line;
|
||||||
}
|
}
|
||||||
return *in->p++;
|
return *in->p++;
|
||||||
}
|
}
|
||||||
if (cpp->PaWhichStr < 0) {
|
if (pp->currentString < 0) {
|
||||||
// we only parsed the built-in pre-amble; start with clean slate for user code
|
// we only parsed the built-in pre-amble; start with clean slate for user code
|
||||||
cpp->notAVersionToken = 0;
|
pp->notAVersionToken = false;
|
||||||
}
|
}
|
||||||
if (++(cpp->PaWhichStr) < cpp->PaArgc) {
|
if (++(pp->currentString) < pp->numStrings) {
|
||||||
free(in);
|
free(in);
|
||||||
SetStringNumber(cpp->PaWhichStr);
|
pp->parseContext.currentLoc.string = pp->currentString;
|
||||||
SetLineNumber(1);
|
pp->parseContext.currentLoc.line = 1;
|
||||||
ScanFromString(cpp->PaArgv[cpp->PaWhichStr]);
|
pp->ScanFromString(pp->strings[pp->currentString]);
|
||||||
in=(StringInputSrc*)cpp->currentInput;
|
in=(StringInputSrc*)pp->currentInput;
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
cpp->currentInput = in->base.prev;
|
pp->currentInput = in->base.prev;
|
||||||
cpp->PaWhichStr=0;
|
pp->currentString = 0;
|
||||||
free(in);
|
free(in);
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // str_getch
|
} // str_getch
|
||||||
|
|
||||||
static void str_ungetch(StringInputSrc *in, int ch, yystypepp *type) {
|
void TPpContext::str_ungetch(TPpContext* pp, StringInputSrc *in, int ch, TPpToken *type)
|
||||||
|
{
|
||||||
if (in->p[-1] == ch)in->p--;
|
if (in->p[-1] == ch)in->p--;
|
||||||
else {
|
else {
|
||||||
*(in->p)='\0'; //this would take care of shifting to the previous string.
|
*(in->p)='\0'; //this would take care of shifting to the previous string.
|
||||||
cpp->PaWhichStr--;
|
pp->currentString--;
|
||||||
|
pp->parseContext.currentLoc.string = pp->currentString;
|
||||||
}
|
}
|
||||||
if (ch == '\n') {
|
if (ch == '\n') {
|
||||||
in->base.line--;
|
in->base.line--;
|
||||||
DecLineNumber();
|
--pp->parseContext.currentLoc.line;
|
||||||
}
|
}
|
||||||
} // str_ungetch
|
} // str_ungetch
|
||||||
|
|
||||||
int ScanFromString(char *s)
|
int TPpContext::ScanFromString(char *s)
|
||||||
{
|
{
|
||||||
|
|
||||||
StringInputSrc *in = (StringInputSrc *)malloc(sizeof(StringInputSrc));
|
StringInputSrc *in = (StringInputSrc *)malloc(sizeof(StringInputSrc));
|
||||||
@@ -216,10 +181,10 @@ int ScanFromString(char *s)
|
|||||||
in->p = s;
|
in->p = s;
|
||||||
in->base.line = 1;
|
in->base.line = 1;
|
||||||
in->base.scan = byte_scan;
|
in->base.scan = byte_scan;
|
||||||
in->base.getch = (int (*)(InputSrc *, yystypepp *))str_getch;
|
in->base.getch = (int (*)(TPpContext*, InputSrc *, TPpToken *))str_getch;
|
||||||
in->base.ungetch = (void (*)(InputSrc *, int, yystypepp *))str_ungetch;
|
in->base.ungetch = (void (*)(TPpContext*, InputSrc *, int, TPpToken *))str_ungetch;
|
||||||
in->base.prev = cpp->currentInput;
|
in->base.prev = currentInput;
|
||||||
cpp->currentInput = &in->base;
|
currentInput = &in->base;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -230,12 +195,12 @@ int ScanFromString(char *s)
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* lFloatConst() - Scan a single- or double-precision floating point constant. Assumes that the scanner
|
* lFloatConst() - Scan a single- or double-precision floating point constant. Assumes that the scanner
|
||||||
* has seen at least one digit, followed by either a decimal '.' or the
|
* has seen at least one digit, followed by either a decimal '.' or the
|
||||||
* letter 'e'.
|
* letter 'e'.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
|
int TPpContext::lFloatConst(char *str, int len, int ch, TPpToken * yylvalpp)
|
||||||
{
|
{
|
||||||
int HasDecimal, declen, exp, ExpSign;
|
int HasDecimal, declen, exp, ExpSign;
|
||||||
int str_len;
|
int str_len;
|
||||||
@@ -249,17 +214,17 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
|
|||||||
if (ch == '.') {
|
if (ch == '.') {
|
||||||
str[len++]=ch;
|
str[len++]=ch;
|
||||||
HasDecimal = 1;
|
HasDecimal = 1;
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = currentInput->getch(this, currentInput, yylvalpp);
|
||||||
while (ch >= '0' && ch <= '9') {
|
while (ch >= '0' && ch <= '9') {
|
||||||
if (len < MAX_TOKEN_LENGTH) {
|
if (len < TPpToken::maxTokenLength) {
|
||||||
declen++;
|
declen++;
|
||||||
if (len > 0 || ch != '0') {
|
if (len > 0 || ch != '0') {
|
||||||
str[len] = ch;
|
str[len] = ch;
|
||||||
len++;str_len++;
|
len++;str_len++;
|
||||||
}
|
}
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = currentInput->getch(this, currentInput, yylvalpp);
|
||||||
} else {
|
} else {
|
||||||
ShPpErrorToInfoLog("floating-point literal too long");
|
parseContext.error(yylvalpp->loc,"float literal too long", "", "");
|
||||||
len = 1,str_len=1;
|
len = 1,str_len=1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -268,74 +233,74 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
|
|||||||
// Exponent:
|
// Exponent:
|
||||||
|
|
||||||
if (ch == 'e' || ch == 'E') {
|
if (ch == 'e' || ch == 'E') {
|
||||||
if (len >= MAX_TOKEN_LENGTH) {
|
if (len >= TPpToken::maxTokenLength) {
|
||||||
ShPpErrorToInfoLog("floating-point literal too long");
|
parseContext.error(yylvalpp->loc,"float literal too long", "", "");
|
||||||
len = 1,str_len=1;
|
len = 1,str_len=1;
|
||||||
} else {
|
} else {
|
||||||
ExpSign = 1;
|
ExpSign = 1;
|
||||||
str[len++]=ch;
|
str[len++]=ch;
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = currentInput->getch(this, currentInput, yylvalpp);
|
||||||
if (ch == '+') {
|
if (ch == '+') {
|
||||||
str[len++]=ch;
|
str[len++]=ch;
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = currentInput->getch(this, currentInput, yylvalpp);
|
||||||
} else if (ch == '-') {
|
} else if (ch == '-') {
|
||||||
ExpSign = -1;
|
ExpSign = -1;
|
||||||
str[len++]=ch;
|
str[len++]=ch;
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = currentInput->getch(this, currentInput, yylvalpp);
|
||||||
}
|
}
|
||||||
if (ch >= '0' && ch <= '9') {
|
if (ch >= '0' && ch <= '9') {
|
||||||
while (ch >= '0' && ch <= '9') {
|
while (ch >= '0' && ch <= '9') {
|
||||||
if (len < MAX_TOKEN_LENGTH) {
|
if (len < TPpToken::maxTokenLength) {
|
||||||
exp = exp*10 + ch - '0';
|
exp = exp*10 + ch - '0';
|
||||||
str[len++]=ch;
|
str[len++]=ch;
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = currentInput->getch(this, currentInput, yylvalpp);
|
||||||
} else {
|
} else {
|
||||||
ShPpErrorToInfoLog("floating-point literal too long");
|
parseContext.error(yylvalpp->loc,"float literal too long", "", "");
|
||||||
len = 1,str_len=1;
|
len = 1,str_len=1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ShPpErrorToInfoLog("bad character in exponent");
|
parseContext.error(yylvalpp->loc,"bad character in float exponent", "", "");
|
||||||
}
|
}
|
||||||
exp *= ExpSign;
|
exp *= ExpSign;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
yylvalpp->sc_dval = 0.0;
|
yylvalpp->dval = 0.0;
|
||||||
strcpy(str, "0.0");
|
strcpy(str, "0.0");
|
||||||
} else {
|
} else {
|
||||||
if (ch == 'l' || ch == 'L') {
|
if (ch == 'l' || ch == 'L') {
|
||||||
int ch2 = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
int ch2 = currentInput->getch(this, currentInput, yylvalpp);
|
||||||
if (ch2 != 'f' && ch2 != 'F') {
|
if (ch2 != 'f' && ch2 != 'F') {
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch2, yylvalpp);
|
currentInput->ungetch(this, currentInput, ch2, yylvalpp);
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
|
currentInput->ungetch(this, currentInput, ch, yylvalpp);
|
||||||
} else {
|
} else {
|
||||||
if (len < MAX_TOKEN_LENGTH) {
|
if (len < TPpToken::maxTokenLength) {
|
||||||
str[len++] = ch;
|
str[len++] = ch;
|
||||||
str[len++] = ch2;
|
str[len++] = ch2;
|
||||||
isDouble = 1;
|
isDouble = 1;
|
||||||
} else {
|
} else {
|
||||||
ShPpErrorToInfoLog("floating-point literal too long");
|
parseContext.error(yylvalpp->loc,"float literal too long", "", "");
|
||||||
len = 1,str_len=1;
|
len = 1,str_len=1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (ch == 'f' || ch == 'F') {
|
} else if (ch == 'f' || ch == 'F') {
|
||||||
if (len < MAX_TOKEN_LENGTH)
|
if (len < TPpToken::maxTokenLength)
|
||||||
str[len++] = ch;
|
str[len++] = ch;
|
||||||
else {
|
else {
|
||||||
ShPpErrorToInfoLog("floating-point literal too long");
|
parseContext.error(yylvalpp->loc,"float literal too long", "", "");
|
||||||
len = 1,str_len=1;
|
len = 1,str_len=1;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
|
currentInput->ungetch(this, currentInput, ch, yylvalpp);
|
||||||
|
|
||||||
str[len]='\0';
|
str[len]='\0';
|
||||||
|
|
||||||
yylvalpp->sc_dval = strtod(str, 0);
|
yylvalpp->dval = strtod(str, 0);
|
||||||
}
|
}
|
||||||
// Suffix:
|
// Suffix:
|
||||||
strcpy(yylvalpp->symbol_name, str);
|
strcpy(yylvalpp->name, str);
|
||||||
|
|
||||||
if (isDouble)
|
if (isDouble)
|
||||||
return CPP_DOUBLECONSTANT;
|
return CPP_DOUBLECONSTANT;
|
||||||
@@ -347,24 +312,23 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
|
|||||||
///////////////////////////////////////// Normal Scanner //////////////////////////////////////
|
///////////////////////////////////////// Normal Scanner //////////////////////////////////////
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
|
int TPpContext::byte_scan(TPpContext* pp, InputSrc *in, TPpToken * yylvalpp)
|
||||||
{
|
{
|
||||||
char tokenText[MAX_TOKEN_LENGTH + 1];
|
char tokenText[TPpToken::maxTokenLength + 1];
|
||||||
int AlreadyComplained = 0;
|
int AlreadyComplained = 0;
|
||||||
int len, ch, ii;
|
int len, ch, ii;
|
||||||
unsigned ival = 0;
|
unsigned ival = 0;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
yylvalpp->sc_int = 0;
|
yylvalpp->ival = 0;
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
|
|
||||||
while (ch == ' ' || ch == '\t' || ch == '\r') {
|
while (ch == ' ' || ch == '\t' || ch == '\r') {
|
||||||
yylvalpp->sc_int = 1;
|
yylvalpp->ival = 1;
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
}
|
}
|
||||||
|
|
||||||
cpp->ltokenLoc.file = cpp->currentInput->name;
|
yylvalpp->loc = pp->parseContext.currentLoc;
|
||||||
cpp->ltokenLoc.line = cpp->currentInput->line;
|
|
||||||
len = 0;
|
len = 0;
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
default:
|
default:
|
||||||
@@ -386,24 +350,24 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
|
|||||||
do {
|
do {
|
||||||
if (ch == '\\') {
|
if (ch == '\\') {
|
||||||
// escaped character
|
// escaped character
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if (ch == '\r' || ch == '\n') {
|
if (ch == '\r' || ch == '\n') {
|
||||||
int nextch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
int nextch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if (ch == '\r' && nextch == '\n')
|
if (ch == '\r' && nextch == '\n')
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
else
|
else
|
||||||
ch = nextch;
|
ch = nextch;
|
||||||
} else
|
} else
|
||||||
ShPpErrorToInfoLog("can only escape newlines");
|
pp->parseContext.error(yylvalpp->loc,"can only escape newlines", "\\", "");
|
||||||
} else if (len < MAX_TOKEN_LENGTH) {
|
} else if (len < TPpToken::maxTokenLength) {
|
||||||
tokenText[len++] = ch;
|
tokenText[len++] = ch;
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
} else {
|
} else {
|
||||||
if (! AlreadyComplained) {
|
if (! AlreadyComplained) {
|
||||||
ShPpErrorToInfoLog("name too long");
|
pp->parseContext.error(yylvalpp->loc,"name too long", "", "");
|
||||||
AlreadyComplained = 1;
|
AlreadyComplained = 1;
|
||||||
}
|
}
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
}
|
}
|
||||||
} while ((ch >= 'a' && ch <= 'z') ||
|
} while ((ch >= 'a' && ch <= 'z') ||
|
||||||
(ch >= 'A' && ch <= 'Z') ||
|
(ch >= 'A' && ch <= 'Z') ||
|
||||||
@@ -412,17 +376,17 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
|
|||||||
ch == '\\');
|
ch == '\\');
|
||||||
|
|
||||||
tokenText[len] = '\0';
|
tokenText[len] = '\0';
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
|
pp->currentInput->ungetch(pp, pp->currentInput, ch, yylvalpp);
|
||||||
yylvalpp->sc_ident = LookUpAddString(atable, tokenText);
|
yylvalpp->atom = pp->LookUpAddString(&pp->atomTable, tokenText);
|
||||||
|
|
||||||
return CPP_IDENTIFIER;
|
return CPP_IDENTIFIER;
|
||||||
case '0':
|
case '0':
|
||||||
yylvalpp->symbol_name[len++] = ch;
|
yylvalpp->name[len++] = ch;
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if (ch == 'x' || ch == 'X') {
|
if (ch == 'x' || ch == 'X') {
|
||||||
int uint = 0;
|
int uint = 0;
|
||||||
yylvalpp->symbol_name[len++] = ch;
|
yylvalpp->name[len++] = ch;
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if ((ch >= '0' && ch <= '9') ||
|
if ((ch >= '0' && ch <= '9') ||
|
||||||
(ch >= 'A' && ch <= 'F') ||
|
(ch >= 'A' && ch <= 'F') ||
|
||||||
(ch >= 'a' && ch <= 'f'))
|
(ch >= 'a' && ch <= 'f'))
|
||||||
@@ -430,7 +394,7 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
|
|||||||
ival = 0;
|
ival = 0;
|
||||||
do {
|
do {
|
||||||
if (ival <= 0x0fffffff) {
|
if (ival <= 0x0fffffff) {
|
||||||
yylvalpp->symbol_name[len++] = ch;
|
yylvalpp->name[len++] = ch;
|
||||||
if (ch >= '0' && ch <= '9') {
|
if (ch >= '0' && ch <= '9') {
|
||||||
ii = ch - '0';
|
ii = ch - '0';
|
||||||
} else if (ch >= 'A' && ch <= 'F') {
|
} else if (ch >= 'A' && ch <= 'F') {
|
||||||
@@ -438,30 +402,30 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
|
|||||||
} else if (ch >= 'a' && ch <= 'f') {
|
} else if (ch >= 'a' && ch <= 'f') {
|
||||||
ii = ch - 'a' + 10;
|
ii = ch - 'a' + 10;
|
||||||
} else
|
} else
|
||||||
ShPpErrorToInfoLog("bad digit in hexidecimal literal");
|
pp->parseContext.error(yylvalpp->loc,"bad digit in hexidecimal literal", "", "");
|
||||||
ival = (ival << 4) | ii;
|
ival = (ival << 4) | ii;
|
||||||
} else {
|
} else {
|
||||||
if (! AlreadyComplained) {
|
if (! AlreadyComplained) {
|
||||||
ShPpErrorToInfoLog("hexidecimal literal too big");
|
pp->parseContext.error(yylvalpp->loc,"hexidecimal literal too big literal", "", "");
|
||||||
AlreadyComplained = 1;
|
AlreadyComplained = 1;
|
||||||
}
|
}
|
||||||
ival = 0xffffffff;
|
ival = 0xffffffff;
|
||||||
}
|
}
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
} while ((ch >= '0' && ch <= '9') ||
|
} while ((ch >= '0' && ch <= '9') ||
|
||||||
(ch >= 'A' && ch <= 'F') ||
|
(ch >= 'A' && ch <= 'F') ||
|
||||||
(ch >= 'a' && ch <= 'f'));
|
(ch >= 'a' && ch <= 'f'));
|
||||||
} else {
|
} else {
|
||||||
ShPpErrorToInfoLog("bad digit in hexidecimal literal");
|
pp->parseContext.error(yylvalpp->loc,"bad digit in hexidecimal literal", "", "");
|
||||||
}
|
}
|
||||||
if (ch == 'u' || ch == 'U') {
|
if (ch == 'u' || ch == 'U') {
|
||||||
if (len < MAX_TOKEN_LENGTH)
|
if (len < TPpToken::maxTokenLength)
|
||||||
yylvalpp->symbol_name[len++] = ch;
|
yylvalpp->name[len++] = ch;
|
||||||
uint = 1;
|
uint = 1;
|
||||||
} else
|
} else
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
|
pp->currentInput->ungetch(pp, pp->currentInput, ch, yylvalpp);
|
||||||
yylvalpp->symbol_name[len] = '\0';
|
yylvalpp->name[len] = '\0';
|
||||||
yylvalpp->sc_int = (int)ival;
|
yylvalpp->ival = (int)ival;
|
||||||
|
|
||||||
if (uint)
|
if (uint)
|
||||||
return CPP_UINTCONSTANT;
|
return CPP_UINTCONSTANT;
|
||||||
@@ -472,79 +436,79 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
|
|||||||
ival = 0;
|
ival = 0;
|
||||||
do {
|
do {
|
||||||
if (ival <= 0x1fffffff) {
|
if (ival <= 0x1fffffff) {
|
||||||
yylvalpp->symbol_name[len++] = ch;
|
yylvalpp->name[len++] = ch;
|
||||||
ii = ch - '0';
|
ii = ch - '0';
|
||||||
ival = (ival << 3) | ii;
|
ival = (ival << 3) | ii;
|
||||||
} else {
|
} else {
|
||||||
if (!AlreadyComplained) {
|
if (!AlreadyComplained) {
|
||||||
ShPpErrorToInfoLog("octal literal too big");
|
pp->parseContext.error(yylvalpp->loc,"octal literal too big", "", "");
|
||||||
AlreadyComplained = 1;
|
AlreadyComplained = 1;
|
||||||
}
|
}
|
||||||
ival = 0xffffffff;
|
ival = 0xffffffff;
|
||||||
}
|
}
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
} while (ch >= '0' && ch <= '7');
|
} while (ch >= '0' && ch <= '7');
|
||||||
if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E' || ch == 'F' || ch == 'l' || ch == 'L')
|
if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E' || ch == 'F' || ch == 'l' || ch == 'L')
|
||||||
return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp);
|
return pp->lFloatConst(yylvalpp->name, len, ch, yylvalpp);
|
||||||
else if (ch == 'u' || ch == 'U') {
|
else if (ch == 'u' || ch == 'U') {
|
||||||
if (len < MAX_TOKEN_LENGTH)
|
if (len < TPpToken::maxTokenLength)
|
||||||
yylvalpp->symbol_name[len++] = ch;
|
yylvalpp->name[len++] = ch;
|
||||||
uint = 1;
|
uint = 1;
|
||||||
} else
|
} else
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
|
pp->currentInput->ungetch(pp, pp->currentInput, ch, yylvalpp);
|
||||||
yylvalpp->symbol_name[len] = '\0';
|
yylvalpp->name[len] = '\0';
|
||||||
yylvalpp->sc_int = (int)ival;
|
yylvalpp->ival = (int)ival;
|
||||||
|
|
||||||
if (uint)
|
if (uint)
|
||||||
return CPP_UINTCONSTANT;
|
return CPP_UINTCONSTANT;
|
||||||
else
|
else
|
||||||
return CPP_INTCONSTANT;
|
return CPP_INTCONSTANT;
|
||||||
} else {
|
} else {
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
|
pp->currentInput->ungetch(pp, pp->currentInput, ch, yylvalpp);
|
||||||
ch = '0';
|
ch = '0';
|
||||||
}
|
}
|
||||||
// Fall through...
|
// Fall through...
|
||||||
case '1': case '2': case '3': case '4':
|
case '1': case '2': case '3': case '4':
|
||||||
case '5': case '6': case '7': case '8': case '9':
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
do {
|
do {
|
||||||
if (len < MAX_TOKEN_LENGTH) {
|
if (len < TPpToken::maxTokenLength) {
|
||||||
if (len > 0 || ch != '0') {
|
if (len > 0 || ch != '0') {
|
||||||
yylvalpp->symbol_name[len] = ch;
|
yylvalpp->name[len] = ch;
|
||||||
len++;
|
len++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (! AlreadyComplained) {
|
if (! AlreadyComplained) {
|
||||||
ShPpErrorToInfoLog("integer literal too long");
|
pp->parseContext.error(yylvalpp->loc,"numeric literal too long", "", "");
|
||||||
AlreadyComplained = 1;
|
AlreadyComplained = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
} while (ch >= '0' && ch <= '9');
|
} while (ch >= '0' && ch <= '9');
|
||||||
if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E' || ch == 'F' || ch == 'l' || ch == 'L') {
|
if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E' || ch == 'F' || ch == 'l' || ch == 'L') {
|
||||||
return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp);
|
return pp->lFloatConst(yylvalpp->name, len, ch, yylvalpp);
|
||||||
} else {
|
} else {
|
||||||
// Finish handling signed and unsigned integers
|
// Finish handling signed and unsigned integers
|
||||||
int numericLen = len;
|
int numericLen = len;
|
||||||
int uint = 0;
|
int uint = 0;
|
||||||
if (ch == 'u' || ch == 'U') {
|
if (ch == 'u' || ch == 'U') {
|
||||||
if (len < MAX_TOKEN_LENGTH)
|
if (len < TPpToken::maxTokenLength)
|
||||||
yylvalpp->symbol_name[len++] = ch;
|
yylvalpp->name[len++] = ch;
|
||||||
uint = 1;
|
uint = 1;
|
||||||
} else
|
} else
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
|
pp->currentInput->ungetch(pp, pp->currentInput, ch, yylvalpp);
|
||||||
|
|
||||||
yylvalpp->symbol_name[len] = '\0';
|
yylvalpp->name[len] = '\0';
|
||||||
ival = 0;
|
ival = 0;
|
||||||
for (ii = 0; ii < numericLen; ii++) {
|
for (ii = 0; ii < numericLen; ii++) {
|
||||||
ch = yylvalpp->symbol_name[ii] - '0';
|
ch = yylvalpp->name[ii] - '0';
|
||||||
if ((ival > 429496729) || (ival == 429496729 && ch >= 6)) {
|
if ((ival > 429496729) || (ival == 429496729 && ch >= 6)) {
|
||||||
ShPpErrorToInfoLog("integral literal too big");
|
pp->parseContext.error(yylvalpp->loc,"numeric literal too big", "", "");
|
||||||
ival = -1;
|
ival = -1;
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
ival = ival * 10 + ch;
|
ival = ival * 10 + ch;
|
||||||
}
|
}
|
||||||
yylvalpp->sc_int = (int)ival;
|
yylvalpp->ival = (int)ival;
|
||||||
|
|
||||||
if (uint)
|
if (uint)
|
||||||
return CPP_UINTCONSTANT;
|
return CPP_UINTCONSTANT;
|
||||||
@@ -553,112 +517,112 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if (ch == '-') {
|
if (ch == '-') {
|
||||||
return CPP_DEC_OP;
|
return CPP_DEC_OP;
|
||||||
} else if (ch == '=') {
|
} else if (ch == '=') {
|
||||||
return CPP_SUB_ASSIGN;
|
return CPP_SUB_ASSIGN;
|
||||||
} else {
|
} else {
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
|
pp->currentInput->ungetch(pp, pp->currentInput, ch, yylvalpp);
|
||||||
return '-';
|
return '-';
|
||||||
}
|
}
|
||||||
case '+':
|
case '+':
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if (ch == '+') {
|
if (ch == '+') {
|
||||||
return CPP_INC_OP;
|
return CPP_INC_OP;
|
||||||
} else if (ch == '=') {
|
} else if (ch == '=') {
|
||||||
return CPP_ADD_ASSIGN;
|
return CPP_ADD_ASSIGN;
|
||||||
} else {
|
} else {
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
|
pp->currentInput->ungetch(pp, pp->currentInput, ch, yylvalpp);
|
||||||
return '+';
|
return '+';
|
||||||
}
|
}
|
||||||
case '*':
|
case '*':
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if (ch == '=') {
|
if (ch == '=') {
|
||||||
return CPP_MUL_ASSIGN;
|
return CPP_MUL_ASSIGN;
|
||||||
} else {
|
} else {
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
|
pp->currentInput->ungetch(pp, pp->currentInput, ch, yylvalpp);
|
||||||
return '*';
|
return '*';
|
||||||
}
|
}
|
||||||
case '%':
|
case '%':
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if (ch == '=') {
|
if (ch == '=') {
|
||||||
return CPP_MOD_ASSIGN;
|
return CPP_MOD_ASSIGN;
|
||||||
} else if (ch == '>'){
|
} else if (ch == '>'){
|
||||||
return CPP_RIGHT_BRACE;
|
return CPP_RIGHT_BRACE;
|
||||||
} else {
|
} else {
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
|
pp->currentInput->ungetch(pp, pp->currentInput, ch, yylvalpp);
|
||||||
return '%';
|
return '%';
|
||||||
}
|
}
|
||||||
case ':':
|
case ':':
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if (ch == '>') {
|
if (ch == '>') {
|
||||||
return CPP_RIGHT_BRACKET;
|
return CPP_RIGHT_BRACKET;
|
||||||
} else {
|
} else {
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
|
pp->currentInput->ungetch(pp, pp->currentInput, ch, yylvalpp);
|
||||||
return ':';
|
return ':';
|
||||||
}
|
}
|
||||||
case '^':
|
case '^':
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if (ch == '^') {
|
if (ch == '^') {
|
||||||
return CPP_XOR_OP;
|
return CPP_XOR_OP;
|
||||||
} else {
|
} else {
|
||||||
if (ch == '=')
|
if (ch == '=')
|
||||||
return CPP_XOR_ASSIGN;
|
return CPP_XOR_ASSIGN;
|
||||||
else{
|
else{
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
|
pp->currentInput->ungetch(pp, pp->currentInput, ch, yylvalpp);
|
||||||
return '^';
|
return '^';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case '=':
|
case '=':
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if (ch == '=') {
|
if (ch == '=') {
|
||||||
return CPP_EQ_OP;
|
return CPP_EQ_OP;
|
||||||
} else {
|
} else {
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
|
pp->currentInput->ungetch(pp, pp->currentInput, ch, yylvalpp);
|
||||||
return '=';
|
return '=';
|
||||||
}
|
}
|
||||||
case '!':
|
case '!':
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if (ch == '=') {
|
if (ch == '=') {
|
||||||
return CPP_NE_OP;
|
return CPP_NE_OP;
|
||||||
} else {
|
} else {
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
|
pp->currentInput->ungetch(pp, pp->currentInput, ch, yylvalpp);
|
||||||
return '!';
|
return '!';
|
||||||
}
|
}
|
||||||
case '|':
|
case '|':
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if (ch == '|') {
|
if (ch == '|') {
|
||||||
return CPP_OR_OP;
|
return CPP_OR_OP;
|
||||||
} else {
|
} else {
|
||||||
if (ch == '=')
|
if (ch == '=')
|
||||||
return CPP_OR_ASSIGN;
|
return CPP_OR_ASSIGN;
|
||||||
else{
|
else{
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
|
pp->currentInput->ungetch(pp, pp->currentInput, ch, yylvalpp);
|
||||||
return '|';
|
return '|';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case '&':
|
case '&':
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if (ch == '&') {
|
if (ch == '&') {
|
||||||
return CPP_AND_OP;
|
return CPP_AND_OP;
|
||||||
} else {
|
} else {
|
||||||
if (ch == '=')
|
if (ch == '=')
|
||||||
return CPP_AND_ASSIGN;
|
return CPP_AND_ASSIGN;
|
||||||
else{
|
else{
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
|
pp->currentInput->ungetch(pp, pp->currentInput, ch, yylvalpp);
|
||||||
return '&';
|
return '&';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case '<':
|
case '<':
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if (ch == '<') {
|
if (ch == '<') {
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if(ch == '=')
|
if (ch == '=')
|
||||||
return CPP_LEFT_ASSIGN;
|
return CPP_LEFT_ASSIGN;
|
||||||
else{
|
else{
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
|
pp->currentInput->ungetch(pp, pp->currentInput, ch, yylvalpp);
|
||||||
return CPP_LEFT_OP;
|
return CPP_LEFT_OP;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -670,159 +634,161 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
|
|||||||
else if (ch == ':')
|
else if (ch == ':')
|
||||||
return CPP_LEFT_BRACKET;
|
return CPP_LEFT_BRACKET;
|
||||||
else{
|
else{
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
|
pp->currentInput->ungetch(pp, pp->currentInput, ch, yylvalpp);
|
||||||
return '<';
|
return '<';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case '>':
|
case '>':
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if (ch == '>') {
|
if (ch == '>') {
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if(ch == '=')
|
if (ch == '=')
|
||||||
return CPP_RIGHT_ASSIGN;
|
return CPP_RIGHT_ASSIGN;
|
||||||
else{
|
else{
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
|
pp->currentInput->ungetch(pp, pp->currentInput, ch, yylvalpp);
|
||||||
return CPP_RIGHT_OP;
|
return CPP_RIGHT_OP;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (ch == '=') {
|
if (ch == '=') {
|
||||||
return CPP_GE_OP;
|
return CPP_GE_OP;
|
||||||
} else {
|
} else {
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
|
pp->currentInput->ungetch(pp, pp->currentInput, ch, yylvalpp);
|
||||||
return '>';
|
return '>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case '.':
|
case '.':
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if (ch >= '0' && ch <= '9') {
|
if (ch >= '0' && ch <= '9') {
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
|
pp->currentInput->ungetch(pp, pp->currentInput, ch, yylvalpp);
|
||||||
return lFloatConst(yylvalpp->symbol_name, 0, '.', yylvalpp);
|
return pp->lFloatConst(yylvalpp->name, 0, '.', yylvalpp);
|
||||||
} else {
|
} else {
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
|
pp->currentInput->ungetch(pp, pp->currentInput, ch, yylvalpp);
|
||||||
return '.';
|
return '.';
|
||||||
}
|
}
|
||||||
case '/':
|
case '/':
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if (ch == '/') {
|
if (ch == '/') {
|
||||||
do {
|
do {
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if (ch == '\\') {
|
if (ch == '\\') {
|
||||||
// allow an escaped newline, otherwise escapes in comments are meaningless
|
// allow an escaped newline, otherwise escapes in comments are meaningless
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if (ch == '\r' || ch == '\n') {
|
if (ch == '\r' || ch == '\n') {
|
||||||
int nextch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
int nextch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if (ch == '\r' && nextch == '\n')
|
if (ch == '\r' && nextch == '\n')
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
else
|
else
|
||||||
ch = nextch;
|
ch = nextch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (ch != '\n' && ch != EOF);
|
} while (ch != '\n' && ch != EOF);
|
||||||
if (ch == EOF)
|
if (ch == EOF)
|
||||||
return -1;
|
return EOF;
|
||||||
return '\n';
|
return '\n';
|
||||||
} else if (ch == '*') {
|
} else if (ch == '*') {
|
||||||
int nlcount = 0;
|
int nlcount = 0;
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
do {
|
do {
|
||||||
while (ch != '*') {
|
while (ch != '*') {
|
||||||
if (ch == '\n') nlcount++;
|
if (ch == '\n')
|
||||||
|
nlcount++;
|
||||||
if (ch == EOF) {
|
if (ch == EOF) {
|
||||||
ShPpErrorToInfoLog("EOF in comment");
|
pp->parseContext.error(yylvalpp->loc,"EOF in comment", "comment", "");
|
||||||
return -1;
|
|
||||||
|
return EOF;
|
||||||
}
|
}
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
}
|
}
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if (ch == EOF) {
|
if (ch == EOF) {
|
||||||
ShPpErrorToInfoLog("EOF in comment");
|
pp->parseContext.error(yylvalpp->loc,"EOF in comment", "comment", "");
|
||||||
return -1;
|
|
||||||
|
return EOF;
|
||||||
}
|
}
|
||||||
} while (ch != '/');
|
} while (ch != '/');
|
||||||
if (nlcount) {
|
if (nlcount)
|
||||||
return '\n';
|
return '\n';
|
||||||
}
|
|
||||||
// Go try it again...
|
// Go try it again...
|
||||||
} else if (ch == '=') {
|
} else if (ch == '=') {
|
||||||
return CPP_DIV_ASSIGN;
|
return CPP_DIV_ASSIGN;
|
||||||
} else {
|
} else {
|
||||||
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
|
pp->currentInput->ungetch(pp, pp->currentInput, ch, yylvalpp);
|
||||||
return '/';
|
return '/';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '"':
|
case '"':
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
while (ch != '"' && ch != '\n' && ch != EOF) {
|
while (ch != '"' && ch != '\n' && ch != EOF) {
|
||||||
if (ch == '\\') {
|
if (ch == '\\') {
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
if (ch == '\n' || ch == EOF) {
|
if (ch == '\n' || ch == EOF) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (len < MAX_TOKEN_LENGTH) {
|
if (len < TPpToken::maxTokenLength) {
|
||||||
tokenText[len] = ch;
|
tokenText[len] = ch;
|
||||||
len++;
|
len++;
|
||||||
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
|
ch = pp->currentInput->getch(pp, pp->currentInput, yylvalpp);
|
||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
tokenText[len] = '\0';
|
tokenText[len] = '\0';
|
||||||
if (ch == '"') {
|
if (ch == '"') {
|
||||||
yylvalpp->sc_ident = LookUpAddString(atable, tokenText);
|
yylvalpp->atom = pp->LookUpAddString(&pp->atomTable, tokenText);
|
||||||
return CPP_STRCONSTANT;
|
return CPP_STRCONSTANT;
|
||||||
} else {
|
} else {
|
||||||
ShPpErrorToInfoLog("end of line in string");
|
pp->parseContext.error(yylvalpp->loc,"end of line in string", "string", "");
|
||||||
return CPP_ERROR_SY;
|
return CPP_ERROR_SY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // byte_scan
|
} // byte_scan
|
||||||
|
|
||||||
const char* PpTokenize(yystypepp* yylvalpp)
|
const char* TPpContext::tokenize(TPpToken* yylvalpp)
|
||||||
{
|
{
|
||||||
int token = '\n';
|
int token = '\n';
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
|
|
||||||
char* tokenString = 0;
|
char* tokenString = 0;
|
||||||
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
|
token = currentInput->scan(this, currentInput, yylvalpp);
|
||||||
yylvalpp->ppToken = token;
|
yylvalpp->ppToken = token;
|
||||||
if (check_EOF(token))
|
if (check_EOF(token))
|
||||||
return 0;
|
return 0;
|
||||||
if (token == '#') {
|
if (token == '#') {
|
||||||
if (cpp->previous_token == '\n'|| cpp->previous_token == 0) {
|
if (previous_token == '\n' || previous_token == 0) {
|
||||||
token = readCPPline(yylvalpp);
|
token = readCPPline(yylvalpp);
|
||||||
if(check_EOF(token))
|
if (check_EOF(token))
|
||||||
return 0;
|
return 0;
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
ShPpErrorToInfoLog("preprocessor directive cannot be preceded by another token");
|
parseContext.error(yylvalpp->loc,"preprocessor directive cannot be preceded by another token", "#", "");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cpp->previous_token = token;
|
previous_token = token;
|
||||||
|
|
||||||
if (token == '\n')
|
if (token == '\n')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
cpp->notAVersionToken = 1;
|
notAVersionToken = true;
|
||||||
|
|
||||||
// expand macros
|
// expand macros
|
||||||
if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp->sc_ident, yylvalpp, 0) == 1)
|
if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp->atom, yylvalpp, 0) == 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (token == CPP_IDENTIFIER)
|
if (token == CPP_IDENTIFIER)
|
||||||
tokenString = GetStringOfAtom(atable, yylvalpp->sc_ident);
|
tokenString = GetStringOfAtom(&atomTable, yylvalpp->atom);
|
||||||
else if (token == CPP_INTCONSTANT || token == CPP_UINTCONSTANT ||
|
else if (token == CPP_INTCONSTANT || token == CPP_UINTCONSTANT ||
|
||||||
token == CPP_FLOATCONSTANT || token == CPP_DOUBLECONSTANT)
|
token == CPP_FLOATCONSTANT || token == CPP_DOUBLECONSTANT)
|
||||||
tokenString = yylvalpp->symbol_name;
|
tokenString = yylvalpp->name;
|
||||||
else
|
else
|
||||||
tokenString = GetStringOfAtom(atable, token);
|
tokenString = GetStringOfAtom(&atomTable, token);
|
||||||
|
|
||||||
if (tokenString) {
|
if (tokenString) {
|
||||||
if (tokenString[0] != 0)
|
if (tokenString[0] != 0)
|
||||||
cpp->tokensBeforeEOF = 1;
|
parseContext.tokensBeforeEOF = 1;
|
||||||
|
|
||||||
return tokenString;
|
return tokenString;
|
||||||
}
|
}
|
||||||
@@ -832,13 +798,11 @@ const char* PpTokenize(yystypepp* yylvalpp)
|
|||||||
} // PpTokenize
|
} // PpTokenize
|
||||||
|
|
||||||
//Checks if the token just read is EOF or not.
|
//Checks if the token just read is EOF or not.
|
||||||
int check_EOF(int token)
|
int TPpContext::check_EOF(int token)
|
||||||
{
|
{
|
||||||
if(token==-1){
|
if (token == EOF) {
|
||||||
if(cpp->ifdepth >0){
|
if (ifdepth > 0)
|
||||||
ShPpErrorToInfoLog("missing #endif");
|
parseContext.error(parseContext.currentLoc, "missing #endif", "#if", "");
|
||||||
cpp->CompileError=1;
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
|
//Copyright (C) 2013 LunarG, Inc.
|
||||||
//All rights reserved.
|
//All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
//Redistribution and use in source and binary forms, with or without
|
||||||
@@ -83,32 +84,29 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "slglobals.h"
|
#include "PpContext.h"
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/////////////////////////////////// Symbol Table Variables: ///////////////////////////////////
|
/////////////////////////////////// Symbol Table Variables: ///////////////////////////////////
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Scope *ScopeList = NULL;
|
static void unlinkScope(void *_scope, void* scopeList)
|
||||||
Scope *CurrentScope = NULL;
|
{
|
||||||
Scope *GlobalScope = NULL;
|
TPpContext::Scope *scope = (TPpContext::Scope*)_scope;
|
||||||
|
|
||||||
static void unlinkScope(void *_scope) {
|
|
||||||
Scope *scope = (Scope*)_scope;
|
|
||||||
|
|
||||||
if (scope->next)
|
if (scope->next)
|
||||||
scope->next->prev = scope->prev;
|
scope->next->prev = scope->prev;
|
||||||
if (scope->prev)
|
if (scope->prev)
|
||||||
scope->prev->next = scope->next;
|
scope->prev->next = scope->next;
|
||||||
else
|
else
|
||||||
ScopeList = scope->next;
|
*(TPpContext::Scope**)scopeList = scope->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NewScope()
|
* NewScope()
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
Scope *NewScopeInPool(MemoryPool *pool)
|
TPpContext::Scope* TPpContext::NewScopeInPool(MemoryPool *pool)
|
||||||
{
|
{
|
||||||
Scope *lScope;
|
Scope *lScope;
|
||||||
|
|
||||||
@@ -125,16 +123,17 @@ Scope *NewScopeInPool(MemoryPool *pool)
|
|||||||
ScopeList->prev = lScope;
|
ScopeList->prev = lScope;
|
||||||
lScope->prev = 0;
|
lScope->prev = 0;
|
||||||
ScopeList = lScope;
|
ScopeList = lScope;
|
||||||
mem_AddCleanup(pool, unlinkScope, lScope);
|
mem_AddCleanup(pool, unlinkScope, lScope, &ScopeList);
|
||||||
|
|
||||||
return lScope;
|
return lScope;
|
||||||
} // NewScope
|
} // NewScope
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PushScope()
|
* PushScope()
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void PushScope(Scope *fScope)
|
void TPpContext::PushScope(Scope *fScope)
|
||||||
{
|
{
|
||||||
Scope *lScope;
|
Scope *lScope;
|
||||||
|
|
||||||
@@ -163,11 +162,11 @@ void PushScope(Scope *fScope)
|
|||||||
} // PushScope
|
} // PushScope
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PopScope()
|
* PopScope()
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Scope *PopScope(void)
|
TPpContext::Scope* TPpContext::PopScope(void)
|
||||||
{
|
{
|
||||||
Scope *lScope;
|
Scope *lScope;
|
||||||
|
|
||||||
@@ -178,11 +177,11 @@ Scope *PopScope(void)
|
|||||||
} // PopScope
|
} // PopScope
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NewSymbol() - Allocate a new symbol node;
|
* NewSymbol() - Allocate a new symbol node;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Symbol *NewSymbol(SourceLoc *loc, Scope *fScope, int name, symbolkind kind)
|
TPpContext::Symbol* TPpContext::NewSymbol(TSourceLoc *loc, Scope *fScope, int name, symbolkind kind)
|
||||||
{
|
{
|
||||||
Symbol *lSymb;
|
Symbol *lSymb;
|
||||||
char *pch;
|
char *pch;
|
||||||
@@ -205,13 +204,13 @@ Symbol *NewSymbol(SourceLoc *loc, Scope *fScope, int name, symbolkind kind)
|
|||||||
} // NewSymbol
|
} // NewSymbol
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* lAddToTree() - Using a binary tree is not a good idea for basic atom values because they
|
* lAddToTree() - Using a binary tree is not a good idea for basic atom values because they
|
||||||
* are generated in order. We'll fix this later (by reversing the bit pattern).
|
* are generated in order. We'll fix this later (by reversing the bit pattern).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void lAddToTree(Symbol **fSymbols, Symbol *fSymb)
|
void TPpContext::lAddToTree(Symbol **fSymbols, Symbol *fSymb, AtomTable *atable)
|
||||||
{
|
{
|
||||||
Symbol *lSymb;
|
TPpContext::Symbol *lSymb;
|
||||||
int lrev, frev;
|
int lrev, frev;
|
||||||
|
|
||||||
lSymb = *fSymbols;
|
lSymb = *fSymbols;
|
||||||
@@ -220,7 +219,7 @@ static void lAddToTree(Symbol **fSymbols, Symbol *fSymb)
|
|||||||
while (lSymb) {
|
while (lSymb) {
|
||||||
lrev = GetReversedAtom(atable, lSymb->name);
|
lrev = GetReversedAtom(atable, lSymb->name);
|
||||||
if (lrev == frev) {
|
if (lrev == frev) {
|
||||||
ShPpErrorToInfoLog("GetAtomString(atable, fSymb->name)");
|
printf("GetAtomString(atable, fSymb->name)");
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if (lrev > frev) {
|
if (lrev > frev) {
|
||||||
@@ -247,18 +246,18 @@ static void lAddToTree(Symbol **fSymbols, Symbol *fSymb)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AddSymbol() - Add a variable, type, or function name to a scope.
|
* AddSymbol() - Add a variable, type, or function name to a scope.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Symbol *AddSymbol(SourceLoc *loc, Scope *fScope, int atom, symbolkind kind)
|
TPpContext::Symbol* TPpContext::AddSymbol(TSourceLoc *loc, Scope *fScope, int atom, symbolkind kind)
|
||||||
{
|
{
|
||||||
Symbol *lSymb;
|
Symbol *lSymb;
|
||||||
|
|
||||||
if (!fScope)
|
if (!fScope)
|
||||||
fScope = CurrentScope;
|
fScope = CurrentScope;
|
||||||
lSymb = NewSymbol(loc, fScope, atom, kind);
|
lSymb = NewSymbol(loc, fScope, atom, kind);
|
||||||
lAddToTree(&fScope->symbols, lSymb);
|
lAddToTree(&fScope->symbols, lSymb, &atomTable);
|
||||||
return lSymb;
|
return lSymb;
|
||||||
} // AddSymbol
|
} // AddSymbol
|
||||||
|
|
||||||
@@ -268,21 +267,21 @@ Symbol *AddSymbol(SourceLoc *loc, Scope *fScope, int atom, symbolkind kind)
|
|||||||
/*********************************************************************************************/
|
/*********************************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LookUpLocalSymbol()
|
* LookUpLocalSymbol()
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Symbol *LookUpLocalSymbol(Scope *fScope, int atom)
|
TPpContext::Symbol* TPpContext::LookUpLocalSymbol(Scope *fScope, int atom)
|
||||||
{
|
{
|
||||||
Symbol *lSymb;
|
Symbol *lSymb;
|
||||||
int rname, ratom;
|
int rname, ratom;
|
||||||
|
|
||||||
ratom = GetReversedAtom(atable, atom);
|
ratom = GetReversedAtom(&atomTable, atom);
|
||||||
if (!fScope)
|
if (!fScope)
|
||||||
fScope = CurrentScope;
|
fScope = CurrentScope;
|
||||||
lSymb = fScope->symbols;
|
lSymb = fScope->symbols;
|
||||||
while (lSymb) {
|
while (lSymb) {
|
||||||
rname = GetReversedAtom(atable, lSymb->name);
|
rname = GetReversedAtom(&atomTable, lSymb->name);
|
||||||
if (rname == ratom) {
|
if (rname == ratom) {
|
||||||
return lSymb;
|
return lSymb;
|
||||||
} else {
|
} else {
|
||||||
@@ -297,11 +296,11 @@ Symbol *LookUpLocalSymbol(Scope *fScope, int atom)
|
|||||||
} // LookUpLocalSymbol
|
} // LookUpLocalSymbol
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LookUpSymbol()
|
* LookUpSymbol()
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Symbol *LookUpSymbol(Scope *fScope, int atom)
|
TPpContext::Symbol* TPpContext::LookUpSymbol(Scope *fScope, int atom)
|
||||||
{
|
{
|
||||||
Symbol *lSymb;
|
Symbol *lSymb;
|
||||||
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
|
//Copyright (C) 2013 LunarG, Inc.
|
||||||
//All rights reserved.
|
//All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
//Redistribution and use in source and binary forms, with or without
|
||||||
@@ -78,8 +79,8 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
// tokens.c
|
// tokens.c
|
||||||
//
|
//
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
#define snprintf sprintf_s
|
#define snprintf sprintf_s
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@@ -88,20 +89,21 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "slglobals.h"
|
#include "PpContext.h"
|
||||||
|
#include "PpTokens.h"
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
//////////////////////// Preprocessor and Token Recorder and Playback: ////////////////////////
|
//////////////////////// Preprocessor and Token Recorder and Playback: ////////////////////////
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* idstr()
|
* idstr()
|
||||||
* Copy a string to a malloc'ed block and convert it into something suitable
|
* Copy a string to a malloc'ed block and convert it into something suitable
|
||||||
* for an ID
|
* for an ID
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static char *idstr(const char *fstr, MemoryPool *pool)
|
char* TPpContext::idstr(const char *fstr, MemoryPool *pool)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
char *str, *t;
|
char *str, *t;
|
||||||
@@ -123,11 +125,11 @@ static char *idstr(const char *fstr, MemoryPool *pool)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* lNewBlock()
|
* lNewBlock()
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static TokenBlock *lNewBlock(TokenStream *fTok, MemoryPool *pool)
|
TPpContext::TokenBlock* TPpContext::lNewBlock(TokenStream *fTok, MemoryPool *pool)
|
||||||
{
|
{
|
||||||
TokenBlock *lBlock;
|
TokenBlock *lBlock;
|
||||||
|
|
||||||
@@ -146,15 +148,16 @@ static TokenBlock *lNewBlock(TokenStream *fTok, MemoryPool *pool)
|
|||||||
fTok->head = lBlock;
|
fTok->head = lBlock;
|
||||||
}
|
}
|
||||||
fTok->current = lBlock;
|
fTok->current = lBlock;
|
||||||
|
|
||||||
return lBlock;
|
return lBlock;
|
||||||
} // lNewBlock
|
} // lNewBlock
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* lAddByte()
|
* lAddByte()
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void lAddByte(TokenStream *fTok, unsigned char fVal)
|
void TPpContext::lAddByte(TokenStream *fTok, unsigned char fVal)
|
||||||
{
|
{
|
||||||
TokenBlock *lBlock;
|
TokenBlock *lBlock;
|
||||||
lBlock = fTok->current;
|
lBlock = fTok->current;
|
||||||
@@ -164,13 +167,12 @@ static void lAddByte(TokenStream *fTok, unsigned char fVal)
|
|||||||
} // lAddByte
|
} // lAddByte
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* lReadByte() - Get the next byte from a stream.
|
* lReadByte() - Get the next byte from a stream.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int lReadByte(TokenStream *pTok)
|
int TPpContext::lReadByte(TokenStream *pTok)
|
||||||
{
|
{
|
||||||
TokenBlock *lBlock;
|
TokenBlock *lBlock;
|
||||||
int lval = -1;
|
int lval = -1;
|
||||||
@@ -192,11 +194,11 @@ static int lReadByte(TokenStream *pTok)
|
|||||||
/////////////////////////////////////// Global Functions://////////////////////////////////////
|
/////////////////////////////////////// Global Functions://////////////////////////////////////
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NewTokenStream()
|
* NewTokenStream()
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TokenStream *NewTokenStream(const char *name, MemoryPool *pool)
|
TPpContext::TokenStream* TPpContext::NewTokenStream(const char *name, MemoryPool *pool)
|
||||||
{
|
{
|
||||||
TokenStream *pTok;
|
TokenStream *pTok;
|
||||||
|
|
||||||
@@ -213,11 +215,11 @@ TokenStream *NewTokenStream(const char *name, MemoryPool *pool)
|
|||||||
} // NewTokenStream
|
} // NewTokenStream
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DeleteTokenStream()
|
* DeleteTokenStream()
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void DeleteTokenStream(TokenStream *pTok)
|
void TPpContext::DeleteTokenStream(TokenStream *pTok)
|
||||||
{
|
{
|
||||||
TokenBlock *pBlock, *nBlock;
|
TokenBlock *pBlock, *nBlock;
|
||||||
|
|
||||||
@@ -235,11 +237,11 @@ void DeleteTokenStream(TokenStream *pTok)
|
|||||||
} // DeleteTokenStream
|
} // DeleteTokenStream
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RecordToken() - Add a token to the end of a list for later playback or printout.
|
* RecordToken() - Add a token to the end of a list for later playback or printout.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void RecordToken(TokenStream *pTok, int token, yystypepp * yylvalpp)
|
void TPpContext::RecordToken(TokenStream *pTok, int token, TPpToken * yylvalpp)
|
||||||
{
|
{
|
||||||
const char *s;
|
const char *s;
|
||||||
char *str = NULL;
|
char *str = NULL;
|
||||||
@@ -252,7 +254,7 @@ void RecordToken(TokenStream *pTok, int token, yystypepp * yylvalpp)
|
|||||||
case CPP_IDENTIFIER:
|
case CPP_IDENTIFIER:
|
||||||
case CPP_TYPEIDENTIFIER:
|
case CPP_TYPEIDENTIFIER:
|
||||||
case CPP_STRCONSTANT:
|
case CPP_STRCONSTANT:
|
||||||
s = GetAtomString(atable, yylvalpp->sc_ident);
|
s = GetAtomString(&atomTable, yylvalpp->atom);
|
||||||
while (*s)
|
while (*s)
|
||||||
lAddByte(pTok, (unsigned char) *s++);
|
lAddByte(pTok, (unsigned char) *s++);
|
||||||
lAddByte(pTok, 0);
|
lAddByte(pTok, 0);
|
||||||
@@ -261,7 +263,7 @@ void RecordToken(TokenStream *pTok, int token, yystypepp * yylvalpp)
|
|||||||
case CPP_UINTCONSTANT:
|
case CPP_UINTCONSTANT:
|
||||||
case CPP_FLOATCONSTANT:
|
case CPP_FLOATCONSTANT:
|
||||||
case CPP_DOUBLECONSTANT:
|
case CPP_DOUBLECONSTANT:
|
||||||
str = yylvalpp->symbol_name;
|
str = yylvalpp->name;
|
||||||
while (*str){
|
while (*str){
|
||||||
lAddByte(pTok, (unsigned char) *str);
|
lAddByte(pTok, (unsigned char) *str);
|
||||||
str++;
|
str++;
|
||||||
@@ -269,18 +271,18 @@ void RecordToken(TokenStream *pTok, int token, yystypepp * yylvalpp)
|
|||||||
lAddByte(pTok, 0);
|
lAddByte(pTok, 0);
|
||||||
break;
|
break;
|
||||||
case '(':
|
case '(':
|
||||||
lAddByte(pTok, (unsigned char)(yylvalpp->sc_int ? 1 : 0));
|
lAddByte(pTok, (unsigned char)(yylvalpp->ival ? 1 : 0));
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} // RecordToken
|
} // RecordToken
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RewindTokenStream() - Reset a token stream in preperation for reading.
|
* RewindTokenStream() - Reset a token stream in preperation for reading.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void RewindTokenStream(TokenStream *pTok)
|
void TPpContext::RewindTokenStream(TokenStream *pTok)
|
||||||
{
|
{
|
||||||
if (pTok->head) {
|
if (pTok->head) {
|
||||||
pTok->current = pTok->head;
|
pTok->current = pTok->head;
|
||||||
@@ -289,19 +291,20 @@ void RewindTokenStream(TokenStream *pTok)
|
|||||||
} // RewindTokenStream
|
} // RewindTokenStream
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ReadToken() - Read the next token from a stream.
|
* ReadToken() - Read the next token from a stream.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
|
int TPpContext::ReadToken(TokenStream *pTok, TPpToken * yylvalpp)
|
||||||
{
|
{
|
||||||
//TODO: PP: why is this different than byte_scan
|
//TODO: PP: why is this different than byte_scan
|
||||||
|
|
||||||
char tokenText[MAX_TOKEN_LENGTH + 1];
|
char tokenText[TPpToken::maxTokenLength + 1];
|
||||||
int ltoken, len;
|
int ltoken, len;
|
||||||
char ch;
|
char ch;
|
||||||
|
|
||||||
ltoken = lReadByte(pTok);
|
ltoken = lReadByte(pTok);
|
||||||
|
yylvalpp->loc = parseContext.currentLoc;
|
||||||
if (ltoken >= 0) {
|
if (ltoken >= 0) {
|
||||||
if (ltoken > 127)
|
if (ltoken > 127)
|
||||||
ltoken += 128;
|
ltoken += 128;
|
||||||
@@ -315,31 +318,31 @@ int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
|
|||||||
(ch >= '0' && ch <= '9') ||
|
(ch >= '0' && ch <= '9') ||
|
||||||
ch == '_')
|
ch == '_')
|
||||||
{
|
{
|
||||||
if (len < MAX_TOKEN_LENGTH) {
|
if (len < TPpToken::maxTokenLength) {
|
||||||
tokenText[len] = ch;
|
tokenText[len] = ch;
|
||||||
len++;
|
len++;
|
||||||
ch = lReadByte(pTok);
|
ch = lReadByte(pTok);
|
||||||
} else {
|
} else {
|
||||||
ShPpErrorToInfoLog("token too long");
|
parseContext.error(yylvalpp->loc,"name too long", "", "");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tokenText[len] = '\0';
|
tokenText[len] = '\0';
|
||||||
assert(ch == '\0');
|
assert(ch == '\0');
|
||||||
yylvalpp->sc_ident = LookUpAddString(atable, tokenText);
|
yylvalpp->atom = LookUpAddString(&atomTable, tokenText);
|
||||||
return CPP_IDENTIFIER;
|
return CPP_IDENTIFIER;
|
||||||
break;
|
break;
|
||||||
case CPP_STRCONSTANT:
|
case CPP_STRCONSTANT:
|
||||||
len = 0;
|
len = 0;
|
||||||
while ((ch = lReadByte(pTok)) != 0) {
|
while ((ch = lReadByte(pTok)) != 0) {
|
||||||
if (len < MAX_TOKEN_LENGTH)
|
if (len < TPpToken::maxTokenLength)
|
||||||
tokenText[len++] = ch;
|
tokenText[len++] = ch;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tokenText[len] = 0;
|
tokenText[len] = 0;
|
||||||
yylvalpp->sc_ident = LookUpAddString(atable, tokenText);
|
yylvalpp->atom = LookUpAddString(&atomTable, tokenText);
|
||||||
break;
|
break;
|
||||||
case CPP_FLOATCONSTANT:
|
case CPP_FLOATCONSTANT:
|
||||||
case CPP_DOUBLECONSTANT:
|
case CPP_DOUBLECONSTANT:
|
||||||
@@ -347,19 +350,19 @@ int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
|
|||||||
ch = lReadByte(pTok);
|
ch = lReadByte(pTok);
|
||||||
while ((ch >= '0' && ch <= '9') || ch=='e' || ch=='E' || ch=='.' || ch=='+' || ch=='-' || ch=='l' || ch=='L' || ch=='f'|| ch=='F')
|
while ((ch >= '0' && ch <= '9') || ch=='e' || ch=='E' || ch=='.' || ch=='+' || ch=='-' || ch=='l' || ch=='L' || ch=='f'|| ch=='F')
|
||||||
{
|
{
|
||||||
if (len < MAX_TOKEN_LENGTH) {
|
if (len < TPpToken::maxTokenLength) {
|
||||||
tokenText[len] = ch;
|
tokenText[len] = ch;
|
||||||
len++;
|
len++;
|
||||||
ch = lReadByte(pTok);
|
ch = lReadByte(pTok);
|
||||||
} else {
|
} else {
|
||||||
ShPpErrorToInfoLog("token too long");
|
parseContext.error(yylvalpp->loc,"float literal too long", "", "");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tokenText[len] = '\0';
|
tokenText[len] = '\0';
|
||||||
assert(ch == '\0');
|
assert(ch == '\0');
|
||||||
strcpy(yylvalpp->symbol_name, tokenText);
|
strcpy(yylvalpp->name, tokenText);
|
||||||
yylvalpp->sc_dval = atof(yylvalpp->symbol_name);
|
yylvalpp->dval = atof(yylvalpp->name);
|
||||||
break;
|
break;
|
||||||
case CPP_INTCONSTANT:
|
case CPP_INTCONSTANT:
|
||||||
case CPP_UINTCONSTANT:
|
case CPP_UINTCONSTANT:
|
||||||
@@ -367,102 +370,94 @@ int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
|
|||||||
ch = lReadByte(pTok);
|
ch = lReadByte(pTok);
|
||||||
while ((ch >= '0' && ch <= '9') || ch == 'u' || ch == 'U')
|
while ((ch >= '0' && ch <= '9') || ch == 'u' || ch == 'U')
|
||||||
{
|
{
|
||||||
if (len < MAX_TOKEN_LENGTH) {
|
if (len < TPpToken::maxTokenLength) {
|
||||||
tokenText[len] = ch;
|
tokenText[len] = ch;
|
||||||
len++;
|
len++;
|
||||||
ch = lReadByte(pTok);
|
ch = lReadByte(pTok);
|
||||||
} else {
|
} else {
|
||||||
ShPpErrorToInfoLog("token too long");
|
parseContext.error(yylvalpp->loc,"integer literal too long", "", "");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tokenText[len] = '\0';
|
tokenText[len] = '\0';
|
||||||
assert(ch == '\0');
|
assert(ch == '\0');
|
||||||
strcpy(yylvalpp->symbol_name,tokenText);
|
strcpy(yylvalpp->name,tokenText);
|
||||||
yylvalpp->sc_int = atoi(yylvalpp->symbol_name);
|
yylvalpp->ival = atoi(yylvalpp->name);
|
||||||
break;
|
break;
|
||||||
case '(':
|
case '(':
|
||||||
yylvalpp->sc_int = lReadByte(pTok);
|
yylvalpp->ival = lReadByte(pTok);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return ltoken;
|
return ltoken;
|
||||||
}
|
}
|
||||||
return EOF_SY;
|
return EOF;
|
||||||
} // ReadToken
|
} // ReadToken
|
||||||
|
|
||||||
typedef struct TokenInputSrc {
|
int TPpContext::scan_token(TPpContext* pp, TokenInputSrc *in, TPpToken * yylvalpp)
|
||||||
InputSrc base;
|
|
||||||
TokenStream *tokens;
|
|
||||||
int (*final)(CPPStruct *);
|
|
||||||
} TokenInputSrc;
|
|
||||||
|
|
||||||
static int scan_token(TokenInputSrc *in, yystypepp * yylvalpp)
|
|
||||||
{
|
{
|
||||||
int token = ReadToken(in->tokens, yylvalpp);
|
int token = pp->ReadToken(in->tokens, yylvalpp);
|
||||||
int (*final)(CPPStruct *);
|
int (*final)(TPpContext *);
|
||||||
cpp->tokenLoc->file = cpp->currentInput->name;
|
yylvalpp->loc.string = pp->currentInput->name;
|
||||||
cpp->tokenLoc->line = cpp->currentInput->line;
|
yylvalpp->loc.line = pp->currentInput->line;
|
||||||
if (token == '\n') {
|
if (token == '\n') {
|
||||||
in->base.line++;
|
in->base.line++;
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
if (token > 0) return token;
|
if (token > 0)
|
||||||
cpp->currentInput = in->base.prev;
|
return token;
|
||||||
|
pp->currentInput = in->base.prev;
|
||||||
final = in->final;
|
final = in->final;
|
||||||
free(in);
|
free(in);
|
||||||
if (final && !final(cpp)) return -1;
|
if (final && !final(pp))
|
||||||
return cpp->currentInput->scan(cpp->currentInput, yylvalpp);
|
return -1;
|
||||||
|
|
||||||
|
return pp->currentInput->scan(pp, pp->currentInput, yylvalpp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ReadFromTokenStream(TokenStream *ts, int name, int (*final)(CPPStruct *))
|
int TPpContext::ReadFromTokenStream(TokenStream *ts, int name, int (*final)(TPpContext *))
|
||||||
{
|
{
|
||||||
TokenInputSrc *in = (TokenInputSrc *) malloc(sizeof(TokenInputSrc));
|
TokenInputSrc *in = (TokenInputSrc *) malloc(sizeof(TokenInputSrc));
|
||||||
memset(in, 0, sizeof(TokenInputSrc));
|
memset(in, 0, sizeof(TokenInputSrc));
|
||||||
in->base.name = name;
|
in->base.name = name;
|
||||||
in->base.prev = cpp->currentInput;
|
in->base.prev = currentInput;
|
||||||
in->base.scan = (int (*)(InputSrc *, yystypepp *))scan_token;
|
in->base.scan = (int (*)(TPpContext*, InputSrc*, TPpToken*))scan_token;
|
||||||
in->base.line = 1;
|
in->base.line = 1;
|
||||||
in->tokens = ts;
|
in->tokens = ts;
|
||||||
in->final = final;
|
in->final = final;
|
||||||
RewindTokenStream(ts);
|
RewindTokenStream(ts);
|
||||||
cpp->currentInput = &in->base;
|
currentInput = &in->base;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct UngotToken {
|
int TPpContext::reget_token(TPpContext* pp, UngotToken *t, TPpToken * yylvalpp)
|
||||||
InputSrc base;
|
|
||||||
int token;
|
|
||||||
yystypepp lval;
|
|
||||||
} UngotToken;
|
|
||||||
|
|
||||||
static int reget_token(UngotToken *t, yystypepp * yylvalpp)
|
|
||||||
{
|
{
|
||||||
int token = t->token;
|
int token = t->token;
|
||||||
*yylvalpp = t->lval;
|
*yylvalpp = t->lval;
|
||||||
cpp->currentInput = t->base.prev;
|
pp->currentInput = t->base.prev;
|
||||||
free(t);
|
free(t);
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef int (*scanFnPtr_t)(struct InputSrc *, yystypepp *);
|
typedef int (*scanFnPtr_t);
|
||||||
|
|
||||||
void UngetToken(int token, yystypepp * yylvalpp) {
|
void TPpContext::UngetToken(int token, TPpToken * yylvalpp)
|
||||||
|
{
|
||||||
UngotToken *t = (UngotToken *) malloc(sizeof(UngotToken));
|
UngotToken *t = (UngotToken *) malloc(sizeof(UngotToken));
|
||||||
memset(t, 0, sizeof(UngotToken));
|
memset(t, 0, sizeof(UngotToken));
|
||||||
t->token = token;
|
t->token = token;
|
||||||
t->lval = *yylvalpp;
|
t->lval = *yylvalpp;
|
||||||
t->base.scan = (scanFnPtr_t)reget_token;
|
t->base.scan = (int(*)(TPpContext*, struct InputSrc *, TPpToken *))reget_token;
|
||||||
t->base.prev = cpp->currentInput;
|
t->base.prev = currentInput;
|
||||||
t->base.name = cpp->currentInput->name;
|
t->base.name = currentInput->name;
|
||||||
t->base.line = cpp->currentInput->line;
|
t->base.line = currentInput->line;
|
||||||
cpp->currentInput = &t->base;
|
currentInput = &t->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DumpTokenStream(FILE *fp, TokenStream *s, yystypepp * yylvalpp) {
|
void TPpContext::DumpTokenStream(FILE *fp, TokenStream *s, TPpToken * yylvalpp)
|
||||||
|
{
|
||||||
int token;
|
int token;
|
||||||
const int maxSize = MAX_TOKEN_LENGTH + 5;
|
|
||||||
char str[100];
|
|
||||||
|
|
||||||
if (fp == 0) fp = stdout;
|
if (fp == 0) fp = stdout;
|
||||||
RewindTokenStream(s);
|
RewindTokenStream(s);
|
||||||
@@ -470,27 +465,26 @@ void DumpTokenStream(FILE *fp, TokenStream *s, yystypepp * yylvalpp) {
|
|||||||
switch (token) {
|
switch (token) {
|
||||||
case CPP_IDENTIFIER:
|
case CPP_IDENTIFIER:
|
||||||
case CPP_TYPEIDENTIFIER:
|
case CPP_TYPEIDENTIFIER:
|
||||||
snprintf(str, maxSize, "%s ", GetAtomString(atable, yylvalpp->sc_ident));
|
printf("%s ", GetAtomString(&atomTable, yylvalpp->atom));
|
||||||
break;
|
break;
|
||||||
case CPP_STRCONSTANT:
|
case CPP_STRCONSTANT:
|
||||||
snprintf(str, maxSize, "\"%s\"", GetAtomString(atable, yylvalpp->sc_ident));
|
printf("\"%s\"", GetAtomString(&atomTable, yylvalpp->atom));
|
||||||
break;
|
break;
|
||||||
case CPP_FLOATCONSTANT:
|
case CPP_FLOATCONSTANT:
|
||||||
case CPP_DOUBLECONSTANT:
|
case CPP_DOUBLECONSTANT:
|
||||||
printf("%g9.6 ", yylvalpp->sc_dval);
|
printf("%g9.6 ", yylvalpp->dval);
|
||||||
break;
|
break;
|
||||||
case CPP_INTCONSTANT:
|
case CPP_INTCONSTANT:
|
||||||
case CPP_UINTCONSTANT:
|
case CPP_UINTCONSTANT:
|
||||||
printf("%d ", yylvalpp->sc_int);
|
printf("%d ", yylvalpp->ival);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (token >= 127)
|
if (token >= 127)
|
||||||
snprintf(str, maxSize, "%s ", GetAtomString(atable, token));
|
printf("%s ", GetAtomString(&atomTable, token));
|
||||||
else
|
else
|
||||||
snprintf(str, maxSize, "%c", token);
|
printf("%c", token);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ShPpDebugLogMsg(str);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,41 +76,42 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
\****************************************************************************/
|
\****************************************************************************/
|
||||||
|
|
||||||
#ifndef PARSER_H
|
#ifndef PARSER_H
|
||||||
# define PARSER_H
|
#define PARSER_H
|
||||||
|
|
||||||
# define CPP_AND_OP 257
|
#define CPP_AND_OP 257
|
||||||
# define CPP_SUB_ASSIGN 259
|
#define CPP_SUB_ASSIGN 259
|
||||||
# define CPP_MOD_ASSIGN 260
|
#define CPP_MOD_ASSIGN 260
|
||||||
# define CPP_ADD_ASSIGN 261
|
#define CPP_ADD_ASSIGN 261
|
||||||
# define CPP_DIV_ASSIGN 262
|
#define CPP_DIV_ASSIGN 262
|
||||||
# define CPP_MUL_ASSIGN 263
|
#define CPP_MUL_ASSIGN 263
|
||||||
# define CPP_EQ_OP 264
|
#define CPP_EQ_OP 264
|
||||||
# define CPP_XOR_OP 265
|
#define CPP_XOR_OP 265
|
||||||
# define CPP_ERROR_SY 266
|
#define CPP_ERROR_SY 266
|
||||||
# define CPP_FLOATCONSTANT 267
|
#define CPP_FLOATCONSTANT 267
|
||||||
# define CPP_GE_OP 268
|
#define CPP_GE_OP 268
|
||||||
# define CPP_RIGHT_OP 269
|
#define CPP_RIGHT_OP 269
|
||||||
# define CPP_IDENTIFIER 270
|
#define CPP_IDENTIFIER 270
|
||||||
# define CPP_INTCONSTANT 271
|
#define CPP_INTCONSTANT 271
|
||||||
# define CPP_LE_OP 272
|
#define CPP_LE_OP 272
|
||||||
# define CPP_LEFT_OP 273
|
#define CPP_LEFT_OP 273
|
||||||
# define CPP_DEC_OP 274
|
#define CPP_DEC_OP 274
|
||||||
# define CPP_NE_OP 275
|
#define CPP_NE_OP 275
|
||||||
# define CPP_OR_OP 276
|
#define CPP_OR_OP 276
|
||||||
# define CPP_INC_OP 277
|
#define CPP_INC_OP 277
|
||||||
# define CPP_STRCONSTANT 278
|
#define CPP_STRCONSTANT 278
|
||||||
# define CPP_TYPEIDENTIFIER 279
|
#define CPP_TYPEIDENTIFIER 279
|
||||||
# define CPP_RIGHT_ASSIGN 280
|
#define CPP_RIGHT_ASSIGN 280
|
||||||
# define CPP_LEFT_ASSIGN 281
|
#define CPP_LEFT_ASSIGN 281
|
||||||
# define CPP_AND_ASSIGN 282
|
#define CPP_AND_ASSIGN 282
|
||||||
# define CPP_OR_ASSIGN 283
|
#define CPP_OR_ASSIGN 283
|
||||||
# define CPP_XOR_ASSIGN 284
|
#define CPP_XOR_ASSIGN 284
|
||||||
# define CPP_LEFT_BRACKET 285
|
#define CPP_LEFT_BRACKET 285
|
||||||
# define CPP_RIGHT_BRACKET 286
|
#define CPP_RIGHT_BRACKET 286
|
||||||
# define CPP_LEFT_BRACE 287
|
#define CPP_LEFT_BRACE 287
|
||||||
# define CPP_RIGHT_BRACE 288
|
#define CPP_RIGHT_BRACE 288
|
||||||
# define CPP_UINTCONSTANT 289
|
#define CPP_UINTCONSTANT 289
|
||||||
# define CPP_DOUBLECONSTANT 290
|
#define CPP_DOUBLECONSTANT 290
|
||||||
# define CPP_FIRST_USER_TOKEN_SY 291
|
|
||||||
|
#define CPP_FIRST_USER_TOKEN_SY 291
|
||||||
|
|
||||||
#endif /* not PARSER_H */
|
#endif /* not PARSER_H */
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
//
|
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
|
||||||
//All rights reserved.
|
|
||||||
//
|
|
||||||
//Redistribution and use in source and binary forms, with or without
|
|
||||||
//modification, are permitted provided that the following conditions
|
|
||||||
//are met:
|
|
||||||
//
|
|
||||||
// Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following
|
|
||||||
// disclaimer in the documentation and/or other materials provided
|
|
||||||
// with the distribution.
|
|
||||||
//
|
|
||||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived
|
|
||||||
// from this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
//
|
|
||||||
/****************************************************************************\
|
|
||||||
Copyright (c) 2002, NVIDIA Corporation.
|
|
||||||
|
|
||||||
NVIDIA Corporation("NVIDIA") supplies this software to you in
|
|
||||||
consideration of your agreement to the following terms, and your use,
|
|
||||||
installation, modification or redistribution of this NVIDIA software
|
|
||||||
constitutes acceptance of these terms. If you do not agree with these
|
|
||||||
terms, please do not use, install, modify or redistribute this NVIDIA
|
|
||||||
software.
|
|
||||||
|
|
||||||
In consideration of your agreement to abide by the following terms, and
|
|
||||||
subject to these terms, NVIDIA grants you a personal, non-exclusive
|
|
||||||
license, under NVIDIA's copyrights in this original NVIDIA software (the
|
|
||||||
"NVIDIA Software"), to use, reproduce, modify and redistribute the
|
|
||||||
NVIDIA Software, with or without modifications, in source and/or binary
|
|
||||||
forms; provided that if you redistribute the NVIDIA Software, you must
|
|
||||||
retain the copyright notice of NVIDIA, this notice and the following
|
|
||||||
text and disclaimers in all such redistributions of the NVIDIA Software.
|
|
||||||
Neither the name, trademarks, service marks nor logos of NVIDIA
|
|
||||||
Corporation may be used to endorse or promote products derived from the
|
|
||||||
NVIDIA Software without specific prior written permission from NVIDIA.
|
|
||||||
Except as expressly stated in this notice, no other rights or licenses
|
|
||||||
express or implied, are granted by NVIDIA herein, including but not
|
|
||||||
limited to any patent rights that may be infringed by your derivative
|
|
||||||
works or by other works in which the NVIDIA Software may be
|
|
||||||
incorporated. No hardware is licensed hereunder.
|
|
||||||
|
|
||||||
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
|
||||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
|
||||||
INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
|
|
||||||
NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
|
|
||||||
ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
|
|
||||||
PRODUCTS.
|
|
||||||
|
|
||||||
IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
|
|
||||||
INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
||||||
TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
|
||||||
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
|
|
||||||
OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
|
|
||||||
NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
|
|
||||||
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
|
|
||||||
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
\****************************************************************************/
|
|
||||||
//
|
|
||||||
// atom.h
|
|
||||||
//
|
|
||||||
|
|
||||||
#if !defined(__ATOM_H)
|
|
||||||
#define __ATOM_H 1
|
|
||||||
|
|
||||||
typedef struct AtomTable_Rec AtomTable;
|
|
||||||
|
|
||||||
extern AtomTable *atable;
|
|
||||||
|
|
||||||
int InitAtomTable(AtomTable *atable, int htsize);
|
|
||||||
void FreeAtomTable(AtomTable *atable);
|
|
||||||
int AddAtom(AtomTable *atable, const char *s);
|
|
||||||
void PrintAtomTable(AtomTable *atable);
|
|
||||||
int LookUpAddString(AtomTable *atable, const char *s);
|
|
||||||
const char *GetAtomString(AtomTable *atable, int atom);
|
|
||||||
int GetReversedAtom(AtomTable *atable, int atom);
|
|
||||||
char* GetStringOfAtom(AtomTable *atable, int atom);
|
|
||||||
#endif // !defined(__ATOM_H)
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,128 +0,0 @@
|
|||||||
//
|
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
|
||||||
//All rights reserved.
|
|
||||||
//
|
|
||||||
//Redistribution and use in source and binary forms, with or without
|
|
||||||
//modification, are permitted provided that the following conditions
|
|
||||||
//are met:
|
|
||||||
//
|
|
||||||
// Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following
|
|
||||||
// disclaimer in the documentation and/or other materials provided
|
|
||||||
// with the distribution.
|
|
||||||
//
|
|
||||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived
|
|
||||||
// from this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
//
|
|
||||||
/****************************************************************************\
|
|
||||||
Copyright (c) 2002, NVIDIA Corporation.
|
|
||||||
|
|
||||||
NVIDIA Corporation("NVIDIA") supplies this software to you in
|
|
||||||
consideration of your agreement to the following terms, and your use,
|
|
||||||
installation, modification or redistribution of this NVIDIA software
|
|
||||||
constitutes acceptance of these terms. If you do not agree with these
|
|
||||||
terms, please do not use, install, modify or redistribute this NVIDIA
|
|
||||||
software.
|
|
||||||
|
|
||||||
In consideration of your agreement to abide by the following terms, and
|
|
||||||
subject to these terms, NVIDIA grants you a personal, non-exclusive
|
|
||||||
license, under NVIDIA's copyrights in this original NVIDIA software (the
|
|
||||||
"NVIDIA Software"), to use, reproduce, modify and redistribute the
|
|
||||||
NVIDIA Software, with or without modifications, in source and/or binary
|
|
||||||
forms; provided that if you redistribute the NVIDIA Software, you must
|
|
||||||
retain the copyright notice of NVIDIA, this notice and the following
|
|
||||||
text and disclaimers in all such redistributions of the NVIDIA Software.
|
|
||||||
Neither the name, trademarks, service marks nor logos of NVIDIA
|
|
||||||
Corporation may be used to endorse or promote products derived from the
|
|
||||||
NVIDIA Software without specific prior written permission from NVIDIA.
|
|
||||||
Except as expressly stated in this notice, no other rights or licenses
|
|
||||||
express or implied, are granted by NVIDIA herein, including but not
|
|
||||||
limited to any patent rights that may be infringed by your derivative
|
|
||||||
works or by other works in which the NVIDIA Software may be
|
|
||||||
incorporated. No hardware is licensed hereunder.
|
|
||||||
|
|
||||||
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
|
||||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
|
||||||
INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
|
|
||||||
NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
|
|
||||||
ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
|
|
||||||
PRODUCTS.
|
|
||||||
|
|
||||||
IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
|
|
||||||
INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
||||||
TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
|
||||||
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
|
|
||||||
OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
|
|
||||||
NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
|
|
||||||
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
|
|
||||||
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
\****************************************************************************/
|
|
||||||
//
|
|
||||||
// cpp.h
|
|
||||||
//
|
|
||||||
|
|
||||||
#if !defined(__CPP_H)
|
|
||||||
#define __CPP_H 1
|
|
||||||
|
|
||||||
#include "parser.h"
|
|
||||||
#include "tokens.h"
|
|
||||||
#include "Versions.h"
|
|
||||||
|
|
||||||
typedef struct MacroSymbol {
|
|
||||||
int argc;
|
|
||||||
int *args;
|
|
||||||
TokenStream *body;
|
|
||||||
unsigned busy:1;
|
|
||||||
unsigned undef:1;
|
|
||||||
} MacroSymbol;
|
|
||||||
|
|
||||||
int InitCPP(void);
|
|
||||||
int FinalCPP(void);
|
|
||||||
int readCPPline(yystypepp * yylvalpp);
|
|
||||||
int MacroExpand(int atom, yystypepp * yylvalpp, int expandUndef);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void ShPpDebugLogMsg(const char *msg); // Prints information into debug log
|
|
||||||
void ShPpErrorToInfoLog(const char*); // Store cpp Err Msg into Sh.Info.Log
|
|
||||||
void ShPpWarningToInfoLog(const char *msg); // Prints warning messages into info log
|
|
||||||
int ShPpMacrosMustBeDefinedError();
|
|
||||||
|
|
||||||
void HandlePragma(const char**, int numTokens); // #pragma directive container.
|
|
||||||
void ResetTString(void); // #error Message as TString.
|
|
||||||
void StoreStr(const char*); // Store the TString in Parse Context.
|
|
||||||
void SetLineNumber(int); // Set line number.
|
|
||||||
void SetStringNumber(int); // Set string number.
|
|
||||||
int GetLineNumber(void); // Get the current String Number.
|
|
||||||
int GetStringNumber(void); // Get the current String Number.
|
|
||||||
const char* GetStrfromTStr(void); // Convert TString to String.
|
|
||||||
void SetVersion(int);
|
|
||||||
int GetShaderVersion(void*);
|
|
||||||
void updateExtensionBehavior(const char* extName, const char* behavior);
|
|
||||||
int FreeCPP(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif // !(defined(__CPP_H)
|
|
||||||
@@ -1,183 +0,0 @@
|
|||||||
//
|
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
|
||||||
//All rights reserved.
|
|
||||||
//
|
|
||||||
//Redistribution and use in source and binary forms, with or without
|
|
||||||
//modification, are permitted provided that the following conditions
|
|
||||||
//are met:
|
|
||||||
//
|
|
||||||
// Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following
|
|
||||||
// disclaimer in the documentation and/or other materials provided
|
|
||||||
// with the distribution.
|
|
||||||
//
|
|
||||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived
|
|
||||||
// from this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
//
|
|
||||||
/****************************************************************************\
|
|
||||||
Copyright (c) 2002, NVIDIA Corporation.
|
|
||||||
|
|
||||||
NVIDIA Corporation("NVIDIA") supplies this software to you in
|
|
||||||
consideration of your agreement to the following terms, and your use,
|
|
||||||
installation, modification or redistribution of this NVIDIA software
|
|
||||||
constitutes acceptance of these terms. If you do not agree with these
|
|
||||||
terms, please do not use, install, modify or redistribute this NVIDIA
|
|
||||||
software.
|
|
||||||
|
|
||||||
In consideration of your agreement to abide by the following terms, and
|
|
||||||
subject to these terms, NVIDIA grants you a personal, non-exclusive
|
|
||||||
license, under NVIDIA's copyrights in this original NVIDIA software (the
|
|
||||||
"NVIDIA Software"), to use, reproduce, modify and redistribute the
|
|
||||||
NVIDIA Software, with or without modifications, in source and/or binary
|
|
||||||
forms; provided that if you redistribute the NVIDIA Software, you must
|
|
||||||
retain the copyright notice of NVIDIA, this notice and the following
|
|
||||||
text and disclaimers in all such redistributions of the NVIDIA Software.
|
|
||||||
Neither the name, trademarks, service marks nor logos of NVIDIA
|
|
||||||
Corporation may be used to endorse or promote products derived from the
|
|
||||||
NVIDIA Software without specific prior written permission from NVIDIA.
|
|
||||||
Except as expressly stated in this notice, no other rights or licenses
|
|
||||||
express or implied, are granted by NVIDIA herein, including but not
|
|
||||||
limited to any patent rights that may be infringed by your derivative
|
|
||||||
works or by other works in which the NVIDIA Software may be
|
|
||||||
incorporated. No hardware is licensed hereunder.
|
|
||||||
|
|
||||||
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
|
||||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
|
||||||
INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
|
|
||||||
NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
|
|
||||||
ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
|
|
||||||
PRODUCTS.
|
|
||||||
|
|
||||||
IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
|
|
||||||
INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
||||||
TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
|
||||||
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
|
|
||||||
OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
|
|
||||||
NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
|
|
||||||
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
|
|
||||||
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
\****************************************************************************/
|
|
||||||
//
|
|
||||||
// cppstruct.c
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "slglobals.h"
|
|
||||||
|
|
||||||
CPPStruct *cpp = NULL;
|
|
||||||
static int refCount = 0;
|
|
||||||
|
|
||||||
int ResetPreprocessor(void);
|
|
||||||
int FreeCPPStruct(void);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* InitCPPStruct() - Initilaize the CPP structure.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
int InitCPPStruct(void)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
cpp = (CPPStruct *) malloc(sizeof(CPPStruct));
|
|
||||||
if (cpp == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
refCount++;
|
|
||||||
|
|
||||||
// Initialize public members:
|
|
||||||
cpp->pLastSourceLoc = &cpp->lastSourceLoc;
|
|
||||||
|
|
||||||
p = (char *) &cpp->options;
|
|
||||||
len = sizeof(cpp->options);
|
|
||||||
while (--len >= 0)
|
|
||||||
p[len] = 0;
|
|
||||||
|
|
||||||
ResetPreprocessor();
|
|
||||||
return 1;
|
|
||||||
} // InitCPPStruct
|
|
||||||
|
|
||||||
int ResetPreprocessor(void)
|
|
||||||
{
|
|
||||||
// Initialize private members:
|
|
||||||
|
|
||||||
cpp->lastSourceLoc.file = 0;
|
|
||||||
cpp->lastSourceLoc.line = 0;
|
|
||||||
cpp->pC=0;
|
|
||||||
cpp->CompileError=0;
|
|
||||||
cpp->ifdepth=0;
|
|
||||||
for(cpp->elsetracker=0; cpp->elsetracker<64; cpp->elsetracker++)
|
|
||||||
cpp->elsedepth[cpp->elsetracker]=0;
|
|
||||||
cpp->elsetracker=0;
|
|
||||||
cpp->tokensBeforeEOF = 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Intializing the Preprocessor.
|
|
||||||
|
|
||||||
int InitPreprocessor(void)
|
|
||||||
{
|
|
||||||
# define CPP_STUFF true
|
|
||||||
# ifdef CPP_STUFF
|
|
||||||
FreeCPPStruct();
|
|
||||||
InitCPPStruct();
|
|
||||||
cpp->options.Quiet = 1;
|
|
||||||
cpp->options.profileString = "generic";
|
|
||||||
if (!InitAtomTable(atable, 0))
|
|
||||||
return 1;
|
|
||||||
if (!InitScanner(cpp))
|
|
||||||
return 1;
|
|
||||||
# endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//FreeCPPStruct() - Free the CPP structure.
|
|
||||||
|
|
||||||
int FreeCPPStruct(void)
|
|
||||||
{
|
|
||||||
if (refCount)
|
|
||||||
{
|
|
||||||
free(cpp);
|
|
||||||
refCount--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Finalizing the Preprocessor.
|
|
||||||
|
|
||||||
int FinalizePreprocessor(void)
|
|
||||||
{
|
|
||||||
# define CPP_STUFF true
|
|
||||||
# ifdef CPP_STUFF
|
|
||||||
FreeAtomTable(atable);
|
|
||||||
FreeCPPStruct();
|
|
||||||
FreeScanner();
|
|
||||||
# endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
////////////////////////////////////// End of cppstruct.c //////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
//
|
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
|
||||||
//All rights reserved.
|
|
||||||
//
|
|
||||||
//Redistribution and use in source and binary forms, with or without
|
|
||||||
//modification, are permitted provided that the following conditions
|
|
||||||
//are met:
|
|
||||||
//
|
|
||||||
// Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following
|
|
||||||
// disclaimer in the documentation and/or other materials provided
|
|
||||||
// with the distribution.
|
|
||||||
//
|
|
||||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived
|
|
||||||
// from this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
//
|
|
||||||
/****************************************************************************\
|
|
||||||
Copyright (c) 2002, NVIDIA Corporation.
|
|
||||||
|
|
||||||
NVIDIA Corporation("NVIDIA") supplies this software to you in
|
|
||||||
consideration of your agreement to the following terms, and your use,
|
|
||||||
installation, modification or redistribution of this NVIDIA software
|
|
||||||
constitutes acceptance of these terms. If you do not agree with these
|
|
||||||
terms, please do not use, install, modify or redistribute this NVIDIA
|
|
||||||
software.
|
|
||||||
|
|
||||||
In consideration of your agreement to abide by the following terms, and
|
|
||||||
subject to these terms, NVIDIA grants you a personal, non-exclusive
|
|
||||||
license, under NVIDIA's copyrights in this original NVIDIA software (the
|
|
||||||
"NVIDIA Software"), to use, reproduce, modify and redistribute the
|
|
||||||
NVIDIA Software, with or without modifications, in source and/or binary
|
|
||||||
forms; provided that if you redistribute the NVIDIA Software, you must
|
|
||||||
retain the copyright notice of NVIDIA, this notice and the following
|
|
||||||
text and disclaimers in all such redistributions of the NVIDIA Software.
|
|
||||||
Neither the name, trademarks, service marks nor logos of NVIDIA
|
|
||||||
Corporation may be used to endorse or promote products derived from the
|
|
||||||
NVIDIA Software without specific prior written permission from NVIDIA.
|
|
||||||
Except as expressly stated in this notice, no other rights or licenses
|
|
||||||
express or implied, are granted by NVIDIA herein, including but not
|
|
||||||
limited to any patent rights that may be infringed by your derivative
|
|
||||||
works or by other works in which the NVIDIA Software may be
|
|
||||||
incorporated. No hardware is licensed hereunder.
|
|
||||||
|
|
||||||
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
|
||||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
|
||||||
INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
|
|
||||||
NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
|
|
||||||
ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
|
|
||||||
PRODUCTS.
|
|
||||||
|
|
||||||
IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
|
|
||||||
INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
||||||
TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
|
||||||
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
|
|
||||||
OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
|
|
||||||
NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
|
|
||||||
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
|
|
||||||
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
\****************************************************************************/
|
|
||||||
//
|
|
||||||
#ifndef __MEMORY_H
|
|
||||||
#define __MEMORY_H
|
|
||||||
|
|
||||||
typedef struct MemoryPool_rec MemoryPool;
|
|
||||||
|
|
||||||
extern MemoryPool *mem_CreatePool(size_t chunksize, unsigned align);
|
|
||||||
extern void mem_FreePool(MemoryPool *);
|
|
||||||
extern void *mem_Alloc(MemoryPool *p, size_t size);
|
|
||||||
extern void *mem_Realloc(MemoryPool *p, void *old, size_t oldsize, size_t newsize);
|
|
||||||
extern int mem_AddCleanup(MemoryPool *p, void (*fn)(void *), void *arg);
|
|
||||||
|
|
||||||
#endif /* __MEMORY_H */
|
|
||||||
@@ -1,158 +0,0 @@
|
|||||||
//
|
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
|
||||||
//All rights reserved.
|
|
||||||
//
|
|
||||||
//Redistribution and use in source and binary forms, with or without
|
|
||||||
//modification, are permitted provided that the following conditions
|
|
||||||
//are met:
|
|
||||||
//
|
|
||||||
// Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following
|
|
||||||
// disclaimer in the documentation and/or other materials provided
|
|
||||||
// with the distribution.
|
|
||||||
//
|
|
||||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived
|
|
||||||
// from this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
//
|
|
||||||
/****************************************************************************\
|
|
||||||
Copyright (c) 2002, NVIDIA Corporation.
|
|
||||||
|
|
||||||
NVIDIA Corporation("NVIDIA") supplies this software to you in
|
|
||||||
consideration of your agreement to the following terms, and your use,
|
|
||||||
installation, modification or redistribution of this NVIDIA software
|
|
||||||
constitutes acceptance of these terms. If you do not agree with these
|
|
||||||
terms, please do not use, install, modify or redistribute this NVIDIA
|
|
||||||
software.
|
|
||||||
|
|
||||||
In consideration of your agreement to abide by the following terms, and
|
|
||||||
subject to these terms, NVIDIA grants you a personal, non-exclusive
|
|
||||||
license, under NVIDIA's copyrights in this original NVIDIA software (the
|
|
||||||
"NVIDIA Software"), to use, reproduce, modify and redistribute the
|
|
||||||
NVIDIA Software, with or without modifications, in source and/or binary
|
|
||||||
forms; provided that if you redistribute the NVIDIA Software, you must
|
|
||||||
retain the copyright notice of NVIDIA, this notice and the following
|
|
||||||
text and disclaimers in all such redistributions of the NVIDIA Software.
|
|
||||||
Neither the name, trademarks, service marks nor logos of NVIDIA
|
|
||||||
Corporation may be used to endorse or promote products derived from the
|
|
||||||
NVIDIA Software without specific prior written permission from NVIDIA.
|
|
||||||
Except as expressly stated in this notice, no other rights or licenses
|
|
||||||
express or implied, are granted by NVIDIA herein, including but not
|
|
||||||
limited to any patent rights that may be infringed by your derivative
|
|
||||||
works or by other works in which the NVIDIA Software may be
|
|
||||||
incorporated. No hardware is licensed hereunder.
|
|
||||||
|
|
||||||
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
|
||||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
|
||||||
INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
|
|
||||||
NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
|
|
||||||
ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
|
|
||||||
PRODUCTS.
|
|
||||||
|
|
||||||
IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
|
|
||||||
INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
||||||
TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
|
||||||
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
|
|
||||||
OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
|
|
||||||
NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
|
|
||||||
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
|
|
||||||
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
\****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef PREPROCESS_H
|
|
||||||
#define PREPROCESS_H
|
|
||||||
|
|
||||||
typedef struct SourceLoc_Rec {
|
|
||||||
int file;
|
|
||||||
int line;
|
|
||||||
} SourceLoc;
|
|
||||||
|
|
||||||
typedef struct Options_Rec {
|
|
||||||
const char *profileString;
|
|
||||||
int ErrorMode;
|
|
||||||
int Quiet;
|
|
||||||
|
|
||||||
// Debug The Compiler options:
|
|
||||||
int DumpAtomTable;
|
|
||||||
} Options;
|
|
||||||
|
|
||||||
#define MAX_TOKEN_LENGTH 1024
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int ppToken;
|
|
||||||
int sc_int;
|
|
||||||
double sc_dval;
|
|
||||||
int sc_ident;
|
|
||||||
char symbol_name[MAX_TOKEN_LENGTH+1];
|
|
||||||
} yystypepp;
|
|
||||||
|
|
||||||
typedef struct InputSrc {
|
|
||||||
struct InputSrc *prev;
|
|
||||||
int (*scan)(struct InputSrc *, yystypepp *);
|
|
||||||
int (*getch)(struct InputSrc *, yystypepp *);
|
|
||||||
void (*ungetch)(struct InputSrc *, int, yystypepp *);
|
|
||||||
int name; /* atom */
|
|
||||||
int line;
|
|
||||||
} InputSrc;
|
|
||||||
|
|
||||||
typedef struct CPPStruct {
|
|
||||||
// Public members
|
|
||||||
SourceLoc *pLastSourceLoc; // Set at the start of each statement by the tree walkers
|
|
||||||
Options options; // Compile options and parameters
|
|
||||||
|
|
||||||
// Private members
|
|
||||||
SourceLoc lastSourceLoc;
|
|
||||||
|
|
||||||
// Scanner data:
|
|
||||||
|
|
||||||
SourceLoc *tokenLoc; // Source location of most recent token seen by the scanner
|
|
||||||
int mostRecentToken; // Most recent token seen by the scanner
|
|
||||||
InputSrc *currentInput;
|
|
||||||
int previous_token;
|
|
||||||
int notAVersionToken; // used to make sure that #version is the first token seen in the file, if present
|
|
||||||
|
|
||||||
void *pC; // storing the parseContext of the compile object in cpp.
|
|
||||||
|
|
||||||
// Private members:
|
|
||||||
SourceLoc ltokenLoc;
|
|
||||||
int ifdepth; //current #if-#else-#endif nesting in the cpp.c file (pre-processor)
|
|
||||||
int elsedepth[64]; //Keep a track of #if depth..Max allowed is 64.
|
|
||||||
int elsetracker; //#if-#else and #endif constructs...Counter.
|
|
||||||
const char *ErrMsg;
|
|
||||||
int CompileError; //Indicate compile error when #error, #else,#elif mismatch.
|
|
||||||
|
|
||||||
//
|
|
||||||
// Globals used to communicate between parseStrings() and yy_input()and
|
|
||||||
// also across the files.(gen_glslang.cpp and scanner.c)
|
|
||||||
//
|
|
||||||
int PaWhichStr; // which string we're parsing
|
|
||||||
int* PaStrLen; // array of lengths of the PaArgv strings
|
|
||||||
int PaArgc; // count of strings in the array
|
|
||||||
char** PaArgv; // our array of strings to parse
|
|
||||||
unsigned int tokensBeforeEOF : 1;
|
|
||||||
} CPPStruct;
|
|
||||||
|
|
||||||
extern CPPStruct *cpp;
|
|
||||||
|
|
||||||
int InitPreprocessor(void);
|
|
||||||
int FinalizePreprocessor(void);
|
|
||||||
int ScanFromString(char *s);
|
|
||||||
const char* PpTokenize(yystypepp*);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
//
|
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
|
||||||
//All rights reserved.
|
|
||||||
//
|
|
||||||
//Redistribution and use in source and binary forms, with or without
|
|
||||||
//modification, are permitted provided that the following conditions
|
|
||||||
//are met:
|
|
||||||
//
|
|
||||||
// Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following
|
|
||||||
// disclaimer in the documentation and/or other materials provided
|
|
||||||
// with the distribution.
|
|
||||||
//
|
|
||||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived
|
|
||||||
// from this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
//
|
|
||||||
/****************************************************************************\
|
|
||||||
Copyright (c) 2002, NVIDIA Corporation.
|
|
||||||
|
|
||||||
NVIDIA Corporation("NVIDIA") supplies this software to you in
|
|
||||||
consideration of your agreement to the following terms, and your use,
|
|
||||||
installation, modification or redistribution of this NVIDIA software
|
|
||||||
constitutes acceptance of these terms. If you do not agree with these
|
|
||||||
terms, please do not use, install, modify or redistribute this NVIDIA
|
|
||||||
software.
|
|
||||||
|
|
||||||
In consideration of your agreement to abide by the following terms, and
|
|
||||||
subject to these terms, NVIDIA grants you a personal, non-exclusive
|
|
||||||
license, under NVIDIA's copyrights in this original NVIDIA software (the
|
|
||||||
"NVIDIA Software"), to use, reproduce, modify and redistribute the
|
|
||||||
NVIDIA Software, with or without modifications, in source and/or binary
|
|
||||||
forms; provided that if you redistribute the NVIDIA Software, you must
|
|
||||||
retain the copyright notice of NVIDIA, this notice and the following
|
|
||||||
text and disclaimers in all such redistributions of the NVIDIA Software.
|
|
||||||
Neither the name, trademarks, service marks nor logos of NVIDIA
|
|
||||||
Corporation may be used to endorse or promote products derived from the
|
|
||||||
NVIDIA Software without specific prior written permission from NVIDIA.
|
|
||||||
Except as expressly stated in this notice, no other rights or licenses
|
|
||||||
express or implied, are granted by NVIDIA herein, including but not
|
|
||||||
limited to any patent rights that may be infringed by your derivative
|
|
||||||
works or by other works in which the NVIDIA Software may be
|
|
||||||
incorporated. No hardware is licensed hereunder.
|
|
||||||
|
|
||||||
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
|
||||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
|
||||||
INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
|
|
||||||
NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
|
|
||||||
ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
|
|
||||||
PRODUCTS.
|
|
||||||
|
|
||||||
IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
|
|
||||||
INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
||||||
TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
|
||||||
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
|
|
||||||
OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
|
|
||||||
NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
|
|
||||||
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
|
|
||||||
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
\****************************************************************************/
|
|
||||||
//
|
|
||||||
// slglobals.h
|
|
||||||
//
|
|
||||||
|
|
||||||
#if !defined(__SLGLOBALS_H)
|
|
||||||
#define __SLGLOBALS_H 1
|
|
||||||
|
|
||||||
#include "preprocess.h"
|
|
||||||
|
|
||||||
// TODO: threading: Multi-threading note: The existence of this global makes
|
|
||||||
// this preprocessing single-threaded only.
|
|
||||||
extern CPPStruct *cpp;
|
|
||||||
|
|
||||||
#undef CPPC_DEBUG_THE_COMPILER
|
|
||||||
#if defined(_DEBUG)
|
|
||||||
#define CPPC_DEBUG_THE_COMPILER 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef CPPC_ENABLE_TOOLS
|
|
||||||
#define CPPC_ENABLE_TOOLS 1
|
|
||||||
|
|
||||||
#include "memory.h"
|
|
||||||
#include "atom.h"
|
|
||||||
#include "scanner.h"
|
|
||||||
#include "cpp.h"
|
|
||||||
#include "tokens.h"
|
|
||||||
#include "symbols.h"
|
|
||||||
#if !defined(NO_PARSER)
|
|
||||||
#include "parser.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(NULL)
|
|
||||||
#define NULL 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // !(defined(__SLGLOBALS_H)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,143 +0,0 @@
|
|||||||
//
|
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
|
||||||
//All rights reserved.
|
|
||||||
//
|
|
||||||
//Redistribution and use in source and binary forms, with or without
|
|
||||||
//modification, are permitted provided that the following conditions
|
|
||||||
//are met:
|
|
||||||
//
|
|
||||||
// Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following
|
|
||||||
// disclaimer in the documentation and/or other materials provided
|
|
||||||
// with the distribution.
|
|
||||||
//
|
|
||||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived
|
|
||||||
// from this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
//
|
|
||||||
/****************************************************************************\
|
|
||||||
Copyright (c) 2002, NVIDIA Corporation.
|
|
||||||
|
|
||||||
NVIDIA Corporation("NVIDIA") supplies this software to you in
|
|
||||||
consideration of your agreement to the following terms, and your use,
|
|
||||||
installation, modification or redistribution of this NVIDIA software
|
|
||||||
constitutes acceptance of these terms. If you do not agree with these
|
|
||||||
terms, please do not use, install, modify or redistribute this NVIDIA
|
|
||||||
software.
|
|
||||||
|
|
||||||
In consideration of your agreement to abide by the following terms, and
|
|
||||||
subject to these terms, NVIDIA grants you a personal, non-exclusive
|
|
||||||
license, under NVIDIA's copyrights in this original NVIDIA software (the
|
|
||||||
"NVIDIA Software"), to use, reproduce, modify and redistribute the
|
|
||||||
NVIDIA Software, with or without modifications, in source and/or binary
|
|
||||||
forms; provided that if you redistribute the NVIDIA Software, you must
|
|
||||||
retain the copyright notice of NVIDIA, this notice and the following
|
|
||||||
text and disclaimers in all such redistributions of the NVIDIA Software.
|
|
||||||
Neither the name, trademarks, service marks nor logos of NVIDIA
|
|
||||||
Corporation may be used to endorse or promote products derived from the
|
|
||||||
NVIDIA Software without specific prior written permission from NVIDIA.
|
|
||||||
Except as expressly stated in this notice, no other rights or licenses
|
|
||||||
express or implied, are granted by NVIDIA herein, including but not
|
|
||||||
limited to any patent rights that may be infringed by your derivative
|
|
||||||
works or by other works in which the NVIDIA Software may be
|
|
||||||
incorporated. No hardware is licensed hereunder.
|
|
||||||
|
|
||||||
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
|
||||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
|
||||||
INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
|
|
||||||
NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
|
|
||||||
ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
|
|
||||||
PRODUCTS.
|
|
||||||
|
|
||||||
IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
|
|
||||||
INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
||||||
TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
|
||||||
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
|
|
||||||
OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
|
|
||||||
NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
|
|
||||||
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
|
|
||||||
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
\****************************************************************************/
|
|
||||||
//
|
|
||||||
// symbols.h
|
|
||||||
//
|
|
||||||
|
|
||||||
#if !defined(__SYMBOLS_H)
|
|
||||||
#define __SYMBOLS_H 1
|
|
||||||
|
|
||||||
#include "memory.h"
|
|
||||||
|
|
||||||
typedef enum symbolkind {
|
|
||||||
MACRO_S
|
|
||||||
} symbolkind;
|
|
||||||
|
|
||||||
// Typedefs for things defined here in "symbols.h":
|
|
||||||
|
|
||||||
typedef struct Scope_Rec Scope;
|
|
||||||
typedef struct Symbol_Rec Symbol;
|
|
||||||
|
|
||||||
typedef struct SymbolList_Rec {
|
|
||||||
struct SymbolList_Rec *next;
|
|
||||||
Symbol *symb;
|
|
||||||
} SymbolList;
|
|
||||||
|
|
||||||
struct Scope_Rec {
|
|
||||||
Scope *next, *prev; // doubly-linked list of all scopes
|
|
||||||
Scope *parent;
|
|
||||||
Scope *funScope; // Points to base scope of enclosing function
|
|
||||||
MemoryPool *pool; // pool used for allocation in this scope
|
|
||||||
Symbol *symbols;
|
|
||||||
|
|
||||||
int level; // 0 = super globals, 1 = globals, etc.
|
|
||||||
|
|
||||||
// Only used at global scope (level 1):
|
|
||||||
SymbolList *programs; // List of programs for this compilation.
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Symbol table is a simple binary tree.
|
|
||||||
|
|
||||||
#include "cpp.h" // to get MacroSymbol def
|
|
||||||
|
|
||||||
struct Symbol_Rec {
|
|
||||||
Symbol *left, *right;
|
|
||||||
Symbol *next;
|
|
||||||
int name; // Name atom
|
|
||||||
SourceLoc loc;
|
|
||||||
symbolkind kind;
|
|
||||||
union {
|
|
||||||
MacroSymbol mac;
|
|
||||||
} details;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern Scope *CurrentScope;
|
|
||||||
extern Scope *GlobalScope;
|
|
||||||
extern Scope *ScopeList;
|
|
||||||
|
|
||||||
Scope *NewScopeInPool(MemoryPool *);
|
|
||||||
#define NewScope() NewScopeInPool(CurrentScope->pool)
|
|
||||||
void PushScope(Scope *fScope);
|
|
||||||
Scope *PopScope(void);
|
|
||||||
Symbol *NewSymbol(SourceLoc *loc, Scope *fScope, int name, symbolkind kind);
|
|
||||||
Symbol *AddSymbol(SourceLoc *loc, Scope *fScope, int atom, symbolkind kind);
|
|
||||||
Symbol *LookUpLocalSymbol(Scope *fScope, int atom);
|
|
||||||
Symbol *LookUpSymbol(Scope *fScope, int atom);
|
|
||||||
|
|
||||||
#endif // !defined(__SYMBOLS_H)
|
|
||||||
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
//
|
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
|
||||||
//All rights reserved.
|
|
||||||
//
|
|
||||||
//Redistribution and use in source and binary forms, with or without
|
|
||||||
//modification, are permitted provided that the following conditions
|
|
||||||
//are met:
|
|
||||||
//
|
|
||||||
// Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following
|
|
||||||
// disclaimer in the documentation and/or other materials provided
|
|
||||||
// with the distribution.
|
|
||||||
//
|
|
||||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived
|
|
||||||
// from this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
//
|
|
||||||
/****************************************************************************\
|
|
||||||
Copyright (c) 2002, NVIDIA Corporation.
|
|
||||||
|
|
||||||
NVIDIA Corporation("NVIDIA") supplies this software to you in
|
|
||||||
consideration of your agreement to the following terms, and your use,
|
|
||||||
installation, modification or redistribution of this NVIDIA software
|
|
||||||
constitutes acceptance of these terms. If you do not agree with these
|
|
||||||
terms, please do not use, install, modify or redistribute this NVIDIA
|
|
||||||
software.
|
|
||||||
|
|
||||||
In consideration of your agreement to abide by the following terms, and
|
|
||||||
subject to these terms, NVIDIA grants you a personal, non-exclusive
|
|
||||||
license, under NVIDIA's copyrights in this original NVIDIA software (the
|
|
||||||
"NVIDIA Software"), to use, reproduce, modify and redistribute the
|
|
||||||
NVIDIA Software, with or without modifications, in source and/or binary
|
|
||||||
forms; provided that if you redistribute the NVIDIA Software, you must
|
|
||||||
retain the copyright notice of NVIDIA, this notice and the following
|
|
||||||
text and disclaimers in all such redistributions of the NVIDIA Software.
|
|
||||||
Neither the name, trademarks, service marks nor logos of NVIDIA
|
|
||||||
Corporation may be used to endorse or promote products derived from the
|
|
||||||
NVIDIA Software without specific prior written permission from NVIDIA.
|
|
||||||
Except as expressly stated in this notice, no other rights or licenses
|
|
||||||
express or implied, are granted by NVIDIA herein, including but not
|
|
||||||
limited to any patent rights that may be infringed by your derivative
|
|
||||||
works or by other works in which the NVIDIA Software may be
|
|
||||||
incorporated. No hardware is licensed hereunder.
|
|
||||||
|
|
||||||
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
|
||||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
|
||||||
INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
|
|
||||||
NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
|
|
||||||
ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
|
|
||||||
PRODUCTS.
|
|
||||||
|
|
||||||
IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
|
|
||||||
INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
||||||
TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
|
||||||
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
|
|
||||||
OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
|
|
||||||
NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
|
|
||||||
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
|
|
||||||
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
\****************************************************************************/
|
|
||||||
//
|
|
||||||
// tokens.h
|
|
||||||
//
|
|
||||||
|
|
||||||
#if !defined(__TOKENS_H)
|
|
||||||
#define __TOKENS_H 1
|
|
||||||
|
|
||||||
#include "parser.h"
|
|
||||||
|
|
||||||
#define EOF_SY (-1)
|
|
||||||
|
|
||||||
typedef struct TokenBlock_Rec TokenBlock;
|
|
||||||
|
|
||||||
typedef struct TokenStream_Rec {
|
|
||||||
struct TokenStream_Rec *next;
|
|
||||||
char *name;
|
|
||||||
TokenBlock *head;
|
|
||||||
TokenBlock *current;
|
|
||||||
} TokenStream;
|
|
||||||
|
|
||||||
struct TokenBlock_Rec {
|
|
||||||
TokenBlock *next;
|
|
||||||
int current;
|
|
||||||
int count;
|
|
||||||
int max;
|
|
||||||
unsigned char *data;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern TokenStream stdlib_cpp_stream;
|
|
||||||
|
|
||||||
|
|
||||||
TokenStream *NewTokenStream(const char *name, MemoryPool *pool);
|
|
||||||
void DeleteTokenStream(TokenStream *pTok);
|
|
||||||
void RecordToken(TokenStream *pTok, int token, yystypepp * yylvalpp);
|
|
||||||
void RewindTokenStream(TokenStream *pTok);
|
|
||||||
int ReadToken(TokenStream *pTok, yystypepp * yylvalpp);
|
|
||||||
int ReadFromTokenStream(TokenStream *pTok, int name, int (*final)(CPPStruct *));
|
|
||||||
void UngetToken(int, yystypepp * yylvalpp);
|
|
||||||
|
|
||||||
#if defined(CPPC_ENABLE_TOOLS)
|
|
||||||
|
|
||||||
void DumpTokenStream(FILE *, TokenStream *, yystypepp * yylvalpp);
|
|
||||||
|
|
||||||
#endif // defined(CPPC_ENABLE_TOOLS)
|
|
||||||
|
|
||||||
#endif // !defined(__TOKENS_H)
|
|
||||||
BIN
tools/bison.exe
BIN
tools/bison.exe
Binary file not shown.
@@ -1,334 +0,0 @@
|
|||||||
|
|
||||||
extern int timeclock;
|
|
||||||
|
|
||||||
|
|
||||||
int yyerror; /* Yyerror and yycost are set by guards. */
|
|
||||||
int yycost; /* If yyerror is set to a nonzero value by a */
|
|
||||||
/* guard, the reduction with which the guard */
|
|
||||||
/* is associated is not performed, and the */
|
|
||||||
/* error recovery mechanism is invoked. */
|
|
||||||
/* Yycost indicates the cost of performing */
|
|
||||||
/* the reduction given the attributes of the */
|
|
||||||
/* symbols. */
|
|
||||||
|
|
||||||
|
|
||||||
/* YYMAXDEPTH indicates the size of the parser's state and value */
|
|
||||||
/* stacks. */
|
|
||||||
|
|
||||||
#ifndef YYMAXDEPTH
|
|
||||||
#define YYMAXDEPTH 500
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* YYMAXRULES must be at least as large as the number of rules that */
|
|
||||||
/* could be placed in the rule queue. That number could be determined */
|
|
||||||
/* from the grammar and the size of the stack, but, as yet, it is not. */
|
|
||||||
|
|
||||||
#ifndef YYMAXRULES
|
|
||||||
#define YYMAXRULES 100
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef YYMAXBACKUP
|
|
||||||
#define YYMAXBACKUP 100
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
short yyss[YYMAXDEPTH]; /* the state stack */
|
|
||||||
YYSTYPE yyvs[YYMAXDEPTH]; /* the semantic value stack */
|
|
||||||
YYLTYPE yyls[YYMAXDEPTH]; /* the location stack */
|
|
||||||
short yyrq[YYMAXRULES]; /* the rule queue */
|
|
||||||
int yychar; /* the lookahead symbol */
|
|
||||||
|
|
||||||
YYSTYPE yylval; /* the semantic value of the */
|
|
||||||
/* lookahead symbol */
|
|
||||||
|
|
||||||
YYSTYPE yytval; /* the semantic value for the state */
|
|
||||||
/* at the top of the state stack. */
|
|
||||||
|
|
||||||
YYSTYPE yyval; /* the variable used to return */
|
|
||||||
/* semantic values from the action */
|
|
||||||
/* routines */
|
|
||||||
|
|
||||||
YYLTYPE yylloc; /* location data for the lookahead */
|
|
||||||
/* symbol */
|
|
||||||
|
|
||||||
YYLTYPE yytloc; /* location data for the state at the */
|
|
||||||
/* top of the state stack */
|
|
||||||
|
|
||||||
|
|
||||||
int yynunlexed;
|
|
||||||
short yyunchar[YYMAXBACKUP];
|
|
||||||
YYSTYPE yyunval[YYMAXBACKUP];
|
|
||||||
YYLTYPE yyunloc[YYMAXBACKUP];
|
|
||||||
|
|
||||||
short *yygssp; /* a pointer to the top of the state */
|
|
||||||
/* stack; only set during error */
|
|
||||||
/* recovery. */
|
|
||||||
|
|
||||||
YYSTYPE *yygvsp; /* a pointer to the top of the value */
|
|
||||||
/* stack; only set during error */
|
|
||||||
/* recovery. */
|
|
||||||
|
|
||||||
YYLTYPE *yyglsp; /* a pointer to the top of the */
|
|
||||||
/* location stack; only set during */
|
|
||||||
/* error recovery. */
|
|
||||||
|
|
||||||
|
|
||||||
/* Yyget is an interface between the parser and the lexical analyzer. */
|
|
||||||
/* It is costly to provide such an interface, but it avoids requiring */
|
|
||||||
/* the lexical analyzer to be able to back up the scan. */
|
|
||||||
|
|
||||||
yyget()
|
|
||||||
{
|
|
||||||
if (yynunlexed > 0)
|
|
||||||
{
|
|
||||||
yynunlexed--;
|
|
||||||
yychar = yyunchar[yynunlexed];
|
|
||||||
yylval = yyunval[yynunlexed];
|
|
||||||
yylloc = yyunloc[yynunlexed];
|
|
||||||
}
|
|
||||||
else if (yychar <= 0)
|
|
||||||
yychar = 0;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
yychar = yylex();
|
|
||||||
if (yychar < 0)
|
|
||||||
yychar = 0;
|
|
||||||
else yychar = YYTRANSLATE(yychar);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
yyunlex(chr, val, loc)
|
|
||||||
int chr;
|
|
||||||
YYSTYPE val;
|
|
||||||
YYLTYPE loc;
|
|
||||||
{
|
|
||||||
yyunchar[yynunlexed] = chr;
|
|
||||||
yyunval[yynunlexed] = val;
|
|
||||||
yyunloc[yynunlexed] = loc;
|
|
||||||
yynunlexed++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
yyrestore(first, last)
|
|
||||||
register short *first;
|
|
||||||
register short *last;
|
|
||||||
{
|
|
||||||
register short *ssp;
|
|
||||||
register short *rp;
|
|
||||||
register int symbol;
|
|
||||||
register int state;
|
|
||||||
register int tvalsaved;
|
|
||||||
|
|
||||||
ssp = yygssp;
|
|
||||||
yyunlex(yychar, yylval, yylloc);
|
|
||||||
|
|
||||||
tvalsaved = 0;
|
|
||||||
while (first != last)
|
|
||||||
{
|
|
||||||
symbol = yystos[*ssp];
|
|
||||||
if (symbol < YYNTBASE)
|
|
||||||
{
|
|
||||||
yyunlex(symbol, yytval, yytloc);
|
|
||||||
tvalsaved = 1;
|
|
||||||
ssp--;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssp--;
|
|
||||||
|
|
||||||
if (first == yyrq)
|
|
||||||
first = yyrq + YYMAXRULES;
|
|
||||||
|
|
||||||
first--;
|
|
||||||
|
|
||||||
for (rp = yyrhs + yyprhs[*first]; symbol = *rp; rp++)
|
|
||||||
{
|
|
||||||
if (symbol < YYNTBASE)
|
|
||||||
state = yytable[yypact[*ssp] + symbol];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
state = yypgoto[symbol - YYNTBASE] + *ssp;
|
|
||||||
|
|
||||||
if (state >= 0 && state <= YYLAST && yycheck[state] == *ssp)
|
|
||||||
state = yytable[state];
|
|
||||||
else
|
|
||||||
state = yydefgoto[symbol - YYNTBASE];
|
|
||||||
}
|
|
||||||
|
|
||||||
*++ssp = state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! tvalsaved && ssp > yyss)
|
|
||||||
{
|
|
||||||
yyunlex(yystos[*ssp], yytval, yytloc);
|
|
||||||
ssp--;
|
|
||||||
}
|
|
||||||
|
|
||||||
yygssp = ssp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
yyparse()
|
|
||||||
{
|
|
||||||
register int yystate;
|
|
||||||
register int yyn;
|
|
||||||
register short *yyssp;
|
|
||||||
register short *yyrq0;
|
|
||||||
register short *yyptr;
|
|
||||||
register YYSTYPE *yyvsp;
|
|
||||||
|
|
||||||
int yylen;
|
|
||||||
YYLTYPE *yylsp;
|
|
||||||
short *yyrq1;
|
|
||||||
short *yyrq2;
|
|
||||||
|
|
||||||
yystate = 0;
|
|
||||||
yyssp = yyss - 1;
|
|
||||||
yyvsp = yyvs - 1;
|
|
||||||
yylsp = yyls - 1;
|
|
||||||
yyrq0 = yyrq;
|
|
||||||
yyrq1 = yyrq0;
|
|
||||||
yyrq2 = yyrq0;
|
|
||||||
|
|
||||||
yychar = yylex();
|
|
||||||
if (yychar < 0)
|
|
||||||
yychar = 0;
|
|
||||||
else yychar = YYTRANSLATE(yychar);
|
|
||||||
|
|
||||||
yynewstate:
|
|
||||||
|
|
||||||
if (yyssp >= yyss + YYMAXDEPTH - 1)
|
|
||||||
{
|
|
||||||
yyabort("Parser Stack Overflow");
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
*++yyssp = yystate;
|
|
||||||
|
|
||||||
yyresume:
|
|
||||||
|
|
||||||
yyn = yypact[yystate];
|
|
||||||
if (yyn == YYFLAG)
|
|
||||||
goto yydefault;
|
|
||||||
|
|
||||||
yyn += yychar;
|
|
||||||
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar)
|
|
||||||
goto yydefault;
|
|
||||||
|
|
||||||
yyn = yytable[yyn];
|
|
||||||
if (yyn < 0)
|
|
||||||
{
|
|
||||||
yyn = -yyn;
|
|
||||||
goto yyreduce;
|
|
||||||
}
|
|
||||||
else if (yyn == 0)
|
|
||||||
goto yyerrlab;
|
|
||||||
|
|
||||||
yystate = yyn;
|
|
||||||
|
|
||||||
yyptr = yyrq2;
|
|
||||||
while (yyptr != yyrq1)
|
|
||||||
{
|
|
||||||
yyn = *yyptr++;
|
|
||||||
yylen = yyr2[yyn];
|
|
||||||
yyvsp -= yylen;
|
|
||||||
yylsp -= yylen;
|
|
||||||
|
|
||||||
yyguard(yyn, yyvsp, yylsp);
|
|
||||||
if (yyerror)
|
|
||||||
goto yysemerr;
|
|
||||||
|
|
||||||
yyaction(yyn, yyvsp, yylsp);
|
|
||||||
*++yyvsp = yyval;
|
|
||||||
|
|
||||||
yylsp++;
|
|
||||||
if (yylen == 0)
|
|
||||||
{
|
|
||||||
yylsp->timestamp = timeclock;
|
|
||||||
yylsp->first_line = yytloc.first_line;
|
|
||||||
yylsp->first_column = yytloc.first_column;
|
|
||||||
yylsp->last_line = (yylsp-1)->last_line;
|
|
||||||
yylsp->last_column = (yylsp-1)->last_column;
|
|
||||||
yylsp->text = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
yylsp->last_line = (yylsp+yylen-1)->last_line;
|
|
||||||
yylsp->last_column = (yylsp+yylen-1)->last_column;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (yyptr == yyrq + YYMAXRULES)
|
|
||||||
yyptr = yyrq;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (yystate == YYFINAL)
|
|
||||||
YYACCEPT;
|
|
||||||
|
|
||||||
yyrq2 = yyptr;
|
|
||||||
yyrq1 = yyrq0;
|
|
||||||
|
|
||||||
*++yyvsp = yytval;
|
|
||||||
*++yylsp = yytloc;
|
|
||||||
yytval = yylval;
|
|
||||||
yytloc = yylloc;
|
|
||||||
yyget();
|
|
||||||
|
|
||||||
goto yynewstate;
|
|
||||||
|
|
||||||
yydefault:
|
|
||||||
|
|
||||||
yyn = yydefact[yystate];
|
|
||||||
if (yyn == 0)
|
|
||||||
goto yyerrlab;
|
|
||||||
|
|
||||||
yyreduce:
|
|
||||||
|
|
||||||
*yyrq0++ = yyn;
|
|
||||||
|
|
||||||
if (yyrq0 == yyrq + YYMAXRULES)
|
|
||||||
yyrq0 = yyrq;
|
|
||||||
|
|
||||||
if (yyrq0 == yyrq2)
|
|
||||||
{
|
|
||||||
yyabort("Parser Rule Queue Overflow");
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
yyssp -= yyr2[yyn];
|
|
||||||
yyn = yyr1[yyn];
|
|
||||||
|
|
||||||
yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
|
|
||||||
if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
|
|
||||||
yystate = yytable[yystate];
|
|
||||||
else
|
|
||||||
yystate = yydefgoto[yyn - YYNTBASE];
|
|
||||||
|
|
||||||
goto yynewstate;
|
|
||||||
|
|
||||||
yysemerr:
|
|
||||||
*--yyptr = yyn;
|
|
||||||
yyrq2 = yyptr;
|
|
||||||
yyvsp += yyr2[yyn];
|
|
||||||
|
|
||||||
yyerrlab:
|
|
||||||
|
|
||||||
yygssp = yyssp;
|
|
||||||
yygvsp = yyvsp;
|
|
||||||
yyglsp = yylsp;
|
|
||||||
yyrestore(yyrq0, yyrq2);
|
|
||||||
yyrecover();
|
|
||||||
yystate = *yygssp;
|
|
||||||
yyssp = yygssp;
|
|
||||||
yyvsp = yygvsp;
|
|
||||||
yyrq0 = yyrq;
|
|
||||||
yyrq1 = yyrq0;
|
|
||||||
yyrq2 = yyrq0;
|
|
||||||
goto yyresume;
|
|
||||||
}
|
|
||||||
|
|
||||||
$
|
|
||||||
@@ -1,699 +0,0 @@
|
|||||||
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
|
|
||||||
|
|
||||||
/* Skeleton output parser for bison,
|
|
||||||
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|
||||||
|
|
||||||
/* As a special exception, when this file is copied by Bison into a
|
|
||||||
Bison output file, you may use that output file without restriction.
|
|
||||||
This special exception was added by the Free Software Foundation
|
|
||||||
in version 1.24 of Bison. */
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#define alloca __builtin_alloca
|
|
||||||
#else /* not __GNUC__ */
|
|
||||||
#if HAVE_ALLOCA_H
|
|
||||||
#include <alloca.h>
|
|
||||||
#else /* not HAVE_ALLOCA_H */
|
|
||||||
#ifdef _AIX
|
|
||||||
#pragma alloca
|
|
||||||
#else /* not _AIX */
|
|
||||||
char *alloca ();
|
|
||||||
#endif /* not _AIX */
|
|
||||||
#endif /* not HAVE_ALLOCA_H */
|
|
||||||
#endif /* not __GNUC__ */
|
|
||||||
|
|
||||||
extern void yyerror(char* s);
|
|
||||||
|
|
||||||
#ifndef alloca
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#define alloca __builtin_alloca
|
|
||||||
#else /* not GNU C. */
|
|
||||||
#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
|
|
||||||
#include <alloca.h>
|
|
||||||
#else /* not sparc */
|
|
||||||
#if (defined (MSDOS) && !defined (__TURBOC__)) || defined (WIN32)
|
|
||||||
#include <malloc.h>
|
|
||||||
#else /* not MSDOS, or __TURBOC__ */
|
|
||||||
#if defined(_AIX)
|
|
||||||
#include <malloc.h>
|
|
||||||
#pragma alloca
|
|
||||||
#else /* not MSDOS, __TURBOC__, or _AIX */
|
|
||||||
#ifdef __hpux
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
void *alloca (unsigned int);
|
|
||||||
};
|
|
||||||
#else /* not __cplusplus */
|
|
||||||
void *alloca ();
|
|
||||||
#endif /* not __cplusplus */
|
|
||||||
#endif /* __hpux */
|
|
||||||
#endif /* not _AIX */
|
|
||||||
#endif /* not MSDOS, or __TURBOC__ */
|
|
||||||
#endif /* not sparc. */
|
|
||||||
#endif /* not GNU C. */
|
|
||||||
#endif /* alloca not defined. */
|
|
||||||
|
|
||||||
/* This is the parser code that is written into each bison parser
|
|
||||||
when the %semantic_parser declaration is not specified in the grammar.
|
|
||||||
It was written by Richard Stallman by simplifying the hairy parser
|
|
||||||
used when %semantic_parser is specified. */
|
|
||||||
|
|
||||||
/* Note: there must be only one dollar sign in this file.
|
|
||||||
It is replaced by the list of actions, each action
|
|
||||||
as one case of the switch. */
|
|
||||||
|
|
||||||
#define yyerrok (yyerrstatus = 0)
|
|
||||||
#define yyclearin (yychar = YYEMPTY)
|
|
||||||
#define YYEMPTY -2
|
|
||||||
#define YYEOF 0
|
|
||||||
#define YYACCEPT return(0)
|
|
||||||
#define YYABORT return(1)
|
|
||||||
#define YYERROR goto yyerrlab1
|
|
||||||
/* Like YYERROR except do call yyerror.
|
|
||||||
This remains here temporarily to ease the
|
|
||||||
transition to the new meaning of YYERROR, for GCC.
|
|
||||||
Once GCC version 2 has supplanted version 1, this can go. */
|
|
||||||
#define YYFAIL goto yyerrlab
|
|
||||||
#define YYRECOVERING() (!!yyerrstatus)
|
|
||||||
#define YYBACKUP(token, value) \
|
|
||||||
do \
|
|
||||||
if (yychar == YYEMPTY && yylen == 1) \
|
|
||||||
{ yychar = (token), yylval = (value); \
|
|
||||||
yychar1 = YYTRANSLATE (yychar); \
|
|
||||||
YYPOPSTACK; \
|
|
||||||
goto yybackup; \
|
|
||||||
} \
|
|
||||||
else \
|
|
||||||
{ yyerror ("syntax error: cannot back up"); YYERROR; } \
|
|
||||||
while (0)
|
|
||||||
|
|
||||||
#define YYTERROR 1
|
|
||||||
#define YYERRCODE 256
|
|
||||||
|
|
||||||
#ifndef YYPURE
|
|
||||||
#define YYLEX yylex()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef YYPURE
|
|
||||||
#ifdef YYLSP_NEEDED
|
|
||||||
#ifdef YYLEX_PARAM
|
|
||||||
#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
|
|
||||||
#else
|
|
||||||
#define YYLEX yylex(&yylval, &yylloc)
|
|
||||||
#endif
|
|
||||||
#else /* not YYLSP_NEEDED */
|
|
||||||
#ifdef YYLEX_PARAM
|
|
||||||
#define YYLEX yylex(&yylval, YYLEX_PARAM)
|
|
||||||
#else
|
|
||||||
#define YYLEX yylex(&yylval)
|
|
||||||
#endif
|
|
||||||
#endif /* not YYLSP_NEEDED */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* If nonreentrant, generate the variables here */
|
|
||||||
|
|
||||||
#ifndef YYPURE
|
|
||||||
|
|
||||||
int yychar; /* the lookahead symbol */
|
|
||||||
YYSTYPE yylval; /* the semantic value of the */
|
|
||||||
/* lookahead symbol */
|
|
||||||
|
|
||||||
#ifdef YYLSP_NEEDED
|
|
||||||
YYLTYPE yylloc; /* location data for the lookahead */
|
|
||||||
/* symbol */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int yynerrs; /* number of parse errors so far */
|
|
||||||
#endif /* not YYPURE */
|
|
||||||
|
|
||||||
#if YYDEBUG != 0
|
|
||||||
int yydebug; /* nonzero means print parse trace */
|
|
||||||
/* Since this is uninitialized, it does not stop multiple parsers
|
|
||||||
from coexisting. */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* YYINITDEPTH indicates the initial size of the parser's stacks */
|
|
||||||
|
|
||||||
#ifndef YYINITDEPTH
|
|
||||||
#define YYINITDEPTH 200
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* YYMAXDEPTH is the maximum size the stacks can grow to
|
|
||||||
(effective only if the built-in stack extension method is used). */
|
|
||||||
|
|
||||||
#if YYMAXDEPTH == 0
|
|
||||||
#undef YYMAXDEPTH
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef YYMAXDEPTH
|
|
||||||
#define YYMAXDEPTH 10000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Prevent warning if -Wstrict-prototypes. */
|
|
||||||
#ifdef __GNUC__
|
|
||||||
int yyparse (void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
|
|
||||||
#define __yy_memcpy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT)
|
|
||||||
#else /* not GNU C or C++ */
|
|
||||||
#ifndef __cplusplus
|
|
||||||
|
|
||||||
/* This is the most reliable way to avoid incompatibilities
|
|
||||||
in available built-in functions on various systems. */
|
|
||||||
static void
|
|
||||||
__yy_memcpy (from, to, count)
|
|
||||||
char *from;
|
|
||||||
char *to;
|
|
||||||
size_t count;
|
|
||||||
{
|
|
||||||
register char *f = from;
|
|
||||||
register char *t = to;
|
|
||||||
register size_t i = count;
|
|
||||||
|
|
||||||
while (i-- > 0)
|
|
||||||
*t++ = *f++;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* __cplusplus */
|
|
||||||
|
|
||||||
/* This is the most reliable way to avoid incompatibilities
|
|
||||||
in available built-in functions on various systems. */
|
|
||||||
static void
|
|
||||||
__yy_memcpy (char *from, char *to, size_t count)
|
|
||||||
{
|
|
||||||
register char *f = from;
|
|
||||||
register char *t = to;
|
|
||||||
register size_t i = count;
|
|
||||||
|
|
||||||
while (i-- > 0)
|
|
||||||
*t++ = *f++;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
|
|
||||||
into yyparse. The argument should have type void *.
|
|
||||||
It should actually point to an object.
|
|
||||||
Grammar actions can access the variable by casting it
|
|
||||||
to the proper pointer type. */
|
|
||||||
|
|
||||||
#ifdef YYPARSE_PARAM
|
|
||||||
#ifndef YYPARSE_PARAM_DECL
|
|
||||||
#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#define YYPARSE_PARAM
|
|
||||||
#define YYPARSE_PARAM_DECL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern YY_DECL;
|
|
||||||
|
|
||||||
int
|
|
||||||
yyparse(YYPARSE_PARAM_DECL YYPARSE_PARAM) {
|
|
||||||
register int yystate;
|
|
||||||
register int yyn;
|
|
||||||
register short *yyssp;
|
|
||||||
register YYSTYPE *yyvsp;
|
|
||||||
int yyerrstatus; /* number of tokens to shift before error messages enabled */
|
|
||||||
int yychar1 = 0; /* lookahead token as an internal (translated) token number */
|
|
||||||
|
|
||||||
short yyssa[YYINITDEPTH]; /* the state stack */
|
|
||||||
YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
|
|
||||||
|
|
||||||
short *yyss = yyssa; /* refer to the stacks thru separate pointers */
|
|
||||||
YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
|
|
||||||
|
|
||||||
#ifdef YYLSP_NEEDED
|
|
||||||
YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
|
|
||||||
YYLTYPE *yyls = yylsa;
|
|
||||||
YYLTYPE *yylsp;
|
|
||||||
|
|
||||||
#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
|
|
||||||
#else
|
|
||||||
#define YYPOPSTACK (yyvsp--, yyssp--)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
size_t yystacksize = YYINITDEPTH;
|
|
||||||
|
|
||||||
#ifdef YYPURE
|
|
||||||
int yychar;
|
|
||||||
YYSTYPE yylval;
|
|
||||||
int yynerrs;
|
|
||||||
#ifdef YYLSP_NEEDED
|
|
||||||
YYLTYPE yylloc;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
YYSTYPE yyval; /* the variable used to return */
|
|
||||||
/* semantic values from the action */
|
|
||||||
/* routines */
|
|
||||||
|
|
||||||
int yylen;
|
|
||||||
|
|
||||||
#if YYDEBUG != 0
|
|
||||||
if (yydebug)
|
|
||||||
fprintf(stderr, "Starting parse\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
yystate = 0;
|
|
||||||
yyerrstatus = 0;
|
|
||||||
yynerrs = 0;
|
|
||||||
yychar = YYEMPTY; /* Cause a token to be read. */
|
|
||||||
|
|
||||||
/* Initialize stack pointers.
|
|
||||||
Waste one element of value and location stack
|
|
||||||
so that they stay on the same level as the state stack.
|
|
||||||
The wasted elements are never initialized. */
|
|
||||||
|
|
||||||
yyssp = yyss - 1;
|
|
||||||
yyvsp = yyvs;
|
|
||||||
#ifdef YYLSP_NEEDED
|
|
||||||
yylsp = yyls;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Push a new state, which is found in yystate . */
|
|
||||||
/* In all cases, when you get here, the value and location stacks
|
|
||||||
have just been pushed. so pushing a state here evens the stacks. */
|
|
||||||
yynewstate:
|
|
||||||
|
|
||||||
*++yyssp = yystate;
|
|
||||||
|
|
||||||
if (yyssp >= yyss + yystacksize - 1)
|
|
||||||
{
|
|
||||||
/* Give user a chance to reallocate the stack */
|
|
||||||
/* Use copies of these so that the &'s don't force the real ones into memory. */
|
|
||||||
YYSTYPE *yyvs1 = yyvs;
|
|
||||||
short *yyss1 = yyss;
|
|
||||||
#ifdef YYLSP_NEEDED
|
|
||||||
YYLTYPE *yyls1 = yyls;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Get the current used size of the three stacks, in elements. */
|
|
||||||
size_t size = yyssp - yyss + 1;
|
|
||||||
|
|
||||||
#ifdef yyoverflow
|
|
||||||
/* Each stack pointer address is followed by the size of
|
|
||||||
the data in use in that stack, in bytes. */
|
|
||||||
#ifdef YYLSP_NEEDED
|
|
||||||
/* This used to be a conditional around just the two extra args,
|
|
||||||
but that might be undefined if yyoverflow is a macro. */
|
|
||||||
yyoverflow("parser stack overflow",
|
|
||||||
&yyss1, size * sizeof (*yyssp),
|
|
||||||
&yyvs1, size * sizeof (*yyvsp),
|
|
||||||
&yyls1, size * sizeof (*yylsp),
|
|
||||||
&yystacksize);
|
|
||||||
#else
|
|
||||||
yyoverflow("parser stack overflow",
|
|
||||||
&yyss1, size * sizeof (*yyssp),
|
|
||||||
&yyvs1, size * sizeof (*yyvsp),
|
|
||||||
&yystacksize);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
yyss = yyss1; yyvs = yyvs1;
|
|
||||||
#ifdef YYLSP_NEEDED
|
|
||||||
yyls = yyls1;
|
|
||||||
#endif
|
|
||||||
#else /* no yyoverflow */
|
|
||||||
/* Extend the stack our own way. */
|
|
||||||
if (yystacksize >= YYMAXDEPTH)
|
|
||||||
{
|
|
||||||
yyerror("parser stack overflow");
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
yystacksize *= 2;
|
|
||||||
if (yystacksize > YYMAXDEPTH)
|
|
||||||
yystacksize = YYMAXDEPTH;
|
|
||||||
yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
|
|
||||||
__yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
|
|
||||||
yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
|
|
||||||
__yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
|
|
||||||
#ifdef YYLSP_NEEDED
|
|
||||||
yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
|
|
||||||
__yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
|
|
||||||
#endif
|
|
||||||
#endif /* no yyoverflow */
|
|
||||||
|
|
||||||
yyssp = yyss + size - 1;
|
|
||||||
yyvsp = yyvs + size - 1;
|
|
||||||
#ifdef YYLSP_NEEDED
|
|
||||||
yylsp = yyls + size - 1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if YYDEBUG != 0
|
|
||||||
if (yydebug)
|
|
||||||
fprintf(stderr, "Stack size increased to %d\n", yystacksize);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (yyssp >= yyss + yystacksize - 1)
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if YYDEBUG != 0
|
|
||||||
if (yydebug)
|
|
||||||
fprintf(stderr, "Entering state %d\n", yystate);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
goto yybackup;
|
|
||||||
yybackup:
|
|
||||||
|
|
||||||
/* Do appropriate processing given the current state. */
|
|
||||||
/* Read a lookahead token if we need one and don't already have one. */
|
|
||||||
/* yyresume: */
|
|
||||||
|
|
||||||
/* First try to decide what to do without reference to lookahead token. */
|
|
||||||
|
|
||||||
yyn = yypact[yystate];
|
|
||||||
if (yyn == YYFLAG)
|
|
||||||
goto yydefault;
|
|
||||||
|
|
||||||
/* Not known => get a lookahead token if don't already have one. */
|
|
||||||
|
|
||||||
/* yychar is either YYEMPTY or YYEOF
|
|
||||||
or a valid token in external form. */
|
|
||||||
|
|
||||||
if (yychar == YYEMPTY)
|
|
||||||
{
|
|
||||||
#if YYDEBUG != 0
|
|
||||||
if (yydebug)
|
|
||||||
fprintf(stderr, "Reading a token: ");
|
|
||||||
#endif
|
|
||||||
yychar = YYLEX;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert token to internal form (in yychar1) for indexing tables with */
|
|
||||||
|
|
||||||
if (yychar <= 0) /* This means end of input. */
|
|
||||||
{
|
|
||||||
yychar1 = 0;
|
|
||||||
yychar = YYEOF; /* Don't call YYLEX any more */
|
|
||||||
|
|
||||||
#if YYDEBUG != 0
|
|
||||||
if (yydebug)
|
|
||||||
fprintf(stderr, "Now at end of input.\n");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
yychar1 = YYTRANSLATE(yychar);
|
|
||||||
|
|
||||||
#if YYDEBUG != 0
|
|
||||||
if (yydebug)
|
|
||||||
{
|
|
||||||
fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
|
|
||||||
/* Give the individual parser a way to print the precise meaning
|
|
||||||
of a token, for further debugging info. */
|
|
||||||
#ifdef YYPRINT
|
|
||||||
YYPRINT (stderr, yychar, yylval);
|
|
||||||
#endif
|
|
||||||
fprintf (stderr, ")\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
yyn += yychar1;
|
|
||||||
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
|
|
||||||
goto yydefault;
|
|
||||||
|
|
||||||
yyn = yytable[yyn];
|
|
||||||
|
|
||||||
/* yyn is what to do for this token type in this state.
|
|
||||||
Negative => reduce, -yyn is rule number.
|
|
||||||
Positive => shift, yyn is new state.
|
|
||||||
New state is final state => don't bother to shift,
|
|
||||||
just return success.
|
|
||||||
0, or most negative number => error. */
|
|
||||||
|
|
||||||
if (yyn < 0)
|
|
||||||
{
|
|
||||||
if (yyn == YYFLAG)
|
|
||||||
goto yyerrlab;
|
|
||||||
yyn = -yyn;
|
|
||||||
goto yyreduce;
|
|
||||||
}
|
|
||||||
else if (yyn == 0)
|
|
||||||
goto yyerrlab;
|
|
||||||
|
|
||||||
if (yyn == YYFINAL)
|
|
||||||
YYACCEPT;
|
|
||||||
|
|
||||||
/* Shift the lookahead token. */
|
|
||||||
|
|
||||||
#if YYDEBUG != 0
|
|
||||||
if (yydebug)
|
|
||||||
fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Discard the token being shifted unless it is eof. */
|
|
||||||
if (yychar != YYEOF)
|
|
||||||
yychar = YYEMPTY;
|
|
||||||
|
|
||||||
*++yyvsp = yylval;
|
|
||||||
#ifdef YYLSP_NEEDED
|
|
||||||
*++yylsp = yylloc;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* count tokens shifted since error; after three, turn off error status. */
|
|
||||||
if (yyerrstatus) yyerrstatus--;
|
|
||||||
|
|
||||||
yystate = yyn;
|
|
||||||
goto yynewstate;
|
|
||||||
|
|
||||||
/* Do the default action for the current state. */
|
|
||||||
yydefault:
|
|
||||||
|
|
||||||
yyn = yydefact[yystate];
|
|
||||||
if (yyn == 0)
|
|
||||||
goto yyerrlab;
|
|
||||||
|
|
||||||
/* Do a reduction. yyn is the number of a rule to reduce with. */
|
|
||||||
yyreduce:
|
|
||||||
yylen = yyr2[yyn];
|
|
||||||
if (yylen > 0)
|
|
||||||
yyval = yyvsp[1-yylen]; /* implement default value of the action */
|
|
||||||
|
|
||||||
#if YYDEBUG != 0
|
|
||||||
if (yydebug)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
fprintf (stderr, "Reducing via rule %d (line %d), ",
|
|
||||||
yyn, yyrline[yyn]);
|
|
||||||
|
|
||||||
/* Print the symbols being reduced, and their result. */
|
|
||||||
for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
|
|
||||||
fprintf (stderr, "%s ", yytname[yyrhs[i]]);
|
|
||||||
fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
$ /* the action file gets copied in in place of this dollarsign */
|
|
||||||
yyvsp -= yylen;
|
|
||||||
yyssp -= yylen;
|
|
||||||
#ifdef YYLSP_NEEDED
|
|
||||||
yylsp -= yylen;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if YYDEBUG != 0
|
|
||||||
if (yydebug)
|
|
||||||
{
|
|
||||||
short *ssp1 = yyss - 1;
|
|
||||||
fprintf (stderr, "state stack now");
|
|
||||||
while (ssp1 != yyssp)
|
|
||||||
fprintf (stderr, " %d", *++ssp1);
|
|
||||||
fprintf (stderr, "\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*++yyvsp = yyval;
|
|
||||||
|
|
||||||
#ifdef YYLSP_NEEDED
|
|
||||||
yylsp++;
|
|
||||||
if (yylen == 0)
|
|
||||||
{
|
|
||||||
yylsp->first_line = yylloc.first_line;
|
|
||||||
yylsp->first_column = yylloc.first_column;
|
|
||||||
yylsp->last_line = (yylsp-1)->last_line;
|
|
||||||
yylsp->last_column = (yylsp-1)->last_column;
|
|
||||||
yylsp->text = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
yylsp->last_line = (yylsp+yylen-1)->last_line;
|
|
||||||
yylsp->last_column = (yylsp+yylen-1)->last_column;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Now "shift" the result of the reduction.
|
|
||||||
Determine what state that goes to,
|
|
||||||
based on the state we popped back to
|
|
||||||
and the rule number reduced by. */
|
|
||||||
|
|
||||||
yyn = yyr1[yyn];
|
|
||||||
|
|
||||||
yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
|
|
||||||
if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
|
|
||||||
yystate = yytable[yystate];
|
|
||||||
else
|
|
||||||
yystate = yydefgoto[yyn - YYNTBASE];
|
|
||||||
|
|
||||||
goto yynewstate;
|
|
||||||
|
|
||||||
yyerrlab: /* here on detecting error */
|
|
||||||
|
|
||||||
if (! yyerrstatus)
|
|
||||||
/* If not already recovering from an error, report this error. */
|
|
||||||
{
|
|
||||||
++yynerrs;
|
|
||||||
|
|
||||||
#ifdef YYERROR_VERBOSE
|
|
||||||
yyn = yypact[yystate];
|
|
||||||
|
|
||||||
if (yyn > YYFLAG && yyn < YYLAST)
|
|
||||||
{
|
|
||||||
int size = 0;
|
|
||||||
char *msg;
|
|
||||||
int x, count;
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
/* Start X at -yyn if nec to avoid negative indexes in yycheck. */
|
|
||||||
for (x = (yyn < 0 ? -yyn : 0);
|
|
||||||
x < (sizeof(yytname) / sizeof(char *)); x++)
|
|
||||||
if (yycheck[x + yyn] == x)
|
|
||||||
size += strlen(yytname[x]) + 15, count++;
|
|
||||||
msg = (char *) malloc(size + 15);
|
|
||||||
if (msg != 0)
|
|
||||||
{
|
|
||||||
strcpy(msg, "parse error");
|
|
||||||
|
|
||||||
if (count < 5)
|
|
||||||
{
|
|
||||||
count = 0;
|
|
||||||
for (x = (yyn < 0 ? -yyn : 0);
|
|
||||||
x < (sizeof(yytname) / sizeof(char *)); x++)
|
|
||||||
if (yycheck[x + yyn] == x)
|
|
||||||
{
|
|
||||||
strcat(msg, count == 0 ? ", expecting `" : " or `");
|
|
||||||
strcat(msg, yytname[x]);
|
|
||||||
strcat(msg, "'");
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
yyerror(msg);
|
|
||||||
free(msg);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
yyerror ("parse error; also virtual memory exceeded");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif /* YYERROR_VERBOSE */
|
|
||||||
yyerror("parse error");
|
|
||||||
}
|
|
||||||
|
|
||||||
goto yyerrlab1;
|
|
||||||
yyerrlab1: /* here on error raised explicitly by an action */
|
|
||||||
|
|
||||||
if (yyerrstatus == 3)
|
|
||||||
{
|
|
||||||
/* if just tried and failed to reuse lookahead token after an error, discard it. */
|
|
||||||
|
|
||||||
/* return failure if at end of input */
|
|
||||||
if (yychar == YYEOF)
|
|
||||||
YYABORT;
|
|
||||||
|
|
||||||
#if YYDEBUG != 0
|
|
||||||
if (yydebug)
|
|
||||||
fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
yychar = YYEMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Else will try to reuse lookahead token
|
|
||||||
after shifting the error token. */
|
|
||||||
|
|
||||||
yyerrstatus = 3; /* Each real token shifted decrements this */
|
|
||||||
|
|
||||||
goto yyerrhandle;
|
|
||||||
|
|
||||||
yyerrdefault: /* current state does not do anything special for the error token. */
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* This is wrong; only states that explicitly want error tokens
|
|
||||||
should shift them. */
|
|
||||||
yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
|
|
||||||
if (yyn) goto yydefault;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
yyerrpop: /* pop the current state because it cannot handle the error token */
|
|
||||||
|
|
||||||
if (yyssp == yyss) YYABORT;
|
|
||||||
yyvsp--;
|
|
||||||
yystate = *--yyssp;
|
|
||||||
#ifdef YYLSP_NEEDED
|
|
||||||
yylsp--;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if YYDEBUG != 0
|
|
||||||
if (yydebug)
|
|
||||||
{
|
|
||||||
short *ssp1 = yyss - 1;
|
|
||||||
fprintf (stderr, "Error: state stack now");
|
|
||||||
while (ssp1 != yyssp)
|
|
||||||
fprintf (stderr, " %d", *++ssp1);
|
|
||||||
fprintf (stderr, "\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
yyerrhandle:
|
|
||||||
|
|
||||||
yyn = yypact[yystate];
|
|
||||||
if (yyn == YYFLAG)
|
|
||||||
goto yyerrdefault;
|
|
||||||
|
|
||||||
yyn += YYTERROR;
|
|
||||||
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
|
|
||||||
goto yyerrdefault;
|
|
||||||
|
|
||||||
yyn = yytable[yyn];
|
|
||||||
if (yyn < 0)
|
|
||||||
{
|
|
||||||
if (yyn == YYFLAG)
|
|
||||||
goto yyerrpop;
|
|
||||||
yyn = -yyn;
|
|
||||||
goto yyreduce;
|
|
||||||
}
|
|
||||||
else if (yyn == 0)
|
|
||||||
goto yyerrpop;
|
|
||||||
|
|
||||||
if (yyn == YYFINAL)
|
|
||||||
YYACCEPT;
|
|
||||||
|
|
||||||
#if YYDEBUG != 0
|
|
||||||
if (yydebug)
|
|
||||||
fprintf(stderr, "Shifting error token, ");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*++yyvsp = yylval;
|
|
||||||
#ifdef YYLSP_NEEDED
|
|
||||||
*++yylsp = yylloc;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
yystate = yyn;
|
|
||||||
goto yynewstate;
|
|
||||||
}
|
|
||||||
30
tools/data/Makefile.am
Normal file
30
tools/data/Makefile.am
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
## Copyright (C) 2002, 2005-2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
dist_pkgdata_DATA = README bison.m4 \
|
||||||
|
c-like.m4 \
|
||||||
|
c-skel.m4 c.m4 yacc.c glr.c \
|
||||||
|
c++-skel.m4 c++.m4 location.cc lalr1.cc glr.cc stack.hh \
|
||||||
|
java-skel.m4 java.m4 lalr1.java
|
||||||
|
|
||||||
|
m4sugardir = $(pkgdatadir)/m4sugar
|
||||||
|
dist_m4sugar_DATA = m4sugar/m4sugar.m4 m4sugar/foreach.m4
|
||||||
|
|
||||||
|
xsltdir = $(pkgdatadir)/xslt
|
||||||
|
dist_xslt_DATA = \
|
||||||
|
xslt/bison.xsl \
|
||||||
|
xslt/xml2dot.xsl \
|
||||||
|
xslt/xml2text.xsl \
|
||||||
|
xslt/xml2xhtml.xsl
|
||||||
1639
tools/data/Makefile.in
Normal file
1639
tools/data/Makefile.in
Normal file
File diff suppressed because it is too large
Load Diff
70
tools/data/README
Normal file
70
tools/data/README
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
-*- outline -*-
|
||||||
|
|
||||||
|
This directory contains data needed by Bison.
|
||||||
|
|
||||||
|
* Skeletons
|
||||||
|
Bison skeletons: the general shapes of the different parser kinds,
|
||||||
|
that are specialized for specific grammars by the bison program.
|
||||||
|
|
||||||
|
Currently, the supported skeletons are:
|
||||||
|
|
||||||
|
- yacc.c
|
||||||
|
It used to be named bison.simple: it corresponds to C Yacc
|
||||||
|
compatible LALR(1) parsers.
|
||||||
|
|
||||||
|
- lalr1.cc
|
||||||
|
Produces a C++ parser class.
|
||||||
|
|
||||||
|
- lalr1.java
|
||||||
|
Produces a Java parser class.
|
||||||
|
|
||||||
|
- glr.c
|
||||||
|
A Generalized LR C parser based on Bison's LALR(1) tables.
|
||||||
|
|
||||||
|
- glr.cc
|
||||||
|
A Generalized LR C++ parser. Actually a C++ wrapper around glr.c.
|
||||||
|
|
||||||
|
These skeletons are the only ones supported by the Bison team.
|
||||||
|
Because the interface between skeletons and the bison program is not
|
||||||
|
finished, *we are not bound to it*. In particular, Bison is not
|
||||||
|
mature enough for us to consider that ``foreign skeletons'' are
|
||||||
|
supported.
|
||||||
|
|
||||||
|
* m4sugar
|
||||||
|
This directory contains M4sugar, sort of an extended library for M4,
|
||||||
|
which is used by Bison to instantiate the skeletons.
|
||||||
|
|
||||||
|
* xslt
|
||||||
|
This directory contains XSLT programs that transform Bison's XML output
|
||||||
|
into various formats.
|
||||||
|
|
||||||
|
- bison.xsl
|
||||||
|
A library of routines used by the other XSLT programs.
|
||||||
|
|
||||||
|
- xml2dot.xsl
|
||||||
|
Conversion into GraphViz's dot format.
|
||||||
|
|
||||||
|
- xml2text.xsl
|
||||||
|
Conversion into text.
|
||||||
|
|
||||||
|
- xml2xhtml.xsl
|
||||||
|
Conversion into XHTML.
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
|
Copyright (C) 2002, 2008-2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GNU Bison.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
610
tools/data/bison.m4
Normal file
610
tools/data/bison.m4
Normal file
@@ -0,0 +1,610 @@
|
|||||||
|
-*- Autoconf -*-
|
||||||
|
|
||||||
|
# Language-independent M4 Macros for Bison.
|
||||||
|
|
||||||
|
# Copyright (C) 2002, 2004-2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
## ---------------- ##
|
||||||
|
## Identification. ##
|
||||||
|
## ---------------- ##
|
||||||
|
|
||||||
|
# b4_copyright(TITLE, YEARS)
|
||||||
|
# --------------------------
|
||||||
|
m4_define([b4_copyright],
|
||||||
|
[b4_comment([A Bison parser, made by GNU Bison b4_version.])
|
||||||
|
|
||||||
|
b4_comment([$1
|
||||||
|
|
||||||
|
m4_text_wrap([Copyright (C) $2 Free Software Foundation, Inc.], [ ])
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.])
|
||||||
|
|
||||||
|
b4_comment([As a special exception, you may create a larger work that contains
|
||||||
|
part or all of the Bison parser skeleton and distribute that work
|
||||||
|
under terms of your choice, so long as that work isn't itself a
|
||||||
|
parser generator using the skeleton or a modified version thereof
|
||||||
|
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||||
|
the parser skeleton itself, you may (at your option) remove this
|
||||||
|
special exception, which will cause the skeleton and the resulting
|
||||||
|
Bison output files to be licensed under the GNU General Public
|
||||||
|
License without this special exception.
|
||||||
|
|
||||||
|
This special exception was added by the Free Software Foundation in
|
||||||
|
version 2.2 of Bison.])])
|
||||||
|
|
||||||
|
|
||||||
|
## -------- ##
|
||||||
|
## Output. ##
|
||||||
|
## -------- ##
|
||||||
|
|
||||||
|
# b4_output_begin(FILE)
|
||||||
|
# ---------------------
|
||||||
|
# Enable output, i.e., send to diversion 0, expand after "#", and
|
||||||
|
# generate the tag to output into FILE. Must be followed by EOL.
|
||||||
|
m4_define([b4_output_begin],
|
||||||
|
[m4_changecom()
|
||||||
|
m4_divert_push(0)dnl
|
||||||
|
@output(m4_unquote([$1])@)@dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_output_end()
|
||||||
|
# ---------------
|
||||||
|
# Output nothing, restore # as comment character (no expansions after #).
|
||||||
|
m4_define([b4_output_end],
|
||||||
|
[m4_divert_pop(0)
|
||||||
|
m4_changecom([#])
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
## ---------------- ##
|
||||||
|
## Error handling. ##
|
||||||
|
## ---------------- ##
|
||||||
|
|
||||||
|
# The following error handling macros print error directives that should not
|
||||||
|
# become arguments of other macro invocations since they would likely then be
|
||||||
|
# mangled. Thus, they print to stdout directly.
|
||||||
|
|
||||||
|
# b4_cat(TEXT)
|
||||||
|
# ------------
|
||||||
|
# Write TEXT to stdout. Precede the final newline with an @ so that it's
|
||||||
|
# escaped. For example:
|
||||||
|
#
|
||||||
|
# b4_cat([[@complain(invalid input@)]])
|
||||||
|
m4_define([b4_cat],
|
||||||
|
[m4_syscmd([cat <<'_m4eof'
|
||||||
|
]m4_bpatsubst(m4_dquote($1), [_m4eof], [_m4@`eof])[@
|
||||||
|
_m4eof
|
||||||
|
])dnl
|
||||||
|
m4_if(m4_sysval, [0], [], [m4_fatal([$0: cannot write to stdout])])])
|
||||||
|
|
||||||
|
# b4_error(KIND, FORMAT, [ARG1], [ARG2], ...)
|
||||||
|
# -------------------------------------------
|
||||||
|
# Write @KIND(FORMAT@,ARG1@,ARG2@,...@) to stdout.
|
||||||
|
#
|
||||||
|
# For example:
|
||||||
|
#
|
||||||
|
# b4_error([[warn]], [[invalid value for '%s': %s]], [[foo]], [[3]])
|
||||||
|
m4_define([b4_error],
|
||||||
|
[b4_cat([[@]$1[(]$2[]]dnl
|
||||||
|
[m4_if([$#], [2], [],
|
||||||
|
[m4_foreach([b4_arg],
|
||||||
|
m4_dquote(m4_shift(m4_shift($@))),
|
||||||
|
[[@,]b4_arg])])[@)]])])
|
||||||
|
|
||||||
|
# b4_error_at(KIND, START, END, FORMAT, [ARG1], [ARG2], ...)
|
||||||
|
# ----------------------------------------------------------
|
||||||
|
# Write @KIND_at(START@,END@,FORMAT@,ARG1@,ARG2@,...@) to stdout.
|
||||||
|
#
|
||||||
|
# For example:
|
||||||
|
#
|
||||||
|
# b4_error_at([[complain]], [[input.y:2.3]], [[input.y:5.4]],
|
||||||
|
# [[invalid %s]], [[foo]])
|
||||||
|
m4_define([b4_error_at],
|
||||||
|
[b4_cat([[@]$1[_at(]$2[@,]$3[@,]$4[]]dnl
|
||||||
|
[m4_if([$#], [4], [],
|
||||||
|
[m4_foreach([b4_arg],
|
||||||
|
m4_dquote(m4_shift(m4_shift(m4_shift(m4_shift($@))))),
|
||||||
|
[[@,]b4_arg])])[@)]])])
|
||||||
|
|
||||||
|
# b4_warn(FORMAT, [ARG1], [ARG2], ...)
|
||||||
|
# ------------------------------------
|
||||||
|
# Write @warn(FORMAT@,ARG1@,ARG2@,...@) to stdout.
|
||||||
|
#
|
||||||
|
# For example:
|
||||||
|
#
|
||||||
|
# b4_warn([[invalid value for '%s': %s]], [[foo]], [[3]])
|
||||||
|
#
|
||||||
|
# As a simple test suite, this:
|
||||||
|
#
|
||||||
|
# m4_divert(-1)
|
||||||
|
# m4_define([asdf], [ASDF])
|
||||||
|
# m4_define([fsa], [FSA])
|
||||||
|
# m4_define([fdsa], [FDSA])
|
||||||
|
# b4_warn([[[asdf), asdf]]], [[[fsa), fsa]]], [[[fdsa), fdsa]]])
|
||||||
|
# b4_warn([[asdf), asdf]], [[fsa), fsa]], [[fdsa), fdsa]])
|
||||||
|
# b4_warn()
|
||||||
|
# b4_warn(1)
|
||||||
|
# b4_warn(1, 2)
|
||||||
|
#
|
||||||
|
# Should produce this without newlines:
|
||||||
|
#
|
||||||
|
# @warn([asdf), asdf]@,[fsa), fsa]@,[fdsa), fdsa]@)
|
||||||
|
# @warn(asdf), asdf@,fsa), fsa@,fdsa), fdsa@)
|
||||||
|
# @warn(@)
|
||||||
|
# @warn(1@)
|
||||||
|
# @warn(1@,2@)
|
||||||
|
m4_define([b4_warn],
|
||||||
|
[b4_error([[warn]], $@)])
|
||||||
|
|
||||||
|
# b4_warn_at(START, END, FORMAT, [ARG1], [ARG2], ...)
|
||||||
|
# ---------------------------------------------------
|
||||||
|
# Write @warn(START@,END@,FORMAT@,ARG1@,ARG2@,...@) to stdout.
|
||||||
|
#
|
||||||
|
# For example:
|
||||||
|
#
|
||||||
|
# b4_warn_at([[input.y:2.3]], [[input.y:5.4]], [[invalid %s]], [[foo]])
|
||||||
|
m4_define([b4_warn_at],
|
||||||
|
[b4_error_at([[warn]], $@)])
|
||||||
|
|
||||||
|
# b4_complain(FORMAT, [ARG1], [ARG2], ...)
|
||||||
|
# ----------------------------------------
|
||||||
|
# Write @complain(FORMAT@,ARG1@,ARG2@,...@) to stdout.
|
||||||
|
#
|
||||||
|
# See b4_warn example.
|
||||||
|
m4_define([b4_complain],
|
||||||
|
[b4_error([[complain]], $@)])
|
||||||
|
|
||||||
|
# b4_complain_at(START, END, FORMAT, [ARG1], [ARG2], ...)
|
||||||
|
# -------------------------------------------------------
|
||||||
|
# Write @complain(START@,END@,FORMAT@,ARG1@,ARG2@,...@) to stdout.
|
||||||
|
#
|
||||||
|
# See b4_warn_at example.
|
||||||
|
m4_define([b4_complain_at],
|
||||||
|
[b4_error_at([[complain]], $@)])
|
||||||
|
|
||||||
|
# b4_fatal(FORMAT, [ARG1], [ARG2], ...)
|
||||||
|
# -------------------------------------
|
||||||
|
# Write @fatal(FORMAT@,ARG1@,ARG2@,...@) to stdout and exit.
|
||||||
|
#
|
||||||
|
# See b4_warn example.
|
||||||
|
m4_define([b4_fatal],
|
||||||
|
[b4_error([[fatal]], $@)dnl
|
||||||
|
m4_exit(1)])
|
||||||
|
|
||||||
|
# b4_fatal_at(START, END, FORMAT, [ARG1], [ARG2], ...)
|
||||||
|
# ----------------------------------------------------
|
||||||
|
# Write @fatal(START@,END@,FORMAT@,ARG1@,ARG2@,...@) to stdout and exit.
|
||||||
|
#
|
||||||
|
# See b4_warn_at example.
|
||||||
|
m4_define([b4_fatal_at],
|
||||||
|
[b4_error_at([[fatal]], $@)dnl
|
||||||
|
m4_exit(1)])
|
||||||
|
|
||||||
|
|
||||||
|
## ------------ ##
|
||||||
|
## Data Types. ##
|
||||||
|
## ------------ ##
|
||||||
|
|
||||||
|
# b4_ints_in(INT1, INT2, LOW, HIGH)
|
||||||
|
# ---------------------------------
|
||||||
|
# Return 1 iff both INT1 and INT2 are in [LOW, HIGH], 0 otherwise.
|
||||||
|
m4_define([b4_ints_in],
|
||||||
|
[m4_eval([$3 <= $1 && $1 <= $4 && $3 <= $2 && $2 <= $4])])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## ------------------ ##
|
||||||
|
## Decoding options. ##
|
||||||
|
## ------------------ ##
|
||||||
|
|
||||||
|
# b4_flag_if(FLAG, IF-TRUE, IF-FALSE)
|
||||||
|
# -----------------------------------
|
||||||
|
# Run IF-TRUE if b4_FLAG_flag is 1, IF-FALSE if FLAG is 0, otherwise fail.
|
||||||
|
m4_define([b4_flag_if],
|
||||||
|
[m4_case(b4_$1_flag,
|
||||||
|
[0], [$3],
|
||||||
|
[1], [$2],
|
||||||
|
[m4_fatal([invalid $1 value: ]$1)])])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_define_flag_if(FLAG)
|
||||||
|
# -----------------------
|
||||||
|
# Define "b4_FLAG_if(IF-TRUE, IF-FALSE)" that depends on the
|
||||||
|
# value of the Boolean FLAG.
|
||||||
|
m4_define([b4_define_flag_if],
|
||||||
|
[_b4_define_flag_if($[1], $[2], [$1])])
|
||||||
|
|
||||||
|
# _b4_define_flag_if($1, $2, FLAG)
|
||||||
|
# --------------------------------
|
||||||
|
# Work around the impossibility to define macros inside macros,
|
||||||
|
# because issuing `[$1]' is not possible in M4. GNU M4 should provide
|
||||||
|
# $$1 a la M5/TeX.
|
||||||
|
m4_define([_b4_define_flag_if],
|
||||||
|
[m4_if([$1$2], $[1]$[2], [],
|
||||||
|
[m4_fatal([$0: Invalid arguments: $@])])dnl
|
||||||
|
m4_define([b4_$3_if],
|
||||||
|
[b4_flag_if([$3], [$1], [$2])])])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_FLAG_if(IF-TRUE, IF-FALSE)
|
||||||
|
# -----------------------------
|
||||||
|
# Expand IF-TRUE, if FLAG is true, IF-FALSE otherwise.
|
||||||
|
b4_define_flag_if([defines]) # Whether headers are requested.
|
||||||
|
b4_define_flag_if([error_verbose]) # Whether error are verbose.
|
||||||
|
b4_define_flag_if([glr]) # Whether a GLR parser is requested.
|
||||||
|
b4_define_flag_if([locations]) # Whether locations are tracked.
|
||||||
|
b4_define_flag_if([nondeterministic]) # Whether conflicts should be handled.
|
||||||
|
b4_define_flag_if([token_table]) # Whether yytoken_table is demanded.
|
||||||
|
b4_define_flag_if([yacc]) # Whether POSIX Yacc is emulated.
|
||||||
|
|
||||||
|
# yytoken_table is needed to support verbose errors.
|
||||||
|
b4_error_verbose_if([m4_define([b4_token_table_flag], [1])])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## ----------- ##
|
||||||
|
## Synclines. ##
|
||||||
|
## ----------- ##
|
||||||
|
|
||||||
|
# b4_basename(NAME)
|
||||||
|
# -----------------
|
||||||
|
# Similar to POSIX basename; the differences don't matter here.
|
||||||
|
# Beware that NAME is not evaluated.
|
||||||
|
m4_define([b4_basename],
|
||||||
|
[m4_bpatsubst([$1], [^.*/\([^/]+\)/*$], [\1])])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_syncline(LINE, FILE)
|
||||||
|
# -----------------------
|
||||||
|
m4_define([b4_syncline],
|
||||||
|
[b4_flag_if([synclines],
|
||||||
|
[b4_sync_end([__line__], [b4_basename(m4_quote(__file__))])
|
||||||
|
b4_sync_start([$1], [$2])])])
|
||||||
|
|
||||||
|
m4_define([b4_sync_end], [b4_comment([Line $1 of $2])])
|
||||||
|
m4_define([b4_sync_start], [b4_comment([Line $1 of $2])])
|
||||||
|
|
||||||
|
# b4_user_code(USER-CODE)
|
||||||
|
# -----------------------
|
||||||
|
# Emit code from the user, ending it with synclines.
|
||||||
|
m4_define([b4_user_code],
|
||||||
|
[$1
|
||||||
|
b4_syncline([@oline@], [@ofile@])])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_define_user_code(MACRO)
|
||||||
|
# --------------------------
|
||||||
|
# From b4_MACRO, build b4_user_MACRO that includes the synclines.
|
||||||
|
m4_define([b4_define_user_code],
|
||||||
|
[m4_define([b4_user_$1],
|
||||||
|
[b4_user_code([b4_$1])])])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_user_actions
|
||||||
|
# b4_user_initial_action
|
||||||
|
# b4_user_post_prologue
|
||||||
|
# b4_user_pre_prologue
|
||||||
|
# b4_user_stype
|
||||||
|
# ----------------------
|
||||||
|
# Macros that issue user code, ending with synclines.
|
||||||
|
b4_define_user_code([actions])
|
||||||
|
b4_define_user_code([initial_action])
|
||||||
|
b4_define_user_code([post_prologue])
|
||||||
|
b4_define_user_code([pre_prologue])
|
||||||
|
b4_define_user_code([stype])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_check_user_names(WHAT, USER-LIST, BISON-NAMESPACE)
|
||||||
|
# -----------------------------------------------------
|
||||||
|
# Complain if any name of type WHAT is used by the user (as recorded in
|
||||||
|
# USER-LIST) but is not used by Bison (as recorded by macros in the
|
||||||
|
# namespace BISON-NAMESPACE).
|
||||||
|
#
|
||||||
|
# USER-LIST must expand to a list specifying all user occurrences of all names
|
||||||
|
# of type WHAT. Each item in the list must be a triplet specifying one
|
||||||
|
# occurrence: name, start boundary, and end boundary. Empty string names are
|
||||||
|
# fine. An empty list is fine.
|
||||||
|
#
|
||||||
|
# For example, to define b4_foo_user_names to be used for USER-LIST with three
|
||||||
|
# name occurrences and with correct quoting:
|
||||||
|
#
|
||||||
|
# m4_define([b4_foo_user_names],
|
||||||
|
# [[[[[[bar]], [[parser.y:1.7]], [[parser.y:1.16]]]],
|
||||||
|
# [[[[bar]], [[parser.y:5.7]], [[parser.y:5.16]]]],
|
||||||
|
# [[[[baz]], [[parser.y:8.7]], [[parser.y:8.16]]]]]])
|
||||||
|
#
|
||||||
|
# The macro BISON-NAMESPACE(bar) must be defined iff the name bar of type WHAT
|
||||||
|
# is used by Bison (in the front-end or in the skeleton). Empty string names
|
||||||
|
# are fine, but it would be ugly for Bison to actually use one.
|
||||||
|
#
|
||||||
|
# For example, to use b4_foo_bison_names for BISON-NAMESPACE and define that
|
||||||
|
# the names bar and baz are used by Bison:
|
||||||
|
#
|
||||||
|
# m4_define([b4_foo_bison_names(bar)])
|
||||||
|
# m4_define([b4_foo_bison_names(baz)])
|
||||||
|
#
|
||||||
|
# To invoke b4_check_user_names with TYPE foo, with USER-LIST
|
||||||
|
# b4_foo_user_names, with BISON-NAMESPACE b4_foo_bison_names, and with correct
|
||||||
|
# quoting:
|
||||||
|
#
|
||||||
|
# b4_check_user_names([[foo]], [b4_foo_user_names],
|
||||||
|
# [[b4_foo_bison_names]])
|
||||||
|
m4_define([b4_check_user_names],
|
||||||
|
[m4_foreach([b4_occurrence], $2,
|
||||||
|
[m4_pushdef([b4_occurrence], b4_occurrence)dnl
|
||||||
|
m4_pushdef([b4_user_name], m4_car(b4_occurrence))dnl
|
||||||
|
m4_pushdef([b4_start], m4_car(m4_shift(b4_occurrence)))dnl
|
||||||
|
m4_pushdef([b4_end], m4_shift(m4_shift(b4_occurrence)))dnl
|
||||||
|
m4_ifndef($3[(]m4_quote(b4_user_name)[)],
|
||||||
|
[b4_complain_at([b4_start], [b4_end],
|
||||||
|
[[%s '%s' is not used]],
|
||||||
|
[$1], [b4_user_name])])[]dnl
|
||||||
|
m4_popdef([b4_occurrence])dnl
|
||||||
|
m4_popdef([b4_user_name])dnl
|
||||||
|
m4_popdef([b4_start])dnl
|
||||||
|
m4_popdef([b4_end])dnl
|
||||||
|
])])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## --------------------- ##
|
||||||
|
## b4_percent_define_*. ##
|
||||||
|
## --------------------- ##
|
||||||
|
|
||||||
|
|
||||||
|
# b4_percent_define_use(VARIABLE)
|
||||||
|
# -------------------------------
|
||||||
|
# Declare that VARIABLE was used.
|
||||||
|
m4_define([b4_percent_define_use],
|
||||||
|
[m4_define([b4_percent_define_bison_variables(]$1[)])dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
# b4_percent_define_get(VARIABLE, [DEFAULT])
|
||||||
|
# ------------------------------------------
|
||||||
|
# Mimic muscle_percent_define_get in ../src/muscle-tab.h. That is, if
|
||||||
|
# the %define variable VARIABLE is defined, emit its value. Contrary
|
||||||
|
# to its C counterpart, return DEFAULT otherwise. Also, record
|
||||||
|
# Bison's usage of VARIABLE by defining
|
||||||
|
# b4_percent_define_bison_variables(VARIABLE).
|
||||||
|
#
|
||||||
|
# For example:
|
||||||
|
#
|
||||||
|
# b4_percent_define_get([[foo]])
|
||||||
|
m4_define([b4_percent_define_get],
|
||||||
|
[b4_percent_define_use([$1])dnl
|
||||||
|
m4_ifdef([b4_percent_define(]$1[)],
|
||||||
|
[m4_indir([b4_percent_define(]$1[)])],
|
||||||
|
[$2])])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_percent_define_get_loc(VARIABLE)
|
||||||
|
# -----------------------------------
|
||||||
|
# Mimic muscle_percent_define_get_loc in ../src/muscle-tab.h exactly. That is,
|
||||||
|
# if the %define variable VARIABLE is undefined, complain fatally since that's
|
||||||
|
# a Bison or skeleton error. Otherwise, return its definition location in a
|
||||||
|
# form approriate for the first two arguments of b4_warn_at, b4_complain_at, or
|
||||||
|
# b4_fatal_at. Don't record this as a Bison usage of VARIABLE as there's no
|
||||||
|
# reason to suspect that the user-supplied value has yet influenced the output.
|
||||||
|
#
|
||||||
|
# For example:
|
||||||
|
#
|
||||||
|
# b4_complain_at(b4_percent_define_get_loc([[foo]]), [[invalid foo]])
|
||||||
|
m4_define([b4_percent_define_get_loc],
|
||||||
|
[m4_ifdef([b4_percent_define_loc(]$1[)],
|
||||||
|
[m4_pushdef([b4_loc], m4_indir([b4_percent_define_loc(]$1[)]))dnl
|
||||||
|
b4_loc[]dnl
|
||||||
|
m4_popdef([b4_loc])],
|
||||||
|
[b4_fatal([[b4_percent_define_get_loc: undefined %%define variable '%s']], [$1])])])
|
||||||
|
|
||||||
|
# b4_percent_define_get_syncline(VARIABLE)
|
||||||
|
# ----------------------------------------
|
||||||
|
# Mimic muscle_percent_define_get_syncline in ../src/muscle-tab.h exactly.
|
||||||
|
# That is, if the %define variable VARIABLE is undefined, complain fatally
|
||||||
|
# since that's a Bison or skeleton error. Otherwise, return its definition
|
||||||
|
# location as a b4_syncline invocation. Don't record this as a Bison usage of
|
||||||
|
# VARIABLE as there's no reason to suspect that the user-supplied value has yet
|
||||||
|
# influenced the output.
|
||||||
|
#
|
||||||
|
# For example:
|
||||||
|
#
|
||||||
|
# b4_percent_define_get_syncline([[foo]])
|
||||||
|
m4_define([b4_percent_define_get_syncline],
|
||||||
|
[m4_ifdef([b4_percent_define_syncline(]$1[)],
|
||||||
|
[m4_indir([b4_percent_define_syncline(]$1[)])],
|
||||||
|
[b4_fatal([[b4_percent_define_get_syncline: undefined %%define variable '%s']], [$1])])])
|
||||||
|
|
||||||
|
# b4_percent_define_ifdef(VARIABLE, IF-TRUE, [IF-FALSE])
|
||||||
|
# ------------------------------------------------------
|
||||||
|
# Mimic muscle_percent_define_ifdef in ../src/muscle-tab.h exactly. That is,
|
||||||
|
# if the %define variable VARIABLE is defined, expand IF-TRUE, else expand
|
||||||
|
# IF-FALSE. Also, record Bison's usage of VARIABLE by defining
|
||||||
|
# b4_percent_define_bison_variables(VARIABLE).
|
||||||
|
#
|
||||||
|
# For example:
|
||||||
|
#
|
||||||
|
# b4_percent_define_ifdef([[foo]], [[it's defined]], [[it's undefined]])
|
||||||
|
m4_define([b4_percent_define_ifdef],
|
||||||
|
[m4_ifdef([b4_percent_define(]$1[)],
|
||||||
|
[m4_define([b4_percent_define_bison_variables(]$1[)])$2],
|
||||||
|
[$3])])
|
||||||
|
|
||||||
|
# b4_percent_define_flag_if(VARIABLE, IF-TRUE, [IF-FALSE])
|
||||||
|
# --------------------------------------------------------
|
||||||
|
# Mimic muscle_percent_define_flag_if in ../src/muscle-tab.h exactly. That is,
|
||||||
|
# if the %define variable VARIABLE is defined to "" or "true", expand IF-TRUE.
|
||||||
|
# If it is defined to "false", expand IF-FALSE. Complain if it is undefined
|
||||||
|
# (a Bison or skeleton error since the default value should have been set
|
||||||
|
# already) or defined to any other value (possibly a user error). Also, record
|
||||||
|
# Bison's usage of VARIABLE by defining
|
||||||
|
# b4_percent_define_bison_variables(VARIABLE).
|
||||||
|
#
|
||||||
|
# For example:
|
||||||
|
#
|
||||||
|
# b4_percent_define_flag_if([[foo]], [[it's true]], [[it's false]])
|
||||||
|
m4_define([b4_percent_define_flag_if],
|
||||||
|
[b4_percent_define_ifdef([$1],
|
||||||
|
[m4_case(b4_percent_define_get([$1]),
|
||||||
|
[], [$2], [true], [$2], [false], [$3],
|
||||||
|
[m4_expand_once([b4_complain_at(b4_percent_define_get_loc([$1]),
|
||||||
|
[[invalid value for %%define Boolean variable '%s']],
|
||||||
|
[$1])],
|
||||||
|
[[b4_percent_define_flag_if($1)]])])],
|
||||||
|
[b4_fatal([[b4_percent_define_flag_if: undefined %%define variable '%s']], [$1])])])
|
||||||
|
|
||||||
|
# b4_percent_define_default(VARIABLE, DEFAULT)
|
||||||
|
# --------------------------------------------
|
||||||
|
# Mimic muscle_percent_define_default in ../src/muscle-tab.h exactly. That is,
|
||||||
|
# if the %define variable VARIABLE is undefined, set its value to DEFAULT.
|
||||||
|
# Don't record this as a Bison usage of VARIABLE as there's no reason to
|
||||||
|
# suspect that the value has yet influenced the output.
|
||||||
|
#
|
||||||
|
# For example:
|
||||||
|
#
|
||||||
|
# b4_percent_define_default([[foo]], [[default value]])
|
||||||
|
m4_define([b4_percent_define_default],
|
||||||
|
[m4_ifndef([b4_percent_define(]$1[)],
|
||||||
|
[m4_define([b4_percent_define(]$1[)], [$2])dnl
|
||||||
|
m4_define([b4_percent_define_loc(]$1[)],
|
||||||
|
[[[[<skeleton default value>:-1.-1]],
|
||||||
|
[[<skeleton default value>:-1.-1]]]])dnl
|
||||||
|
m4_define([b4_percent_define_syncline(]$1[)], [[]])])])
|
||||||
|
|
||||||
|
# b4_percent_define_check_values(VALUES)
|
||||||
|
# --------------------------------------
|
||||||
|
# Mimic muscle_percent_define_check_values in ../src/muscle-tab.h exactly
|
||||||
|
# except that the VALUES structure is more appropriate for M4. That is, VALUES
|
||||||
|
# is a list of sublists of strings. For each sublist, the first string is the
|
||||||
|
# name of a %define variable, and all remaining strings in that sublist are the
|
||||||
|
# valid values for that variable. Complain if such a variable is undefined (a
|
||||||
|
# Bison error since the default value should have been set already) or defined
|
||||||
|
# to any other value (possibly a user error). Don't record this as a Bison
|
||||||
|
# usage of the variable as there's no reason to suspect that the value has yet
|
||||||
|
# influenced the output.
|
||||||
|
#
|
||||||
|
# For example:
|
||||||
|
#
|
||||||
|
# b4_percent_define_check_values([[[[foo]], [[foo-value1]], [[foo-value2]]]],
|
||||||
|
# [[[[bar]], [[bar-value1]]]])
|
||||||
|
m4_define([b4_percent_define_check_values],
|
||||||
|
[m4_foreach([b4_sublist], m4_quote($@),
|
||||||
|
[_b4_percent_define_check_values(b4_sublist)])])
|
||||||
|
|
||||||
|
m4_define([_b4_percent_define_check_values],
|
||||||
|
[m4_ifdef([b4_percent_define(]$1[)],
|
||||||
|
[m4_pushdef([b4_good_value], [0])dnl
|
||||||
|
m4_if($#, 1, [],
|
||||||
|
[m4_foreach([b4_value], m4_dquote(m4_shift($@)),
|
||||||
|
[m4_if(m4_indir([b4_percent_define(]$1[)]), b4_value,
|
||||||
|
[m4_define([b4_good_value], [1])])])])dnl
|
||||||
|
m4_if(b4_good_value, [0],
|
||||||
|
[b4_complain_at(b4_percent_define_get_loc([$1]),
|
||||||
|
[[invalid value for %%define variable '%s': '%s']],
|
||||||
|
[$1],
|
||||||
|
m4_dquote(m4_indir([b4_percent_define(]$1[)])))
|
||||||
|
m4_foreach([b4_value], m4_dquote(m4_shift($@)),
|
||||||
|
[b4_complain_at(b4_percent_define_get_loc([$1]),
|
||||||
|
[[accepted value: '%s']],
|
||||||
|
m4_dquote(b4_value))])])dnl
|
||||||
|
m4_popdef([b4_good_value])],
|
||||||
|
[b4_fatal([[b4_percent_define_check_values: undefined %%define variable '%s']], [$1])])])
|
||||||
|
|
||||||
|
# b4_percent_code_get([QUALIFIER])
|
||||||
|
# --------------------------------
|
||||||
|
# If any %code blocks for QUALIFIER are defined, emit them beginning with a
|
||||||
|
# comment and ending with synclines and a newline. If QUALIFIER is not
|
||||||
|
# specified or empty, do this for the unqualified %code blocks. Also, record
|
||||||
|
# Bison's usage of QUALIFIER (if specified) by defining
|
||||||
|
# b4_percent_code_bison_qualifiers(QUALIFIER).
|
||||||
|
#
|
||||||
|
# For example, to emit any unqualified %code blocks followed by any %code
|
||||||
|
# blocks for the qualifier foo:
|
||||||
|
#
|
||||||
|
# b4_percent_code_get
|
||||||
|
# b4_percent_code_get([[foo]])
|
||||||
|
m4_define([b4_percent_code_get],
|
||||||
|
[m4_pushdef([b4_macro_name], [[b4_percent_code(]$1[)]])dnl
|
||||||
|
m4_ifval([$1], [m4_define([b4_percent_code_bison_qualifiers(]$1[)])])dnl
|
||||||
|
m4_ifdef(b4_macro_name,
|
||||||
|
[b4_comment([m4_if([$#], [0], [[Unqualified %code]],
|
||||||
|
[["%code ]$1["]])[ blocks.]])
|
||||||
|
b4_user_code([m4_indir(b4_macro_name)])
|
||||||
|
])dnl
|
||||||
|
m4_popdef([b4_macro_name])])
|
||||||
|
|
||||||
|
# b4_percent_code_ifdef(QUALIFIER, IF-TRUE, [IF-FALSE])
|
||||||
|
# -----------------------------------------------------
|
||||||
|
# If any %code blocks for QUALIFIER (or unqualified %code blocks if
|
||||||
|
# QUALIFIER is empty) are defined, expand IF-TRUE, else expand IF-FALSE.
|
||||||
|
# Also, record Bison's usage of QUALIFIER (if specified) by defining
|
||||||
|
# b4_percent_code_bison_qualifiers(QUALIFIER).
|
||||||
|
m4_define([b4_percent_code_ifdef],
|
||||||
|
[m4_ifdef([b4_percent_code(]$1[)],
|
||||||
|
[m4_ifval([$1], [m4_define([b4_percent_code_bison_qualifiers(]$1[)])])$2],
|
||||||
|
[$3])])
|
||||||
|
|
||||||
|
|
||||||
|
## ----------------------------------------------------------- ##
|
||||||
|
## After processing the skeletons, check that all the user's ##
|
||||||
|
## %define variables and %code qualifiers were used by Bison. ##
|
||||||
|
## ----------------------------------------------------------- ##
|
||||||
|
|
||||||
|
m4_define([b4_check_user_names_wrap],
|
||||||
|
[m4_ifdef([b4_percent_]$1[_user_]$2[s],
|
||||||
|
[b4_check_user_names([[%]$1 $2],
|
||||||
|
[b4_percent_]$1[_user_]$2[s],
|
||||||
|
[[b4_percent_]$1[_bison_]$2[s]])])])
|
||||||
|
|
||||||
|
m4_wrap_lifo([
|
||||||
|
b4_check_user_names_wrap([[define]], [[variable]])
|
||||||
|
b4_check_user_names_wrap([[code]], [[qualifier]])
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
## ---------------- ##
|
||||||
|
## Default values. ##
|
||||||
|
## ---------------- ##
|
||||||
|
|
||||||
|
# m4_define_default([b4_lex_param], []) dnl breaks other skeletons
|
||||||
|
m4_define_default([b4_pre_prologue], [])
|
||||||
|
m4_define_default([b4_post_prologue], [])
|
||||||
|
m4_define_default([b4_epilogue], [])
|
||||||
|
m4_define_default([b4_parse_param], [])
|
||||||
|
|
||||||
|
# The initial column and line.
|
||||||
|
m4_define_default([b4_location_initial_column], [1])
|
||||||
|
m4_define_default([b4_location_initial_line], [1])
|
||||||
|
|
||||||
|
# Sanity checks.
|
||||||
|
b4_percent_define_ifdef([api.prefix],
|
||||||
|
[m4_ifdef([b4_prefix],
|
||||||
|
[b4_complain_at(b4_percent_define_get_loc([api.prefix]),
|
||||||
|
[['%s' and '%s' cannot be used together]],
|
||||||
|
[%name-prefix],
|
||||||
|
[%define api.prefix])])])
|
||||||
26
tools/data/c++-skel.m4
Normal file
26
tools/data/c++-skel.m4
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
-*- Autoconf -*-
|
||||||
|
|
||||||
|
# C++ skeleton dispatching for Bison.
|
||||||
|
|
||||||
|
# Copyright (C) 2006-2007, 2009-2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
b4_glr_if( [m4_define([b4_used_skeleton], [b4_pkgdatadir/[glr.cc]])])
|
||||||
|
b4_nondeterministic_if([m4_define([b4_used_skeleton], [b4_pkgdatadir/[glr.cc]])])
|
||||||
|
|
||||||
|
m4_define_default([b4_used_skeleton], [b4_pkgdatadir/[lalr1.cc]])
|
||||||
|
m4_define_default([b4_skeleton], ["b4_basename(b4_used_skeleton)"])
|
||||||
|
|
||||||
|
m4_include(b4_used_skeleton)
|
||||||
205
tools/data/c++.m4
Normal file
205
tools/data/c++.m4
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
-*- Autoconf -*-
|
||||||
|
|
||||||
|
# C++ skeleton for Bison
|
||||||
|
|
||||||
|
# Copyright (C) 2002-2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
m4_include(b4_pkgdatadir/[c.m4])
|
||||||
|
|
||||||
|
## ---------------- ##
|
||||||
|
## Default values. ##
|
||||||
|
## ---------------- ##
|
||||||
|
|
||||||
|
# Default parser class name.
|
||||||
|
b4_percent_define_default([[parser_class_name]], [[parser]])
|
||||||
|
|
||||||
|
# Don't do that so that we remember whether we're using a user
|
||||||
|
# request, or the default value.
|
||||||
|
#
|
||||||
|
# b4_percent_define_default([[api.location.type]], [[location]])
|
||||||
|
|
||||||
|
b4_percent_define_default([[filename_type]], [[std::string]])
|
||||||
|
b4_percent_define_default([[namespace]], m4_defn([b4_prefix]))
|
||||||
|
b4_percent_define_default([[global_tokens_and_yystype]], [[false]])
|
||||||
|
b4_percent_define_default([[define_location_comparison]],
|
||||||
|
[m4_if(b4_percent_define_get([[filename_type]]),
|
||||||
|
[std::string], [[true]], [[false]])])
|
||||||
|
|
||||||
|
|
||||||
|
## ----------- ##
|
||||||
|
## Namespace. ##
|
||||||
|
## ----------- ##
|
||||||
|
|
||||||
|
m4_define([b4_namespace_ref], [b4_percent_define_get([[namespace]])])
|
||||||
|
|
||||||
|
# Don't permit an empty b4_namespace_ref. Any `::parser::foo' appended to it
|
||||||
|
# would compile as an absolute reference with `parser' in the global namespace.
|
||||||
|
# b4_namespace_open would open an anonymous namespace and thus establish
|
||||||
|
# internal linkage. This would compile. However, it's cryptic, and internal
|
||||||
|
# linkage for the parser would be specified in all translation units that
|
||||||
|
# include the header, which is always generated. If we ever need to permit
|
||||||
|
# internal linkage somehow, surely we can find a cleaner approach.
|
||||||
|
m4_if(m4_bregexp(b4_namespace_ref, [^[ ]*$]), [-1], [],
|
||||||
|
[b4_complain_at(b4_percent_define_get_loc([[namespace]]),
|
||||||
|
[[namespace reference is empty]])])
|
||||||
|
|
||||||
|
# Instead of assuming the C++ compiler will do it, Bison should reject any
|
||||||
|
# invalid b4_namepsace_ref that would be converted to a valid
|
||||||
|
# b4_namespace_open. The problem is that Bison doesn't always output
|
||||||
|
# b4_namespace_ref to uncommented code but should reserve the ability to do so
|
||||||
|
# in future releases without risking breaking any existing user grammars.
|
||||||
|
# Specifically, don't allow empty names as b4_namespace_open would just convert
|
||||||
|
# those into anonymous namespaces, and that might tempt some users.
|
||||||
|
m4_if(m4_bregexp(b4_namespace_ref, [::[ ]*::]), [-1], [],
|
||||||
|
[b4_complain_at(b4_percent_define_get_loc([[namespace]]),
|
||||||
|
[[namespace reference has consecutive "::"]])])
|
||||||
|
m4_if(m4_bregexp(b4_namespace_ref, [::[ ]*$]), [-1], [],
|
||||||
|
[b4_complain_at(b4_percent_define_get_loc([[namespace]]),
|
||||||
|
[[namespace reference has a trailing "::"]])])
|
||||||
|
|
||||||
|
m4_define([b4_namespace_open],
|
||||||
|
[b4_user_code([b4_percent_define_get_syncline([[namespace]])
|
||||||
|
[namespace ]m4_bpatsubst(m4_dquote(m4_bpatsubst(m4_dquote(b4_namespace_ref),
|
||||||
|
[^\(.\)[ ]*::], [\1])),
|
||||||
|
[::], [ { namespace ])[ {]])])
|
||||||
|
|
||||||
|
m4_define([b4_namespace_close],
|
||||||
|
[b4_user_code([b4_percent_define_get_syncline([[namespace]])
|
||||||
|
m4_bpatsubst(m4_dquote(m4_bpatsubst(m4_dquote(b4_namespace_ref[ ]),
|
||||||
|
[^\(.\)[ ]*\(::\)?\([^][:]\|:[^:]\)*],
|
||||||
|
[\1])),
|
||||||
|
[::\([^][:]\|:[^:]\)*], [} ])[} // ]b4_namespace_ref])])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_token_enums(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER)
|
||||||
|
# -----------------------------------------------------
|
||||||
|
# Output the definition of the tokens as enums.
|
||||||
|
m4_define([b4_token_enums],
|
||||||
|
[/* Tokens. */
|
||||||
|
enum yytokentype {
|
||||||
|
m4_map_sep([ b4_token_enum], [,
|
||||||
|
],
|
||||||
|
[$@])
|
||||||
|
};
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## ----------------- ##
|
||||||
|
## Semantic Values. ##
|
||||||
|
## ----------------- ##
|
||||||
|
|
||||||
|
|
||||||
|
# b4_lhs_value([TYPE])
|
||||||
|
# --------------------
|
||||||
|
# Expansion of $<TYPE>$.
|
||||||
|
m4_define([b4_lhs_value],
|
||||||
|
[(yyval[]m4_ifval([$1], [.$1]))])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_rhs_value(RULE-LENGTH, NUM, [TYPE])
|
||||||
|
# --------------------------------------
|
||||||
|
# Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
|
||||||
|
# symbols on RHS.
|
||||||
|
m4_define([b4_rhs_value],
|
||||||
|
[(yysemantic_stack_@{($1) - ($2)@}m4_ifval([$3], [.$3]))])
|
||||||
|
|
||||||
|
# b4_lhs_location()
|
||||||
|
# -----------------
|
||||||
|
# Expansion of @$.
|
||||||
|
m4_define([b4_lhs_location],
|
||||||
|
[(yyloc)])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_rhs_location(RULE-LENGTH, NUM)
|
||||||
|
# ---------------------------------
|
||||||
|
# Expansion of @NUM, where the current rule has RULE-LENGTH symbols
|
||||||
|
# on RHS.
|
||||||
|
m4_define([b4_rhs_location],
|
||||||
|
[(yylocation_stack_@{($1) - ($2)@})])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_parse_param_decl
|
||||||
|
# -------------------
|
||||||
|
# Extra formal arguments of the constructor.
|
||||||
|
# Change the parameter names from "foo" into "foo_yyarg", so that
|
||||||
|
# there is no collision bw the user chosen attribute name, and the
|
||||||
|
# argument name in the constructor.
|
||||||
|
m4_define([b4_parse_param_decl],
|
||||||
|
[m4_ifset([b4_parse_param],
|
||||||
|
[m4_map_sep([b4_parse_param_decl_1], [, ], [b4_parse_param])])])
|
||||||
|
|
||||||
|
m4_define([b4_parse_param_decl_1],
|
||||||
|
[$1_yyarg])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# b4_parse_param_cons
|
||||||
|
# -------------------
|
||||||
|
# Extra initialisations of the constructor.
|
||||||
|
m4_define([b4_parse_param_cons],
|
||||||
|
[m4_ifset([b4_parse_param],
|
||||||
|
[
|
||||||
|
b4_cc_constructor_calls(b4_parse_param)])])
|
||||||
|
m4_define([b4_cc_constructor_calls],
|
||||||
|
[m4_map_sep([b4_cc_constructor_call], [,
|
||||||
|
], [$@])])
|
||||||
|
m4_define([b4_cc_constructor_call],
|
||||||
|
[$2 ($2_yyarg)])
|
||||||
|
|
||||||
|
# b4_parse_param_vars
|
||||||
|
# -------------------
|
||||||
|
# Extra instance variables.
|
||||||
|
m4_define([b4_parse_param_vars],
|
||||||
|
[m4_ifset([b4_parse_param],
|
||||||
|
[
|
||||||
|
/* User arguments. */
|
||||||
|
b4_cc_var_decls(b4_parse_param)])])
|
||||||
|
m4_define([b4_cc_var_decls],
|
||||||
|
[m4_map_sep([b4_cc_var_decl], [
|
||||||
|
], [$@])])
|
||||||
|
m4_define([b4_cc_var_decl],
|
||||||
|
[ $1;])
|
||||||
|
|
||||||
|
|
||||||
|
## ---------##
|
||||||
|
## Values. ##
|
||||||
|
## ---------##
|
||||||
|
|
||||||
|
# b4_yylloc_default_define
|
||||||
|
# ------------------------
|
||||||
|
# Define YYLLOC_DEFAULT.
|
||||||
|
m4_define([b4_yylloc_default_define],
|
||||||
|
[[/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
|
||||||
|
If N is 0, then set CURRENT to the empty location which ends
|
||||||
|
the previous symbol: RHS[0] (always defined). */
|
||||||
|
|
||||||
|
# ifndef YYLLOC_DEFAULT
|
||||||
|
# define YYLLOC_DEFAULT(Current, Rhs, N) \
|
||||||
|
do \
|
||||||
|
if (N) \
|
||||||
|
{ \
|
||||||
|
(Current).begin = YYRHSLOC (Rhs, 1).begin; \
|
||||||
|
(Current).end = YYRHSLOC (Rhs, N).end; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
(Current).begin = (Current).end = YYRHSLOC (Rhs, 0).end; \
|
||||||
|
} \
|
||||||
|
while (/*CONSTCOND*/ false)
|
||||||
|
# endif
|
||||||
|
]])
|
||||||
44
tools/data/c-like.m4
Normal file
44
tools/data/c-like.m4
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
-*- Autoconf -*-
|
||||||
|
|
||||||
|
# Common code for C-like languages (C, C++, Java, etc.)
|
||||||
|
|
||||||
|
# Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# b4_dollar_dollar_(VALUE, FIELD, DEFAULT-FIELD)
|
||||||
|
# ----------------------------------------------
|
||||||
|
# If FIELD (or DEFAULT-FIELD) is non-null, return "VALUE.FIELD",
|
||||||
|
# otherwise just VALUE. Be sure to pass "(VALUE)" is VALUE is a
|
||||||
|
# pointer.
|
||||||
|
m4_define([b4_dollar_dollar_],
|
||||||
|
[m4_if([$2], [[]],
|
||||||
|
[m4_ifval([$3], [($1.$3)],
|
||||||
|
[$1])],
|
||||||
|
[($1.$2)])])
|
||||||
|
|
||||||
|
# b4_dollar_pushdef(VALUE-POINTER, DEFAULT-FIELD, LOCATION)
|
||||||
|
# b4_dollar_popdef
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
# Define b4_dollar_dollar for VALUE and DEFAULT-FIELD,
|
||||||
|
# and b4_at_dollar for LOCATION.
|
||||||
|
m4_define([b4_dollar_pushdef],
|
||||||
|
[m4_pushdef([b4_dollar_dollar],
|
||||||
|
[b4_dollar_dollar_([$1], m4_dquote($][1), [$2])])dnl
|
||||||
|
m4_pushdef([b4_at_dollar], [$3])dnl
|
||||||
|
])
|
||||||
|
m4_define([b4_dollar_popdef],
|
||||||
|
[m4_popdef([b4_at_dollar])dnl
|
||||||
|
m4_popdef([b4_dollar_dollar])dnl
|
||||||
|
])
|
||||||
26
tools/data/c-skel.m4
Normal file
26
tools/data/c-skel.m4
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
-*- Autoconf -*-
|
||||||
|
|
||||||
|
# C skeleton dispatching for Bison.
|
||||||
|
|
||||||
|
# Copyright (C) 2006-2007, 2009-2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
b4_glr_if( [m4_define([b4_used_skeleton], [b4_pkgdatadir/[glr.c]])])
|
||||||
|
b4_nondeterministic_if([m4_define([b4_used_skeleton], [b4_pkgdatadir/[glr.c]])])
|
||||||
|
|
||||||
|
m4_define_default([b4_used_skeleton], [b4_pkgdatadir/[yacc.c]])
|
||||||
|
m4_define_default([b4_skeleton], ["b4_basename(b4_used_skeleton)"])
|
||||||
|
|
||||||
|
m4_include(b4_used_skeleton)
|
||||||
722
tools/data/c.m4
Normal file
722
tools/data/c.m4
Normal file
@@ -0,0 +1,722 @@
|
|||||||
|
-*- Autoconf -*-
|
||||||
|
|
||||||
|
# C M4 Macros for Bison.
|
||||||
|
|
||||||
|
# Copyright (C) 2002, 2004-2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
m4_include(b4_pkgdatadir/[c-like.m4])
|
||||||
|
|
||||||
|
# b4_tocpp(STRING)
|
||||||
|
# ----------------
|
||||||
|
# Convert STRING into a valid C macro name.
|
||||||
|
m4_define([b4_tocpp],
|
||||||
|
[m4_toupper(m4_bpatsubst(m4_quote($1), [[^a-zA-Z0-9]+], [_]))])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_cpp_guard(FILE)
|
||||||
|
# ------------------
|
||||||
|
# A valid C macro name to use as a CPP header guard for FILE.
|
||||||
|
m4_define([b4_cpp_guard],
|
||||||
|
[[YY_]b4_tocpp(m4_defn([b4_prefix])/[$1])[_INCLUDED]])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_cpp_guard_open(FILE)
|
||||||
|
# b4_cpp_guard_close(FILE)
|
||||||
|
# ------------------------
|
||||||
|
# If FILE does not expand to nothing, open/close CPP inclusion guards for FILE.
|
||||||
|
m4_define([b4_cpp_guard_open],
|
||||||
|
[m4_ifval(m4_quote($1),
|
||||||
|
[#ifndef b4_cpp_guard([$1])
|
||||||
|
# define b4_cpp_guard([$1])])])
|
||||||
|
|
||||||
|
m4_define([b4_cpp_guard_close],
|
||||||
|
[m4_ifval(m4_quote($1),
|
||||||
|
[#endif b4_comment([!b4_cpp_guard([$1])])])])
|
||||||
|
|
||||||
|
|
||||||
|
## ---------------- ##
|
||||||
|
## Identification. ##
|
||||||
|
## ---------------- ##
|
||||||
|
|
||||||
|
# b4_comment(TEXT)
|
||||||
|
# ----------------
|
||||||
|
m4_define([b4_comment], [/* m4_bpatsubst([$1], [
|
||||||
|
], [
|
||||||
|
]) */])
|
||||||
|
|
||||||
|
# b4_identification
|
||||||
|
# -----------------
|
||||||
|
# Depends on individual skeletons to define b4_pure_flag, b4_push_flag, or
|
||||||
|
# b4_pull_flag if they use the values of the %define variables api.pure or
|
||||||
|
# api.push-pull.
|
||||||
|
m4_define([b4_identification],
|
||||||
|
[[/* Identify Bison output. */
|
||||||
|
#define YYBISON 1
|
||||||
|
|
||||||
|
/* Bison version. */
|
||||||
|
#define YYBISON_VERSION "]b4_version["
|
||||||
|
|
||||||
|
/* Skeleton name. */
|
||||||
|
#define YYSKELETON_NAME ]b4_skeleton[]m4_ifdef([b4_pure_flag], [[
|
||||||
|
|
||||||
|
/* Pure parsers. */
|
||||||
|
#define YYPURE ]b4_pure_flag])[]m4_ifdef([b4_push_flag], [[
|
||||||
|
|
||||||
|
/* Push parsers. */
|
||||||
|
#define YYPUSH ]b4_push_flag])[]m4_ifdef([b4_pull_flag], [[
|
||||||
|
|
||||||
|
/* Pull parsers. */
|
||||||
|
#define YYPULL ]b4_pull_flag])[
|
||||||
|
]])
|
||||||
|
|
||||||
|
|
||||||
|
## ---------------- ##
|
||||||
|
## Default values. ##
|
||||||
|
## ---------------- ##
|
||||||
|
|
||||||
|
# b4_api_prefix, b4_api_PREFIX
|
||||||
|
# ----------------------------
|
||||||
|
# Corresponds to %define api.prefix
|
||||||
|
b4_percent_define_default([[api.prefix]], [[yy]])
|
||||||
|
m4_define([b4_api_prefix],
|
||||||
|
[b4_percent_define_get([[api.prefix]])])
|
||||||
|
m4_define([b4_api_PREFIX],
|
||||||
|
[m4_toupper(b4_api_prefix)])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_prefix
|
||||||
|
# ---------
|
||||||
|
# If the %name-prefix is not given, it is api.prefix.
|
||||||
|
m4_define_default([b4_prefix], [b4_api_prefix])
|
||||||
|
|
||||||
|
# If the %union is not named, its name is YYSTYPE.
|
||||||
|
m4_define_default([b4_union_name], [b4_api_PREFIX[]STYPE])
|
||||||
|
|
||||||
|
|
||||||
|
## ------------------------ ##
|
||||||
|
## Pure/impure interfaces. ##
|
||||||
|
## ------------------------ ##
|
||||||
|
|
||||||
|
# b4_user_args
|
||||||
|
# ------------
|
||||||
|
m4_define([b4_user_args],
|
||||||
|
[m4_ifset([b4_parse_param], [, b4_c_args(b4_parse_param)])])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_parse_param
|
||||||
|
# --------------
|
||||||
|
# If defined, b4_parse_param arrives double quoted, but below we prefer
|
||||||
|
# it to be single quoted.
|
||||||
|
m4_define([b4_parse_param],
|
||||||
|
b4_parse_param)
|
||||||
|
|
||||||
|
|
||||||
|
# b4_parse_param_for(DECL, FORMAL, BODY)
|
||||||
|
# ---------------------------------------
|
||||||
|
# Iterate over the user parameters, binding the declaration to DECL,
|
||||||
|
# the formal name to FORMAL, and evaluating the BODY.
|
||||||
|
m4_define([b4_parse_param_for],
|
||||||
|
[m4_foreach([$1_$2], m4_defn([b4_parse_param]),
|
||||||
|
[m4_pushdef([$1], m4_unquote(m4_car($1_$2)))dnl
|
||||||
|
m4_pushdef([$2], m4_shift($1_$2))dnl
|
||||||
|
$3[]dnl
|
||||||
|
m4_popdef([$2])dnl
|
||||||
|
m4_popdef([$1])dnl
|
||||||
|
])])
|
||||||
|
|
||||||
|
# b4_parse_param_use
|
||||||
|
# ------------------
|
||||||
|
# `YYUSE' all the parse-params.
|
||||||
|
m4_define([b4_parse_param_use],
|
||||||
|
[b4_parse_param_for([Decl], [Formal], [ YYUSE (Formal);
|
||||||
|
])dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
## ------------ ##
|
||||||
|
## Data Types. ##
|
||||||
|
## ------------ ##
|
||||||
|
|
||||||
|
# b4_int_type(MIN, MAX)
|
||||||
|
# ---------------------
|
||||||
|
# Return the smallest int type able to handle numbers ranging from
|
||||||
|
# MIN to MAX (included).
|
||||||
|
m4_define([b4_int_type],
|
||||||
|
[m4_if(b4_ints_in($@, [0], [255]), [1], [unsigned char],
|
||||||
|
b4_ints_in($@, [-128], [127]), [1], [signed char],
|
||||||
|
|
||||||
|
b4_ints_in($@, [0], [65535]), [1], [unsigned short int],
|
||||||
|
b4_ints_in($@, [-32768], [32767]), [1], [short int],
|
||||||
|
|
||||||
|
m4_eval([0 <= $1]), [1], [unsigned int],
|
||||||
|
|
||||||
|
[int])])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_int_type_for(NAME)
|
||||||
|
# ---------------------
|
||||||
|
# Return the smallest int type able to handle numbers ranging from
|
||||||
|
# `NAME_min' to `NAME_max' (included).
|
||||||
|
m4_define([b4_int_type_for],
|
||||||
|
[b4_int_type($1_min, $1_max)])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_table_value_equals(TABLE, VALUE, LITERAL)
|
||||||
|
# --------------------------------------------
|
||||||
|
# Without inducing a comparison warning from the compiler, check if the
|
||||||
|
# literal value LITERAL equals VALUE from table TABLE, which must have
|
||||||
|
# TABLE_min and TABLE_max defined. YYID must be defined as an identity
|
||||||
|
# function that suppresses warnings about constant conditions.
|
||||||
|
m4_define([b4_table_value_equals],
|
||||||
|
[m4_if(m4_eval($3 < m4_indir([b4_]$1[_min])
|
||||||
|
|| m4_indir([b4_]$1[_max]) < $3), [1],
|
||||||
|
[[YYID (0)]],
|
||||||
|
[(!!(($2) == ($3)))])])
|
||||||
|
|
||||||
|
|
||||||
|
## ---------##
|
||||||
|
## Values. ##
|
||||||
|
## ---------##
|
||||||
|
|
||||||
|
|
||||||
|
# b4_null_define
|
||||||
|
# --------------
|
||||||
|
# Portability issues: define a YY_NULL appropriate for the current
|
||||||
|
# language (C, C++98, or C++11).
|
||||||
|
m4_define([b4_null_define],
|
||||||
|
[# ifndef YY_NULL
|
||||||
|
# if defined __cplusplus && 201103L <= __cplusplus
|
||||||
|
# define YY_NULL nullptr
|
||||||
|
# else
|
||||||
|
# define YY_NULL 0
|
||||||
|
# endif
|
||||||
|
# endif[]dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_null
|
||||||
|
# -------
|
||||||
|
# Return a null pointer constant.
|
||||||
|
m4_define([b4_null], [YY_NULL])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## ------------------------- ##
|
||||||
|
## Assigning token numbers. ##
|
||||||
|
## ------------------------- ##
|
||||||
|
|
||||||
|
# b4_token_define(TOKEN-NAME, TOKEN-NUMBER)
|
||||||
|
# -----------------------------------------
|
||||||
|
# Output the definition of this token as #define.
|
||||||
|
m4_define([b4_token_define],
|
||||||
|
[#define $1 $2
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_token_defines(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER)
|
||||||
|
# -------------------------------------------------------
|
||||||
|
# Output the definition of the tokens (if there are) as #defines.
|
||||||
|
m4_define([b4_token_defines],
|
||||||
|
[m4_if([$#$1], [1], [],
|
||||||
|
[/* Tokens. */
|
||||||
|
m4_map([b4_token_define], [$@])])
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_token_enum(TOKEN-NAME, TOKEN-NUMBER)
|
||||||
|
# ---------------------------------------
|
||||||
|
# Output the definition of this token as an enum.
|
||||||
|
m4_define([b4_token_enum],
|
||||||
|
[$1 = $2])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_token_enums(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER)
|
||||||
|
# -----------------------------------------------------
|
||||||
|
# Output the definition of the tokens (if there are) as enums.
|
||||||
|
m4_define([b4_token_enums],
|
||||||
|
[m4_if([$#$1], [1], [],
|
||||||
|
[[/* Tokens. */
|
||||||
|
#ifndef ]b4_api_PREFIX[TOKENTYPE
|
||||||
|
# define ]b4_api_PREFIX[TOKENTYPE
|
||||||
|
/* Put the tokens into the symbol table, so that GDB and other debuggers
|
||||||
|
know about them. */
|
||||||
|
enum ]b4_api_prefix[tokentype {
|
||||||
|
]m4_map_sep([ b4_token_enum], [,
|
||||||
|
],
|
||||||
|
[$@])[
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
]])])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_token_enums_defines(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER)
|
||||||
|
# -------------------------------------------------------------
|
||||||
|
# Output the definition of the tokens (if there are any) as enums and, if POSIX
|
||||||
|
# Yacc is enabled, as #defines.
|
||||||
|
m4_define([b4_token_enums_defines],
|
||||||
|
[b4_token_enums($@)b4_yacc_if([b4_token_defines($@)], [])
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## --------------------------------------------- ##
|
||||||
|
## Defining C functions in both K&R and ANSI-C. ##
|
||||||
|
## --------------------------------------------- ##
|
||||||
|
|
||||||
|
|
||||||
|
# b4_modern_c
|
||||||
|
# -----------
|
||||||
|
# A predicate useful in #if to determine whether C is ancient or modern.
|
||||||
|
#
|
||||||
|
# If __STDC__ is defined, the compiler is modern. IBM xlc 7.0 when run
|
||||||
|
# as 'cc' doesn't define __STDC__ (or __STDC_VERSION__) for pedantic
|
||||||
|
# reasons, but it defines __C99__FUNC__ so check that as well.
|
||||||
|
# Microsoft C normally doesn't define these macros, but it defines _MSC_VER.
|
||||||
|
# Consider a C++ compiler to be modern if it defines __cplusplus.
|
||||||
|
#
|
||||||
|
m4_define([b4_c_modern],
|
||||||
|
[[(defined __STDC__ || defined __C99__FUNC__ \
|
||||||
|
|| defined __cplusplus || defined _MSC_VER)]])
|
||||||
|
|
||||||
|
# b4_c_function_def(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
|
||||||
|
# ----------------------------------------------------------
|
||||||
|
# Declare the function NAME.
|
||||||
|
m4_define([b4_c_function_def],
|
||||||
|
[#if b4_c_modern
|
||||||
|
b4_c_ansi_function_def($@)
|
||||||
|
#else
|
||||||
|
$2
|
||||||
|
$1 (b4_c_knr_formal_names(m4_shift2($@)))
|
||||||
|
b4_c_knr_formal_decls(m4_shift2($@))
|
||||||
|
#endif[]dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_c_ansi_function_def(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
# Declare the function NAME in ANSI.
|
||||||
|
m4_define([b4_c_ansi_function_def],
|
||||||
|
[$2
|
||||||
|
$1 (b4_c_ansi_formals(m4_shift2($@)))[]dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_c_ansi_formals([DECL1, NAME1], ...)
|
||||||
|
# --------------------------------------
|
||||||
|
# Output the arguments ANSI-C definition.
|
||||||
|
m4_define([b4_c_ansi_formals],
|
||||||
|
[m4_if([$#], [0], [void],
|
||||||
|
[$#$1], [1], [void],
|
||||||
|
[m4_map_sep([b4_c_ansi_formal], [, ], [$@])])])
|
||||||
|
|
||||||
|
m4_define([b4_c_ansi_formal],
|
||||||
|
[$1])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_c_knr_formal_names([DECL1, NAME1], ...)
|
||||||
|
# ------------------------------------------
|
||||||
|
# Output the argument names.
|
||||||
|
m4_define([b4_c_knr_formal_names],
|
||||||
|
[m4_map_sep([b4_c_knr_formal_name], [, ], [$@])])
|
||||||
|
|
||||||
|
m4_define([b4_c_knr_formal_name],
|
||||||
|
[$2])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_c_knr_formal_decls([DECL1, NAME1], ...)
|
||||||
|
# ------------------------------------------
|
||||||
|
# Output the K&R argument declarations.
|
||||||
|
m4_define([b4_c_knr_formal_decls],
|
||||||
|
[m4_map_sep([b4_c_knr_formal_decl],
|
||||||
|
[
|
||||||
|
],
|
||||||
|
[$@])])
|
||||||
|
|
||||||
|
m4_define([b4_c_knr_formal_decl],
|
||||||
|
[ $1;])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## ------------------------------------------------------------ ##
|
||||||
|
## Declaring (prototyping) C functions in both K&R and ANSI-C. ##
|
||||||
|
## ------------------------------------------------------------ ##
|
||||||
|
|
||||||
|
|
||||||
|
# b4_c_ansi_function_decl(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
|
||||||
|
# ----------------------------------------------------------------
|
||||||
|
# Declare the function NAME ANSI C style.
|
||||||
|
m4_define([b4_c_ansi_function_decl],
|
||||||
|
[$2 $1 (b4_c_ansi_formals(m4_shift2($@)));[]dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# b4_c_function_decl(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
|
||||||
|
# -----------------------------------------------------------
|
||||||
|
# Declare the function NAME in both K&R and ANSI C.
|
||||||
|
m4_define([b4_c_function_decl],
|
||||||
|
[#if defined __STDC__ || defined __cplusplus
|
||||||
|
b4_c_ansi_function_decl($@)
|
||||||
|
#else
|
||||||
|
$2 $1 ();
|
||||||
|
#endif[]dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## --------------------- ##
|
||||||
|
## Calling C functions. ##
|
||||||
|
## --------------------- ##
|
||||||
|
|
||||||
|
|
||||||
|
# b4_c_function_call(NAME, RETURN-VALUE, [DECL1, NAME1], ...)
|
||||||
|
# -----------------------------------------------------------
|
||||||
|
# Call the function NAME with arguments NAME1, NAME2 etc.
|
||||||
|
m4_define([b4_c_function_call],
|
||||||
|
[$1 (b4_c_args(m4_shift2($@)))[]dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_c_args([DECL1, NAME1], ...)
|
||||||
|
# ------------------------------
|
||||||
|
# Output the arguments NAME1, NAME2...
|
||||||
|
m4_define([b4_c_args],
|
||||||
|
[m4_map_sep([b4_c_arg], [, ], [$@])])
|
||||||
|
|
||||||
|
m4_define([b4_c_arg],
|
||||||
|
[$2])
|
||||||
|
|
||||||
|
|
||||||
|
## ----------- ##
|
||||||
|
## Synclines. ##
|
||||||
|
## ----------- ##
|
||||||
|
|
||||||
|
# b4_sync_start(LINE, FILE)
|
||||||
|
# -----------------------
|
||||||
|
m4_define([b4_sync_start], [[#]line $1 $2])
|
||||||
|
|
||||||
|
|
||||||
|
## -------------- ##
|
||||||
|
## User actions. ##
|
||||||
|
## -------------- ##
|
||||||
|
|
||||||
|
# b4_case(LABEL, STATEMENTS)
|
||||||
|
# --------------------------
|
||||||
|
m4_define([b4_case],
|
||||||
|
[ case $1:
|
||||||
|
$2
|
||||||
|
break;])
|
||||||
|
|
||||||
|
# b4_symbol_actions(FILENAME, LINENO,
|
||||||
|
# SYMBOL-TAG, SYMBOL-NUM,
|
||||||
|
# SYMBOL-ACTION, SYMBOL-TYPENAME)
|
||||||
|
# -------------------------------------------------
|
||||||
|
# Issue the code for a symbol action (e.g., %printer).
|
||||||
|
#
|
||||||
|
# Define b4_dollar_dollar([TYPE-NAME]), and b4_at_dollar, which are
|
||||||
|
# invoked where $<TYPE-NAME>$ and @$ were specified by the user.
|
||||||
|
m4_define([b4_symbol_actions],
|
||||||
|
[b4_dollar_pushdef([(*yyvaluep)], [$6], [(*yylocationp)])dnl
|
||||||
|
case $4: /* $3 */
|
||||||
|
b4_syncline([$2], [$1])
|
||||||
|
$5;
|
||||||
|
b4_syncline([@oline@], [@ofile@])
|
||||||
|
break;
|
||||||
|
b4_dollar_popdef[]dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_yydestruct_generate(FUNCTION-DECLARATOR)
|
||||||
|
# -------------------------------------------
|
||||||
|
# Generate the "yydestruct" function, which declaration is issued using
|
||||||
|
# FUNCTION-DECLARATOR, which may be "b4_c_ansi_function_def" for ISO C
|
||||||
|
# or "b4_c_function_def" for K&R.
|
||||||
|
m4_define_default([b4_yydestruct_generate],
|
||||||
|
[[/*-----------------------------------------------.
|
||||||
|
| Release the memory associated to this symbol. |
|
||||||
|
`-----------------------------------------------*/
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
]$1([yydestruct],
|
||||||
|
[static void],
|
||||||
|
[[const char *yymsg], [yymsg]],
|
||||||
|
[[int yytype], [yytype]],
|
||||||
|
[[YYSTYPE *yyvaluep], [yyvaluep]][]dnl
|
||||||
|
b4_locations_if( [, [[YYLTYPE *yylocationp], [yylocationp]]])[]dnl
|
||||||
|
m4_ifset([b4_parse_param], [, b4_parse_param]))[
|
||||||
|
{
|
||||||
|
YYUSE (yyvaluep);
|
||||||
|
]b4_locations_if([ YYUSE (yylocationp);
|
||||||
|
])dnl
|
||||||
|
b4_parse_param_use[]dnl
|
||||||
|
[
|
||||||
|
if (!yymsg)
|
||||||
|
yymsg = "Deleting";
|
||||||
|
YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
|
||||||
|
|
||||||
|
switch (yytype)
|
||||||
|
{
|
||||||
|
]m4_map([b4_symbol_actions], m4_defn([b4_symbol_destructors]))[
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}]dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_yy_symbol_print_generate(FUNCTION-DECLARATOR)
|
||||||
|
# ------------------------------------------------
|
||||||
|
# Generate the "yy_symbol_print" function, which declaration is issued using
|
||||||
|
# FUNCTION-DECLARATOR, which may be "b4_c_ansi_function_def" for ISO C
|
||||||
|
# or "b4_c_function_def" for K&R.
|
||||||
|
m4_define_default([b4_yy_symbol_print_generate],
|
||||||
|
[[
|
||||||
|
/*--------------------------------.
|
||||||
|
| Print this symbol on YYOUTPUT. |
|
||||||
|
`--------------------------------*/
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
]$1([yy_symbol_value_print],
|
||||||
|
[static void],
|
||||||
|
[[FILE *yyoutput], [yyoutput]],
|
||||||
|
[[int yytype], [yytype]],
|
||||||
|
[[YYSTYPE const * const yyvaluep], [yyvaluep]][]dnl
|
||||||
|
b4_locations_if([, [[YYLTYPE const * const yylocationp], [yylocationp]]])[]dnl
|
||||||
|
m4_ifset([b4_parse_param], [, b4_parse_param]))[
|
||||||
|
{
|
||||||
|
FILE *yyo = yyoutput;
|
||||||
|
YYUSE (yyo);
|
||||||
|
if (!yyvaluep)
|
||||||
|
return;
|
||||||
|
]b4_locations_if([ YYUSE (yylocationp);
|
||||||
|
])dnl
|
||||||
|
b4_parse_param_use[]dnl
|
||||||
|
[# ifdef YYPRINT
|
||||||
|
if (yytype < YYNTOKENS)
|
||||||
|
YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
|
||||||
|
# else
|
||||||
|
YYUSE (yyoutput);
|
||||||
|
# endif
|
||||||
|
switch (yytype)
|
||||||
|
{
|
||||||
|
]m4_map([b4_symbol_actions], m4_defn([b4_symbol_printers]))dnl
|
||||||
|
[ default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------.
|
||||||
|
| Print this symbol on YYOUTPUT. |
|
||||||
|
`--------------------------------*/
|
||||||
|
|
||||||
|
]$1([yy_symbol_print],
|
||||||
|
[static void],
|
||||||
|
[[FILE *yyoutput], [yyoutput]],
|
||||||
|
[[int yytype], [yytype]],
|
||||||
|
[[YYSTYPE const * const yyvaluep], [yyvaluep]][]dnl
|
||||||
|
b4_locations_if([, [[YYLTYPE const * const yylocationp], [yylocationp]]])[]dnl
|
||||||
|
m4_ifset([b4_parse_param], [, b4_parse_param]))[
|
||||||
|
{
|
||||||
|
if (yytype < YYNTOKENS)
|
||||||
|
YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
|
||||||
|
else
|
||||||
|
YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
|
||||||
|
|
||||||
|
]b4_locations_if([ YY_LOCATION_PRINT (yyoutput, *yylocationp);
|
||||||
|
YYFPRINTF (yyoutput, ": ");
|
||||||
|
])dnl
|
||||||
|
[ yy_symbol_value_print (yyoutput, yytype, yyvaluep]dnl
|
||||||
|
b4_locations_if([, yylocationp])[]b4_user_args[);
|
||||||
|
YYFPRINTF (yyoutput, ")");
|
||||||
|
}]dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
## -------------- ##
|
||||||
|
## Declarations. ##
|
||||||
|
## -------------- ##
|
||||||
|
|
||||||
|
# b4_declare_yylstype
|
||||||
|
# -------------------
|
||||||
|
# Declarations that might either go into the header (if --defines) or
|
||||||
|
# in the parser body. Declare YYSTYPE/YYLTYPE, and yylval/yylloc.
|
||||||
|
m4_define([b4_declare_yylstype],
|
||||||
|
[[#if ! defined ]b4_api_PREFIX[STYPE && ! defined ]b4_api_PREFIX[STYPE_IS_DECLARED
|
||||||
|
]m4_ifdef([b4_stype],
|
||||||
|
[[typedef union ]b4_union_name[
|
||||||
|
{
|
||||||
|
]b4_user_stype[
|
||||||
|
} ]b4_api_PREFIX[STYPE;
|
||||||
|
# define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1]],
|
||||||
|
[m4_if(b4_tag_seen_flag, 0,
|
||||||
|
[[typedef int ]b4_api_PREFIX[STYPE;
|
||||||
|
# define ]b4_api_PREFIX[STYPE_IS_TRIVIAL 1]])])[
|
||||||
|
# define ]b4_api_prefix[stype ]b4_api_PREFIX[STYPE /* obsolescent; will be withdrawn */
|
||||||
|
# define ]b4_api_PREFIX[STYPE_IS_DECLARED 1
|
||||||
|
#endif]b4_locations_if([[
|
||||||
|
|
||||||
|
#if ! defined ]b4_api_PREFIX[LTYPE && ! defined ]b4_api_PREFIX[LTYPE_IS_DECLARED
|
||||||
|
typedef struct ]b4_api_PREFIX[LTYPE
|
||||||
|
{
|
||||||
|
int first_line;
|
||||||
|
int first_column;
|
||||||
|
int last_line;
|
||||||
|
int last_column;
|
||||||
|
} ]b4_api_PREFIX[LTYPE;
|
||||||
|
# define ]b4_api_prefix[ltype ]b4_api_PREFIX[LTYPE /* obsolescent; will be withdrawn */
|
||||||
|
# define ]b4_api_PREFIX[LTYPE_IS_DECLARED 1
|
||||||
|
# define ]b4_api_PREFIX[LTYPE_IS_TRIVIAL 1
|
||||||
|
#endif]])
|
||||||
|
|
||||||
|
b4_pure_if([], [[extern ]b4_api_PREFIX[STYPE ]b4_prefix[lval;
|
||||||
|
]b4_locations_if([[extern ]b4_api_PREFIX[LTYPE ]b4_prefix[lloc;]])])[]dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
# b4_YYDEBUG_define
|
||||||
|
# ------------------
|
||||||
|
m4_define([b4_YYDEBUG_define],
|
||||||
|
[[/* Enabling traces. */
|
||||||
|
]m4_if(b4_api_prefix, [yy],
|
||||||
|
[[#ifndef YYDEBUG
|
||||||
|
# define YYDEBUG ]b4_debug_flag[
|
||||||
|
#endif]],
|
||||||
|
[[#ifndef ]b4_api_PREFIX[DEBUG
|
||||||
|
# if defined YYDEBUG
|
||||||
|
# if YYDEBUG
|
||||||
|
# define ]b4_api_PREFIX[DEBUG 1
|
||||||
|
# else
|
||||||
|
# define ]b4_api_PREFIX[DEBUG 0
|
||||||
|
# endif
|
||||||
|
# else /* ! defined YYDEBUG */
|
||||||
|
# define ]b4_api_PREFIX[DEBUG ]b4_debug_flag[
|
||||||
|
# endif /* ! defined YYDEBUG */
|
||||||
|
#endif /* ! defined ]b4_api_PREFIX[DEBUG */]])[]dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
# b4_declare_yydebug
|
||||||
|
# ------------------
|
||||||
|
m4_define([b4_declare_yydebug],
|
||||||
|
[b4_YYDEBUG_define[
|
||||||
|
#if ]b4_api_PREFIX[DEBUG
|
||||||
|
extern int ]b4_prefix[debug;
|
||||||
|
#endif][]dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
# b4_yylloc_default_define
|
||||||
|
# ------------------------
|
||||||
|
# Define YYLLOC_DEFAULT.
|
||||||
|
m4_define([b4_yylloc_default_define],
|
||||||
|
[[/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
|
||||||
|
If N is 0, then set CURRENT to the empty location which ends
|
||||||
|
the previous symbol: RHS[0] (always defined). */
|
||||||
|
|
||||||
|
#ifndef YYLLOC_DEFAULT
|
||||||
|
# define YYLLOC_DEFAULT(Current, Rhs, N) \
|
||||||
|
do \
|
||||||
|
if (YYID (N)) \
|
||||||
|
{ \
|
||||||
|
(Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
|
||||||
|
(Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
|
||||||
|
(Current).last_line = YYRHSLOC (Rhs, N).last_line; \
|
||||||
|
(Current).last_column = YYRHSLOC (Rhs, N).last_column; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
(Current).first_line = (Current).last_line = \
|
||||||
|
YYRHSLOC (Rhs, 0).last_line; \
|
||||||
|
(Current).first_column = (Current).last_column = \
|
||||||
|
YYRHSLOC (Rhs, 0).last_column; \
|
||||||
|
} \
|
||||||
|
while (YYID (0))
|
||||||
|
#endif
|
||||||
|
]])
|
||||||
|
|
||||||
|
# b4_yy_location_print_define
|
||||||
|
# ---------------------------
|
||||||
|
# Define YY_LOCATION_PRINT.
|
||||||
|
m4_define([b4_yy_location_print_define],
|
||||||
|
[b4_locations_if([[
|
||||||
|
/* YY_LOCATION_PRINT -- Print the location on the stream.
|
||||||
|
This macro was not mandated originally: define only if we know
|
||||||
|
we won't break user code: when these are the locations we know. */
|
||||||
|
|
||||||
|
#ifndef __attribute__
|
||||||
|
/* This feature is available in gcc versions 2.5 and later. */
|
||||||
|
# if (! defined __GNUC__ || __GNUC__ < 2 \
|
||||||
|
|| (__GNUC__ == 2 && __GNUC_MINOR__ < 5))
|
||||||
|
# define __attribute__(Spec) /* empty */
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef YY_LOCATION_PRINT
|
||||||
|
# if defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL
|
||||||
|
|
||||||
|
/* Print *YYLOCP on YYO. Private, do not rely on its existence. */
|
||||||
|
|
||||||
|
__attribute__((__unused__))
|
||||||
|
]b4_c_function_def([yy_location_print_],
|
||||||
|
[static unsigned],
|
||||||
|
[[FILE *yyo], [yyo]],
|
||||||
|
[[YYLTYPE const * const yylocp], [yylocp]])[
|
||||||
|
{
|
||||||
|
unsigned res = 0;
|
||||||
|
int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0;
|
||||||
|
if (0 <= yylocp->first_line)
|
||||||
|
{
|
||||||
|
res += fprintf (yyo, "%d", yylocp->first_line);
|
||||||
|
if (0 <= yylocp->first_column)
|
||||||
|
res += fprintf (yyo, ".%d", yylocp->first_column);
|
||||||
|
}
|
||||||
|
if (0 <= yylocp->last_line)
|
||||||
|
{
|
||||||
|
if (yylocp->first_line < yylocp->last_line)
|
||||||
|
{
|
||||||
|
res += fprintf (yyo, "-%d", yylocp->last_line);
|
||||||
|
if (0 <= end_col)
|
||||||
|
res += fprintf (yyo, ".%d", end_col);
|
||||||
|
}
|
||||||
|
else if (0 <= end_col && yylocp->first_column < end_col)
|
||||||
|
res += fprintf (yyo, "-%d", end_col);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
# define YY_LOCATION_PRINT(File, Loc) \
|
||||||
|
yy_location_print_ (File, &(Loc))
|
||||||
|
|
||||||
|
# else
|
||||||
|
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
|
||||||
|
# endif
|
||||||
|
#endif]],
|
||||||
|
[[/* This macro is provided for backward compatibility. */
|
||||||
|
#ifndef YY_LOCATION_PRINT
|
||||||
|
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
|
||||||
|
#endif]])
|
||||||
|
])
|
||||||
|
|
||||||
|
# b4_yyloc_default
|
||||||
|
# ----------------
|
||||||
|
# Expand to a possible default value for yylloc.
|
||||||
|
m4_define([b4_yyloc_default],
|
||||||
|
[[
|
||||||
|
# if defined ]b4_api_PREFIX[LTYPE_IS_TRIVIAL && ]b4_api_PREFIX[LTYPE_IS_TRIVIAL
|
||||||
|
= { ]m4_join([, ],
|
||||||
|
m4_defn([b4_location_initial_line]),
|
||||||
|
m4_defn([b4_location_initial_column]),
|
||||||
|
m4_defn([b4_location_initial_line]),
|
||||||
|
m4_defn([b4_location_initial_column]))[ }
|
||||||
|
# endif
|
||||||
|
]])
|
||||||
2589
tools/data/glr.c
Normal file
2589
tools/data/glr.c
Normal file
File diff suppressed because it is too large
Load Diff
346
tools/data/glr.cc
Normal file
346
tools/data/glr.cc
Normal file
@@ -0,0 +1,346 @@
|
|||||||
|
-*- C -*-
|
||||||
|
|
||||||
|
# C++ GLR skeleton for Bison
|
||||||
|
|
||||||
|
# Copyright (C) 2002-2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
# This skeleton produces a C++ class that encapsulates a C glr parser.
|
||||||
|
# This is in order to reduce the maintenance burden. The glr.c
|
||||||
|
# skeleton is clean and pure enough so that there are no real
|
||||||
|
# problems. The C++ interface is the same as that of lalr1.cc. In
|
||||||
|
# fact, glr.c can replace yacc.c without the user noticing any
|
||||||
|
# difference, and similarly for glr.cc replacing lalr1.cc.
|
||||||
|
#
|
||||||
|
# The passing of parse-params
|
||||||
|
#
|
||||||
|
# The additional arguments are stored as members of the parser
|
||||||
|
# object, yyparser. The C routines need to carry yyparser
|
||||||
|
# throughout the C parser; that easy: just let yyparser become an
|
||||||
|
# additional parse-param. But because the C++ skeleton needs to
|
||||||
|
# know the "real" original parse-param, we save them
|
||||||
|
# (b4_parse_param_orig). Note that b4_parse_param is overquoted
|
||||||
|
# (and c.m4 strips one level of quotes). This is a PITA, and
|
||||||
|
# explains why there are so many levels of quotes.
|
||||||
|
#
|
||||||
|
# The locations
|
||||||
|
#
|
||||||
|
# We use location.cc just like lalr1.cc, but because glr.c stores
|
||||||
|
# the locations in a (C++) union, the position and location classes
|
||||||
|
# must not have a constructor. Therefore, contrary to lalr1.cc, we
|
||||||
|
# must not define "b4_location_constructors". As a consequence the
|
||||||
|
# user must initialize the first positions (in particular the
|
||||||
|
# filename member).
|
||||||
|
|
||||||
|
# We require a pure interface using locations.
|
||||||
|
m4_define([b4_locations_flag], [1])
|
||||||
|
m4_define([b4_pure_flag], [1])
|
||||||
|
|
||||||
|
# The header is mandatory.
|
||||||
|
b4_defines_if([],
|
||||||
|
[b4_fatal([b4_skeleton[: using %%defines is mandatory]])])
|
||||||
|
|
||||||
|
m4_include(b4_pkgdatadir/[c++.m4])
|
||||||
|
b4_percent_define_ifdef([[api.location.type]], [],
|
||||||
|
[m4_include(b4_pkgdatadir/[location.cc])])
|
||||||
|
|
||||||
|
m4_define([b4_parser_class_name],
|
||||||
|
[b4_percent_define_get([[parser_class_name]])])
|
||||||
|
|
||||||
|
# Save the parse parameters.
|
||||||
|
m4_define([b4_parse_param_orig], m4_defn([b4_parse_param]))
|
||||||
|
|
||||||
|
|
||||||
|
# b4_yy_symbol_print_generate
|
||||||
|
# ---------------------------
|
||||||
|
# Bypass the default implementation to generate the "yy_symbol_print"
|
||||||
|
# and "yy_symbol_value_print" functions.
|
||||||
|
m4_define([b4_yy_symbol_print_generate],
|
||||||
|
[[
|
||||||
|
/*--------------------.
|
||||||
|
| Print this symbol. |
|
||||||
|
`--------------------*/
|
||||||
|
|
||||||
|
]b4_c_ansi_function_def([yy_symbol_print],
|
||||||
|
[static void],
|
||||||
|
[[FILE *], []],
|
||||||
|
[[int yytype], [yytype]],
|
||||||
|
[[const ]b4_namespace_ref::b4_parser_class_name[::semantic_type *yyvaluep],
|
||||||
|
[yyvaluep]],
|
||||||
|
[[const ]b4_namespace_ref::b4_parser_class_name[::location_type *yylocationp],
|
||||||
|
[yylocationp]],
|
||||||
|
b4_parse_param)[
|
||||||
|
{
|
||||||
|
]b4_parse_param_use[]dnl
|
||||||
|
[ yyparser.yy_symbol_print_ (yytype, yyvaluep]b4_locations_if([, yylocationp])[);
|
||||||
|
}
|
||||||
|
]])[
|
||||||
|
|
||||||
|
# Hijack the initial action to initialize the locations.
|
||||||
|
]b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [],
|
||||||
|
[m4_define([b4_initial_action],
|
||||||
|
[yylloc.initialize ();]m4_ifdef([b4_initial_action], [
|
||||||
|
m4_defn([b4_initial_action])]))])])[
|
||||||
|
|
||||||
|
# Hijack the post prologue to insert early definition of YYLLOC_DEFAULT
|
||||||
|
# and declaration of yyerror.
|
||||||
|
]m4_append([b4_post_prologue],
|
||||||
|
[b4_syncline([@oline@], [@ofile@])[
|
||||||
|
]b4_yylloc_default_define[
|
||||||
|
#define YYRHSLOC(Rhs, K) ((Rhs)[K].yystate.yyloc)
|
||||||
|
]b4_c_ansi_function_decl([yyerror],
|
||||||
|
[static void],
|
||||||
|
[[const ]b4_namespace_ref::b4_parser_class_name[::location_type *yylocationp],
|
||||||
|
[yylocationp]],
|
||||||
|
b4_parse_param,
|
||||||
|
[[const char* msg], [msg]])])
|
||||||
|
|
||||||
|
|
||||||
|
# Hijack the epilogue to define implementations (yyerror, parser member
|
||||||
|
# functions etc.).
|
||||||
|
m4_append([b4_epilogue],
|
||||||
|
[b4_syncline([@oline@], [@ofile@])[
|
||||||
|
/*------------------.
|
||||||
|
| Report an error. |
|
||||||
|
`------------------*/
|
||||||
|
|
||||||
|
]b4_c_ansi_function_def([yyerror],
|
||||||
|
[static void],
|
||||||
|
[[const ]b4_namespace_ref::b4_parser_class_name[::location_type *yylocationp],
|
||||||
|
[yylocationp]],
|
||||||
|
b4_parse_param,
|
||||||
|
[[const char* msg], [msg]])[
|
||||||
|
{
|
||||||
|
]b4_parse_param_use[]dnl
|
||||||
|
[ yyparser.error (*yylocationp, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
]b4_namespace_open[
|
||||||
|
]dnl In this section, the parse param are the original parse_params.
|
||||||
|
m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
|
||||||
|
[ /// Build a parser object.
|
||||||
|
]b4_parser_class_name::b4_parser_class_name[ (]b4_parse_param_decl[)]m4_ifset([b4_parse_param], [
|
||||||
|
:])[
|
||||||
|
#if ]b4_api_PREFIX[DEBUG
|
||||||
|
]m4_ifset([b4_parse_param], [ ], [ :])[
|
||||||
|
yycdebug_ (&std::cerr)]m4_ifset([b4_parse_param], [,])[
|
||||||
|
#endif]b4_parse_param_cons[
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
]b4_parser_class_name::~b4_parser_class_name[ ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
]b4_parser_class_name[::parse ()
|
||||||
|
{
|
||||||
|
return ::yyparse (*this]b4_user_args[);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ]b4_api_PREFIX[DEBUG
|
||||||
|
/*--------------------.
|
||||||
|
| Print this symbol. |
|
||||||
|
`--------------------*/
|
||||||
|
|
||||||
|
inline void
|
||||||
|
]b4_parser_class_name[::yy_symbol_value_print_ (int yytype,
|
||||||
|
const semantic_type* yyvaluep,
|
||||||
|
const location_type* yylocationp)
|
||||||
|
{
|
||||||
|
YYUSE (yylocationp);
|
||||||
|
YYUSE (yyvaluep);
|
||||||
|
std::ostream& yyoutput = debug_stream ();
|
||||||
|
std::ostream& yyo = yyoutput;
|
||||||
|
YYUSE (yyo);
|
||||||
|
switch (yytype)
|
||||||
|
{
|
||||||
|
]m4_map([b4_symbol_actions], m4_defn([b4_symbol_printers]))dnl
|
||||||
|
[ default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
]b4_parser_class_name[::yy_symbol_print_ (int yytype,
|
||||||
|
const semantic_type* yyvaluep,
|
||||||
|
const location_type* yylocationp)
|
||||||
|
{
|
||||||
|
*yycdebug_ << (yytype < YYNTOKENS ? "token" : "nterm")
|
||||||
|
<< ' ' << yytname[yytype] << " ("
|
||||||
|
<< *yylocationp << ": ";
|
||||||
|
yy_symbol_value_print_ (yytype, yyvaluep, yylocationp);
|
||||||
|
*yycdebug_ << ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream&
|
||||||
|
]b4_parser_class_name[::debug_stream () const
|
||||||
|
{
|
||||||
|
return *yycdebug_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
]b4_parser_class_name[::set_debug_stream (std::ostream& o)
|
||||||
|
{
|
||||||
|
yycdebug_ = &o;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
]b4_parser_class_name[::debug_level_type
|
||||||
|
]b4_parser_class_name[::debug_level () const
|
||||||
|
{
|
||||||
|
return yydebug;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
]b4_parser_class_name[::set_debug_level (debug_level_type l)
|
||||||
|
{
|
||||||
|
// Actually, it is yydebug which is really used.
|
||||||
|
yydebug = l;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
]m4_popdef([b4_parse_param])dnl
|
||||||
|
b4_namespace_close])
|
||||||
|
|
||||||
|
|
||||||
|
# Let glr.c believe that the user arguments include the parser itself.
|
||||||
|
m4_ifset([b4_parse_param],
|
||||||
|
[m4_pushdef([b4_parse_param],
|
||||||
|
[[b4_namespace_ref::b4_parser_class_name[& yyparser], [[yyparser]]],]
|
||||||
|
m4_defn([b4_parse_param]))],
|
||||||
|
[m4_pushdef([b4_parse_param],
|
||||||
|
[[b4_namespace_ref::b4_parser_class_name[& yyparser], [[yyparser]]]])
|
||||||
|
])
|
||||||
|
m4_include(b4_pkgdatadir/[glr.c])
|
||||||
|
m4_popdef([b4_parse_param])
|
||||||
|
|
||||||
|
b4_output_begin([b4_spec_defines_file])
|
||||||
|
b4_copyright([Skeleton interface for Bison GLR parsers in C++],
|
||||||
|
[2002-2006, 2009-2012])[
|
||||||
|
|
||||||
|
/* C++ GLR parser skeleton written by Akim Demaille. */
|
||||||
|
|
||||||
|
]b4_cpp_guard_open([b4_spec_defines_file])[
|
||||||
|
|
||||||
|
]b4_percent_code_get([[requires]])[
|
||||||
|
|
||||||
|
# include <string>
|
||||||
|
# include <iostream>
|
||||||
|
]b4_percent_define_ifdef([[api.location.type]], [],
|
||||||
|
[[# include "location.hh"]])[
|
||||||
|
|
||||||
|
]b4_YYDEBUG_define[
|
||||||
|
|
||||||
|
]b4_namespace_open[
|
||||||
|
/// A Bison parser.
|
||||||
|
class ]b4_parser_class_name[
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Symbol semantic values.
|
||||||
|
# ifndef ]b4_api_PREFIX[STYPE
|
||||||
|
]m4_ifdef([b4_stype],
|
||||||
|
[ union semantic_type
|
||||||
|
{
|
||||||
|
b4_user_stype
|
||||||
|
};],
|
||||||
|
[m4_if(b4_tag_seen_flag, 0,
|
||||||
|
[[ typedef int semantic_type;]],
|
||||||
|
[[ typedef ]b4_api_PREFIX[STYPE semantic_type;]])])[
|
||||||
|
# else
|
||||||
|
typedef ]b4_api_PREFIX[STYPE semantic_type;
|
||||||
|
# endif
|
||||||
|
/// Symbol locations.
|
||||||
|
typedef ]b4_percent_define_get([[api.location.type]],
|
||||||
|
[[location]])[ location_type;
|
||||||
|
/// Tokens.
|
||||||
|
struct token
|
||||||
|
{
|
||||||
|
]b4_token_enums(b4_tokens)[
|
||||||
|
};
|
||||||
|
/// Token type.
|
||||||
|
typedef token::yytokentype token_type;
|
||||||
|
|
||||||
|
/// Build a parser object.
|
||||||
|
]b4_parser_class_name[ (]b4_parse_param_decl[);
|
||||||
|
virtual ~]b4_parser_class_name[ ();
|
||||||
|
|
||||||
|
/// Parse.
|
||||||
|
/// \returns 0 iff parsing succeeded.
|
||||||
|
virtual int parse ();
|
||||||
|
|
||||||
|
/// The current debugging stream.
|
||||||
|
std::ostream& debug_stream () const;
|
||||||
|
/// Set the current debugging stream.
|
||||||
|
void set_debug_stream (std::ostream &);
|
||||||
|
|
||||||
|
/// Type for debugging levels.
|
||||||
|
typedef int debug_level_type;
|
||||||
|
/// The current debugging level.
|
||||||
|
debug_level_type debug_level () const;
|
||||||
|
/// Set the current debugging level.
|
||||||
|
void set_debug_level (debug_level_type l);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Report a syntax error.
|
||||||
|
/// \param loc where the syntax error is found.
|
||||||
|
/// \param msg a description of the syntax error.
|
||||||
|
virtual void error (const location_type& loc, const std::string& msg);
|
||||||
|
private:
|
||||||
|
|
||||||
|
# if ]b4_api_PREFIX[DEBUG
|
||||||
|
public:
|
||||||
|
/// \brief Report a symbol value on the debug stream.
|
||||||
|
/// \param yytype The token type.
|
||||||
|
/// \param yyvaluep Its semantic value.
|
||||||
|
/// \param yylocationp Its location.
|
||||||
|
virtual void yy_symbol_value_print_ (int yytype,
|
||||||
|
const semantic_type* yyvaluep,
|
||||||
|
const location_type* yylocationp);
|
||||||
|
/// \brief Report a symbol on the debug stream.
|
||||||
|
/// \param yytype The token type.
|
||||||
|
/// \param yyvaluep Its semantic value.
|
||||||
|
/// \param yylocationp Its location.
|
||||||
|
virtual void yy_symbol_print_ (int yytype,
|
||||||
|
const semantic_type* yyvaluep,
|
||||||
|
const location_type* yylocationp);
|
||||||
|
private:
|
||||||
|
/* Debugging. */
|
||||||
|
std::ostream* yycdebug_;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
]b4_parse_param_vars[
|
||||||
|
};
|
||||||
|
|
||||||
|
]dnl Redirections for glr.c.
|
||||||
|
b4_percent_define_flag_if([[global_tokens_and_yystype]],
|
||||||
|
[b4_token_defines(b4_tokens)])
|
||||||
|
[
|
||||||
|
#ifndef ]b4_api_PREFIX[STYPE
|
||||||
|
# define ]b4_api_PREFIX[STYPE ]b4_namespace_ref[::]b4_parser_class_name[::semantic_type
|
||||||
|
#endif
|
||||||
|
#ifndef ]b4_api_PREFIX[LTYPE
|
||||||
|
# define ]b4_api_PREFIX[LTYPE ]b4_namespace_ref[::]b4_parser_class_name[::location_type
|
||||||
|
#endif
|
||||||
|
|
||||||
|
]b4_namespace_close[
|
||||||
|
]b4_percent_code_get([[provides]])[
|
||||||
|
]b4_cpp_guard_close([b4_spec_defines_file])[
|
||||||
|
]b4_output_end()
|
||||||
26
tools/data/java-skel.m4
Normal file
26
tools/data/java-skel.m4
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
-*- Autoconf -*-
|
||||||
|
|
||||||
|
# Java skeleton dispatching for Bison.
|
||||||
|
|
||||||
|
# Copyright (C) 2007, 2009-2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
b4_glr_if( [b4_complain([%%glr-parser not supported for Java])])
|
||||||
|
b4_nondeterministic_if([b4_complain([%%nondeterministic-parser not supported for Java])])
|
||||||
|
|
||||||
|
m4_define_default([b4_used_skeleton], [b4_pkgdatadir/[lalr1.java]])
|
||||||
|
m4_define_default([b4_skeleton], ["b4_basename(b4_used_skeleton)"])
|
||||||
|
|
||||||
|
m4_include(b4_used_skeleton)
|
||||||
304
tools/data/java.m4
Normal file
304
tools/data/java.m4
Normal file
@@ -0,0 +1,304 @@
|
|||||||
|
-*- Autoconf -*-
|
||||||
|
|
||||||
|
# Java language support for Bison
|
||||||
|
|
||||||
|
# Copyright (C) 2007-2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
m4_include(b4_pkgdatadir/[c-like.m4])
|
||||||
|
|
||||||
|
# b4_comment(TEXT)
|
||||||
|
# ----------------
|
||||||
|
m4_define([b4_comment], [/* m4_bpatsubst([$1], [
|
||||||
|
], [
|
||||||
|
]) */])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_list2(LIST1, LIST2)
|
||||||
|
# --------------------------
|
||||||
|
# Join two lists with a comma if necessary.
|
||||||
|
m4_define([b4_list2],
|
||||||
|
[$1[]m4_ifval(m4_quote($1), [m4_ifval(m4_quote($2), [[, ]])])[]$2])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_percent_define_get3(DEF, PRE, POST, NOT)
|
||||||
|
# -------------------------------------------
|
||||||
|
# Expand to the value of DEF surrounded by PRE and POST if it's %define'ed,
|
||||||
|
# otherwise NOT.
|
||||||
|
m4_define([b4_percent_define_get3],
|
||||||
|
[m4_ifval(m4_quote(b4_percent_define_get([$1])),
|
||||||
|
[$2[]b4_percent_define_get([$1])[]$3], [$4])])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# b4_flag_value(BOOLEAN-FLAG)
|
||||||
|
# ---------------------------
|
||||||
|
m4_define([b4_flag_value], [b4_flag_if([$1], [true], [false])])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_public_if(TRUE, FALSE)
|
||||||
|
# -------------------------
|
||||||
|
b4_percent_define_default([[public]], [[false]])
|
||||||
|
m4_define([b4_public_if],
|
||||||
|
[b4_percent_define_flag_if([public], [$1], [$2])])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_abstract_if(TRUE, FALSE)
|
||||||
|
# ---------------------------
|
||||||
|
b4_percent_define_default([[abstract]], [[false]])
|
||||||
|
m4_define([b4_abstract_if],
|
||||||
|
[b4_percent_define_flag_if([abstract], [$1], [$2])])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_final_if(TRUE, FALSE)
|
||||||
|
# ---------------------------
|
||||||
|
b4_percent_define_default([[final]], [[false]])
|
||||||
|
m4_define([b4_final_if],
|
||||||
|
[b4_percent_define_flag_if([final], [$1], [$2])])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_strictfp_if(TRUE, FALSE)
|
||||||
|
# ---------------------------
|
||||||
|
b4_percent_define_default([[strictfp]], [[false]])
|
||||||
|
m4_define([b4_strictfp_if],
|
||||||
|
[b4_percent_define_flag_if([strictfp], [$1], [$2])])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_lexer_if(TRUE, FALSE)
|
||||||
|
# ------------------------
|
||||||
|
m4_define([b4_lexer_if],
|
||||||
|
[b4_percent_code_ifdef([[lexer]], [$1], [$2])])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_identification
|
||||||
|
# -----------------
|
||||||
|
m4_define([b4_identification],
|
||||||
|
[ /** Version number for the Bison executable that generated this parser. */
|
||||||
|
public static final String bisonVersion = "b4_version";
|
||||||
|
|
||||||
|
/** Name of the skeleton that generated this parser. */
|
||||||
|
public static final String bisonSkeleton = b4_skeleton;
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
## ------------ ##
|
||||||
|
## Data types. ##
|
||||||
|
## ------------ ##
|
||||||
|
|
||||||
|
# b4_int_type(MIN, MAX)
|
||||||
|
# ---------------------
|
||||||
|
# Return the smallest int type able to handle numbers ranging from
|
||||||
|
# MIN to MAX (included).
|
||||||
|
m4_define([b4_int_type],
|
||||||
|
[m4_if(b4_ints_in($@, [-128], [127]), [1], [byte],
|
||||||
|
b4_ints_in($@, [-32768], [32767]), [1], [short],
|
||||||
|
[int])])
|
||||||
|
|
||||||
|
# b4_int_type_for(NAME)
|
||||||
|
# ---------------------
|
||||||
|
# Return the smallest int type able to handle numbers ranging from
|
||||||
|
# `NAME_min' to `NAME_max' (included).
|
||||||
|
m4_define([b4_int_type_for],
|
||||||
|
[b4_int_type($1_min, $1_max)])
|
||||||
|
|
||||||
|
# b4_null
|
||||||
|
# -------
|
||||||
|
m4_define([b4_null], [null])
|
||||||
|
|
||||||
|
|
||||||
|
## ------------------------- ##
|
||||||
|
## Assigning token numbers. ##
|
||||||
|
## ------------------------- ##
|
||||||
|
|
||||||
|
# b4_token_enum(TOKEN-NAME, TOKEN-NUMBER)
|
||||||
|
# ---------------------------------------
|
||||||
|
# Output the definition of this token as an enum.
|
||||||
|
m4_define([b4_token_enum],
|
||||||
|
[ /** Token number, to be returned by the scanner. */
|
||||||
|
public static final int $1 = $2;
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_token_enums(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER)
|
||||||
|
# -----------------------------------------------------
|
||||||
|
# Output the definition of the tokens (if there are) as enums.
|
||||||
|
m4_define([b4_token_enums],
|
||||||
|
[m4_if([$#$1], [1], [],
|
||||||
|
[/* Tokens. */
|
||||||
|
m4_map([b4_token_enum], [$@])])
|
||||||
|
])
|
||||||
|
|
||||||
|
# b4-case(ID, CODE)
|
||||||
|
# -----------------
|
||||||
|
# We need to fool Java's stupid unreachable code detection.
|
||||||
|
m4_define([b4_case], [ case $1:
|
||||||
|
if (yyn == $1)
|
||||||
|
$2;
|
||||||
|
break;
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
## ---------------- ##
|
||||||
|
## Default values. ##
|
||||||
|
## ---------------- ##
|
||||||
|
|
||||||
|
m4_define([b4_yystype], [b4_percent_define_get([[stype]])])
|
||||||
|
b4_percent_define_default([[stype]], [[Object]])
|
||||||
|
|
||||||
|
# %name-prefix
|
||||||
|
m4_define_default([b4_prefix], [[YY]])
|
||||||
|
|
||||||
|
b4_percent_define_default([[parser_class_name]], [b4_prefix[]Parser])
|
||||||
|
m4_define([b4_parser_class_name], [b4_percent_define_get([[parser_class_name]])])
|
||||||
|
|
||||||
|
b4_percent_define_default([[lex_throws]], [[java.io.IOException]])
|
||||||
|
m4_define([b4_lex_throws], [b4_percent_define_get([[lex_throws]])])
|
||||||
|
|
||||||
|
b4_percent_define_default([[throws]], [])
|
||||||
|
m4_define([b4_throws], [b4_percent_define_get([[throws]])])
|
||||||
|
|
||||||
|
b4_percent_define_default([[api.location.type]], [Location])
|
||||||
|
m4_define([b4_location_type], [b4_percent_define_get([[api.location.type]])])
|
||||||
|
|
||||||
|
b4_percent_define_default([[api.position.type]], [Position])
|
||||||
|
m4_define([b4_position_type], [b4_percent_define_get([[api.position.type]])])
|
||||||
|
|
||||||
|
|
||||||
|
## ----------------- ##
|
||||||
|
## Semantic Values. ##
|
||||||
|
## ----------------- ##
|
||||||
|
|
||||||
|
|
||||||
|
# b4_lhs_value([TYPE])
|
||||||
|
# --------------------
|
||||||
|
# Expansion of $<TYPE>$.
|
||||||
|
m4_define([b4_lhs_value], [yyval])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_rhs_value(RULE-LENGTH, NUM, [TYPE])
|
||||||
|
# --------------------------------------
|
||||||
|
# Expansion of $<TYPE>NUM, where the current rule has RULE-LENGTH
|
||||||
|
# symbols on RHS.
|
||||||
|
#
|
||||||
|
# In this simple implementation, %token and %type have class names
|
||||||
|
# between the angle brackets.
|
||||||
|
m4_define([b4_rhs_value],
|
||||||
|
[(m4_ifval($3, [($3)])[](yystack.valueAt ($1-($2))))])
|
||||||
|
|
||||||
|
# b4_lhs_location()
|
||||||
|
# -----------------
|
||||||
|
# Expansion of @$.
|
||||||
|
m4_define([b4_lhs_location],
|
||||||
|
[(yyloc)])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_rhs_location(RULE-LENGTH, NUM)
|
||||||
|
# ---------------------------------
|
||||||
|
# Expansion of @NUM, where the current rule has RULE-LENGTH symbols
|
||||||
|
# on RHS.
|
||||||
|
m4_define([b4_rhs_location],
|
||||||
|
[yystack.locationAt ($1-($2))])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_lex_param
|
||||||
|
# b4_parse_param
|
||||||
|
# --------------
|
||||||
|
# If defined, b4_lex_param arrives double quoted, but below we prefer
|
||||||
|
# it to be single quoted. Same for b4_parse_param.
|
||||||
|
|
||||||
|
# TODO: should be in bison.m4
|
||||||
|
m4_define_default([b4_lex_param], [[]])
|
||||||
|
m4_define([b4_lex_param], b4_lex_param)
|
||||||
|
m4_define([b4_parse_param], b4_parse_param)
|
||||||
|
|
||||||
|
# b4_lex_param_decl
|
||||||
|
# -------------------
|
||||||
|
# Extra formal arguments of the constructor.
|
||||||
|
m4_define([b4_lex_param_decl],
|
||||||
|
[m4_ifset([b4_lex_param],
|
||||||
|
[b4_remove_comma([$1],
|
||||||
|
b4_param_decls(b4_lex_param))],
|
||||||
|
[$1])])
|
||||||
|
|
||||||
|
m4_define([b4_param_decls],
|
||||||
|
[m4_map([b4_param_decl], [$@])])
|
||||||
|
m4_define([b4_param_decl], [, $1])
|
||||||
|
|
||||||
|
m4_define([b4_remove_comma], [m4_ifval(m4_quote($1), [$1, ], [])m4_shift2($@)])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# b4_parse_param_decl
|
||||||
|
# -------------------
|
||||||
|
# Extra formal arguments of the constructor.
|
||||||
|
m4_define([b4_parse_param_decl],
|
||||||
|
[m4_ifset([b4_parse_param],
|
||||||
|
[b4_remove_comma([$1],
|
||||||
|
b4_param_decls(b4_parse_param))],
|
||||||
|
[$1])])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# b4_lex_param_call
|
||||||
|
# -------------------
|
||||||
|
# Delegating the lexer parameters to the lexer constructor.
|
||||||
|
m4_define([b4_lex_param_call],
|
||||||
|
[m4_ifset([b4_lex_param],
|
||||||
|
[b4_remove_comma([$1],
|
||||||
|
b4_param_calls(b4_lex_param))],
|
||||||
|
[$1])])
|
||||||
|
m4_define([b4_param_calls],
|
||||||
|
[m4_map([b4_param_call], [$@])])
|
||||||
|
m4_define([b4_param_call], [, $2])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# b4_parse_param_cons
|
||||||
|
# -------------------
|
||||||
|
# Extra initialisations of the constructor.
|
||||||
|
m4_define([b4_parse_param_cons],
|
||||||
|
[m4_ifset([b4_parse_param],
|
||||||
|
[b4_constructor_calls(b4_parse_param)])])
|
||||||
|
|
||||||
|
m4_define([b4_constructor_calls],
|
||||||
|
[m4_map([b4_constructor_call], [$@])])
|
||||||
|
m4_define([b4_constructor_call],
|
||||||
|
[this.$2 = $2;
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# b4_parse_param_vars
|
||||||
|
# -------------------
|
||||||
|
# Extra instance variables.
|
||||||
|
m4_define([b4_parse_param_vars],
|
||||||
|
[m4_ifset([b4_parse_param],
|
||||||
|
[
|
||||||
|
/* User arguments. */
|
||||||
|
b4_var_decls(b4_parse_param)])])
|
||||||
|
|
||||||
|
m4_define([b4_var_decls],
|
||||||
|
[m4_map_sep([b4_var_decl], [
|
||||||
|
], [$@])])
|
||||||
|
m4_define([b4_var_decl],
|
||||||
|
[ protected final $1;])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# b4_maybe_throws(THROWS)
|
||||||
|
# -----------------------
|
||||||
|
# Expand to either an empty string or "throws THROWS".
|
||||||
|
m4_define([b4_maybe_throws],
|
||||||
|
[m4_ifval($1, [throws $1])])
|
||||||
1143
tools/data/lalr1.cc
Normal file
1143
tools/data/lalr1.cc
Normal file
File diff suppressed because it is too large
Load Diff
927
tools/data/lalr1.java
Normal file
927
tools/data/lalr1.java
Normal file
@@ -0,0 +1,927 @@
|
|||||||
|
# Java skeleton for Bison -*- autoconf -*-
|
||||||
|
|
||||||
|
# Copyright (C) 2007-2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
m4_include(b4_pkgdatadir/[java.m4])
|
||||||
|
|
||||||
|
b4_defines_if([b4_fatal([%s: %%defines does not make sense in Java], [b4_skeleton])])
|
||||||
|
m4_ifval(m4_defn([b4_symbol_destructors]),
|
||||||
|
[b4_fatal([%s: %%destructor does not make sense in Java], [b4_skeleton])],
|
||||||
|
[])
|
||||||
|
|
||||||
|
b4_output_begin([b4_parser_file_name])
|
||||||
|
b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java],
|
||||||
|
[2007-2012])
|
||||||
|
|
||||||
|
b4_percent_define_ifdef([package], [package b4_percent_define_get([package]);
|
||||||
|
])[/* First part of user declarations. */
|
||||||
|
]b4_pre_prologue
|
||||||
|
b4_percent_code_get([[imports]])
|
||||||
|
[/**
|
||||||
|
* A Bison parser, automatically generated from <tt>]m4_bpatsubst(b4_file_name, [^"\(.*\)"$], [\1])[</tt>.
|
||||||
|
*
|
||||||
|
* @@author LALR (1) parser skeleton written by Paolo Bonzini.
|
||||||
|
*/
|
||||||
|
]b4_public_if([public ])dnl
|
||||||
|
b4_abstract_if([abstract ])dnl
|
||||||
|
b4_final_if([final ])dnl
|
||||||
|
b4_strictfp_if([strictfp ])dnl
|
||||||
|
[class ]b4_parser_class_name[]dnl
|
||||||
|
b4_percent_define_get3([extends], [ extends ])dnl
|
||||||
|
b4_percent_define_get3([implements], [ implements ])[
|
||||||
|
{
|
||||||
|
]b4_identification[
|
||||||
|
|
||||||
|
/** True if verbose error messages are enabled. */
|
||||||
|
public boolean errorVerbose = ]b4_flag_value([error_verbose]);
|
||||||
|
|
||||||
|
b4_locations_if([[
|
||||||
|
/**
|
||||||
|
* A class defining a pair of positions. Positions, defined by the
|
||||||
|
* <code>]b4_position_type[</code> class, denote a point in the input.
|
||||||
|
* Locations represent a part of the input through the beginning
|
||||||
|
* and ending positions. */
|
||||||
|
public class ]b4_location_type[ {
|
||||||
|
/** The first, inclusive, position in the range. */
|
||||||
|
public ]b4_position_type[ begin;
|
||||||
|
|
||||||
|
/** The first position beyond the range. */
|
||||||
|
public ]b4_position_type[ end;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a <code>]b4_location_type[</code> denoting an empty range located at
|
||||||
|
* a given point.
|
||||||
|
* @@param loc The position at which the range is anchored. */
|
||||||
|
public ]b4_location_type[ (]b4_position_type[ loc) {
|
||||||
|
this.begin = this.end = loc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a <code>]b4_location_type[</code> from the endpoints of the range.
|
||||||
|
* @@param begin The first position included in the range.
|
||||||
|
* @@param end The first position beyond the range. */
|
||||||
|
public ]b4_location_type[ (]b4_position_type[ begin, ]b4_position_type[ end) {
|
||||||
|
this.begin = begin;
|
||||||
|
this.end = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print a representation of the location. For this to be correct,
|
||||||
|
* <code>]b4_position_type[</code> should override the <code>equals</code>
|
||||||
|
* method. */
|
||||||
|
public String toString () {
|
||||||
|
if (begin.equals (end))
|
||||||
|
return begin.toString ();
|
||||||
|
else
|
||||||
|
return begin.toString () + "-" + end.toString ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
]])
|
||||||
|
|
||||||
|
[ /** Token returned by the scanner to signal the end of its input. */
|
||||||
|
public static final int EOF = 0;]
|
||||||
|
|
||||||
|
b4_token_enums(b4_tokens)
|
||||||
|
|
||||||
|
b4_locations_if([[
|
||||||
|
private ]b4_location_type[ yylloc (YYStack rhs, int n)
|
||||||
|
{
|
||||||
|
if (n > 0)
|
||||||
|
return new ]b4_location_type[ (rhs.locationAt (n-1).begin, rhs.locationAt (0).end);
|
||||||
|
else
|
||||||
|
return new ]b4_location_type[ (rhs.locationAt (0).end);
|
||||||
|
}]])[
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Communication interface between the scanner and the Bison-generated
|
||||||
|
* parser <tt>]b4_parser_class_name[</tt>.
|
||||||
|
*/
|
||||||
|
public interface Lexer {
|
||||||
|
]b4_locations_if([[/**
|
||||||
|
* Method to retrieve the beginning position of the last scanned token.
|
||||||
|
* @@return the position at which the last scanned token starts. */
|
||||||
|
]b4_position_type[ getStartPos ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to retrieve the ending position of the last scanned token.
|
||||||
|
* @@return the first position beyond the last scanned token. */
|
||||||
|
]b4_position_type[ getEndPos ();]])[
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to retrieve the semantic value of the last scanned token.
|
||||||
|
* @@return the semantic value of the last scanned token. */
|
||||||
|
]b4_yystype[ getLVal ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entry point for the scanner. Returns the token identifier corresponding
|
||||||
|
* to the next token and prepares to return the semantic value
|
||||||
|
* ]b4_locations_if([and beginning/ending positions ])[of the token.
|
||||||
|
* @@return the token identifier corresponding to the next token. */
|
||||||
|
int yylex () ]b4_maybe_throws([b4_lex_throws])[;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entry point for error reporting. Emits an error
|
||||||
|
* ]b4_locations_if([referring to the given location ])[in a user-defined way.
|
||||||
|
*
|
||||||
|
* ]b4_locations_if([[@@param loc The location of the element to which the
|
||||||
|
* error message is related]])[
|
||||||
|
* @@param s The string for the error message. */
|
||||||
|
void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String s);]
|
||||||
|
}
|
||||||
|
|
||||||
|
b4_lexer_if([[private class YYLexer implements Lexer {
|
||||||
|
]b4_percent_code_get([[lexer]])[
|
||||||
|
}
|
||||||
|
|
||||||
|
]])[/** The object doing lexical analysis for us. */
|
||||||
|
private Lexer yylexer;
|
||||||
|
]
|
||||||
|
b4_parse_param_vars
|
||||||
|
|
||||||
|
b4_lexer_if([[
|
||||||
|
/**
|
||||||
|
* Instantiates the Bison-generated parser.
|
||||||
|
*/
|
||||||
|
public ]b4_parser_class_name (b4_parse_param_decl([b4_lex_param_decl])[) {
|
||||||
|
this.yylexer = new YYLexer(]b4_lex_param_call[);
|
||||||
|
]b4_parse_param_cons[
|
||||||
|
}
|
||||||
|
]])
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates the Bison-generated parser.
|
||||||
|
* @@param yylexer The scanner that will supply tokens to the parser.
|
||||||
|
*/
|
||||||
|
b4_lexer_if([[protected]], [[public]]) b4_parser_class_name[ (]b4_parse_param_decl([[Lexer yylexer]])[) {
|
||||||
|
this.yylexer = yylexer;
|
||||||
|
]b4_parse_param_cons[
|
||||||
|
}
|
||||||
|
|
||||||
|
private java.io.PrintStream yyDebugStream = System.err;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the <tt>PrintStream</tt> on which the debugging output is
|
||||||
|
* printed.
|
||||||
|
*/
|
||||||
|
public final java.io.PrintStream getDebugStream () { return yyDebugStream; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the <tt>PrintStream</tt> on which the debug output is printed.
|
||||||
|
* @@param s The stream that is used for debugging output.
|
||||||
|
*/
|
||||||
|
public final void setDebugStream(java.io.PrintStream s) { yyDebugStream = s; }
|
||||||
|
|
||||||
|
private int yydebug = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Answer the verbosity of the debugging output; 0 means that all kinds of
|
||||||
|
* output from the parser are suppressed.
|
||||||
|
*/
|
||||||
|
public final int getDebugLevel() { return yydebug; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the verbosity of the debugging output; 0 means that all kinds of
|
||||||
|
* output from the parser are suppressed.
|
||||||
|
* @@param level The verbosity level for debugging output.
|
||||||
|
*/
|
||||||
|
public final void setDebugLevel(int level) { yydebug = level; }
|
||||||
|
|
||||||
|
private final int yylex () ]b4_maybe_throws([b4_lex_throws]) [{
|
||||||
|
return yylexer.yylex ();
|
||||||
|
}
|
||||||
|
protected final void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String s) {
|
||||||
|
yylexer.yyerror (]b4_locations_if([loc, ])[s);
|
||||||
|
}
|
||||||
|
|
||||||
|
]b4_locations_if([
|
||||||
|
protected final void yyerror (String s) {
|
||||||
|
yylexer.yyerror ((]b4_location_type[)null, s);
|
||||||
|
}
|
||||||
|
protected final void yyerror (]b4_position_type[ loc, String s) {
|
||||||
|
yylexer.yyerror (new ]b4_location_type[ (loc), s);
|
||||||
|
}])
|
||||||
|
|
||||||
|
[protected final void yycdebug (String s) {
|
||||||
|
if (yydebug > 0)
|
||||||
|
yyDebugStream.println (s);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class YYStack {
|
||||||
|
private int[] stateStack = new int[16];
|
||||||
|
]b4_locations_if([[private ]b4_location_type[[] locStack = new ]b4_location_type[[16];]])[
|
||||||
|
private ]b4_yystype[[] valueStack = new ]b4_yystype[[16];
|
||||||
|
|
||||||
|
public int size = 16;
|
||||||
|
public int height = -1;
|
||||||
|
|
||||||
|
public final void push (int state, ]b4_yystype[ value]dnl
|
||||||
|
b4_locations_if([, ]b4_location_type[ loc])[) {
|
||||||
|
height++;
|
||||||
|
if (size == height)
|
||||||
|
{
|
||||||
|
int[] newStateStack = new int[size * 2];
|
||||||
|
System.arraycopy (stateStack, 0, newStateStack, 0, height);
|
||||||
|
stateStack = newStateStack;
|
||||||
|
]b4_locations_if([[
|
||||||
|
]b4_location_type[[] newLocStack = new ]b4_location_type[[size * 2];
|
||||||
|
System.arraycopy (locStack, 0, newLocStack, 0, height);
|
||||||
|
locStack = newLocStack;]])
|
||||||
|
|
||||||
|
b4_yystype[[] newValueStack = new ]b4_yystype[[size * 2];
|
||||||
|
System.arraycopy (valueStack, 0, newValueStack, 0, height);
|
||||||
|
valueStack = newValueStack;
|
||||||
|
|
||||||
|
size *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
stateStack[height] = state;
|
||||||
|
]b4_locations_if([[locStack[height] = loc;]])[
|
||||||
|
valueStack[height] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void pop () {
|
||||||
|
pop (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void pop (int num) {
|
||||||
|
// Avoid memory leaks... garbage collection is a white lie!
|
||||||
|
if (num > 0) {
|
||||||
|
java.util.Arrays.fill (valueStack, height - num + 1, height + 1, null);
|
||||||
|
]b4_locations_if([[java.util.Arrays.fill (locStack, height - num + 1, height + 1, null);]])[
|
||||||
|
}
|
||||||
|
height -= num;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int stateAt (int i) {
|
||||||
|
return stateStack[height - i];
|
||||||
|
}
|
||||||
|
|
||||||
|
]b4_locations_if([[public final ]b4_location_type[ locationAt (int i) {
|
||||||
|
return locStack[height - i];
|
||||||
|
}
|
||||||
|
|
||||||
|
]])[public final ]b4_yystype[ valueAt (int i) {
|
||||||
|
return valueStack[height - i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the state stack on the debug stream.
|
||||||
|
public void print (java.io.PrintStream out)
|
||||||
|
{
|
||||||
|
out.print ("Stack now");
|
||||||
|
|
||||||
|
for (int i = 0; i <= height; i++)
|
||||||
|
{
|
||||||
|
out.print (' ');
|
||||||
|
out.print (stateStack[i]);
|
||||||
|
}
|
||||||
|
out.println ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returned by a Bison action in order to stop the parsing process and
|
||||||
|
* return success (<tt>true</tt>). */
|
||||||
|
public static final int YYACCEPT = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returned by a Bison action in order to stop the parsing process and
|
||||||
|
* return failure (<tt>false</tt>). */
|
||||||
|
public static final int YYABORT = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returned by a Bison action in order to start error recovery without
|
||||||
|
* printing an error message. */
|
||||||
|
public static final int YYERROR = 2;
|
||||||
|
|
||||||
|
// Internal return codes that are not supported for user semantic
|
||||||
|
// actions.
|
||||||
|
private static final int YYERRLAB = 3;
|
||||||
|
private static final int YYNEWSTATE = 4;
|
||||||
|
private static final int YYDEFAULT = 5;
|
||||||
|
private static final int YYREDUCE = 6;
|
||||||
|
private static final int YYERRLAB1 = 7;
|
||||||
|
private static final int YYRETURN = 8;
|
||||||
|
|
||||||
|
private int yyerrstatus_ = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether error recovery is being done. In this state, the parser
|
||||||
|
* reads token until it reaches a known state, and then restarts normal
|
||||||
|
* operation. */
|
||||||
|
public final boolean recovering ()
|
||||||
|
{
|
||||||
|
return yyerrstatus_ == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int yyaction (int yyn, YYStack yystack, int yylen) ]b4_maybe_throws([b4_throws])[
|
||||||
|
{
|
||||||
|
]b4_yystype[ yyval;
|
||||||
|
]b4_locations_if([b4_location_type[ yyloc = yylloc (yystack, yylen);]])[
|
||||||
|
|
||||||
|
/* If YYLEN is nonzero, implement the default value of the action:
|
||||||
|
`$$ = $1'. Otherwise, use the top of the stack.
|
||||||
|
|
||||||
|
Otherwise, the following line sets YYVAL to garbage.
|
||||||
|
This behavior is undocumented and Bison
|
||||||
|
users should not rely upon it. */
|
||||||
|
if (yylen > 0)
|
||||||
|
yyval = yystack.valueAt (yylen - 1);
|
||||||
|
else
|
||||||
|
yyval = yystack.valueAt (0);
|
||||||
|
|
||||||
|
yy_reduce_print (yyn, yystack);
|
||||||
|
|
||||||
|
switch (yyn)
|
||||||
|
{
|
||||||
|
]b4_user_actions[
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
yy_symbol_print ("-> $$ =", yyr1_[yyn], yyval]b4_locations_if([, yyloc])[);
|
||||||
|
|
||||||
|
yystack.pop (yylen);
|
||||||
|
yylen = 0;
|
||||||
|
|
||||||
|
/* Shift the result of the reduction. */
|
||||||
|
yyn = yyr1_[yyn];
|
||||||
|
int yystate = yypgoto_[yyn - yyntokens_] + yystack.stateAt (0);
|
||||||
|
if (0 <= yystate && yystate <= yylast_
|
||||||
|
&& yycheck_[yystate] == yystack.stateAt (0))
|
||||||
|
yystate = yytable_[yystate];
|
||||||
|
else
|
||||||
|
yystate = yydefgoto_[yyn - yyntokens_];
|
||||||
|
|
||||||
|
yystack.push (yystate, yyval]b4_locations_if([, yyloc])[);
|
||||||
|
return YYNEWSTATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return YYSTR after stripping away unnecessary quotes and
|
||||||
|
backslashes, so that it's suitable for yyerror. The heuristic is
|
||||||
|
that double-quoting is unnecessary unless the string contains an
|
||||||
|
apostrophe, a comma, or backslash (other than backslash-backslash).
|
||||||
|
YYSTR is taken from yytname. */
|
||||||
|
private final String yytnamerr_ (String yystr)
|
||||||
|
{
|
||||||
|
if (yystr.charAt (0) == '"')
|
||||||
|
{
|
||||||
|
StringBuffer yyr = new StringBuffer ();
|
||||||
|
strip_quotes: for (int i = 1; i < yystr.length (); i++)
|
||||||
|
switch (yystr.charAt (i))
|
||||||
|
{
|
||||||
|
case '\'':
|
||||||
|
case ',':
|
||||||
|
break strip_quotes;
|
||||||
|
|
||||||
|
case '\\':
|
||||||
|
if (yystr.charAt(++i) != '\\')
|
||||||
|
break strip_quotes;
|
||||||
|
/* Fall through. */
|
||||||
|
default:
|
||||||
|
yyr.append (yystr.charAt (i));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '"':
|
||||||
|
return yyr.toString ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (yystr.equals ("$end"))
|
||||||
|
return "end of input";
|
||||||
|
|
||||||
|
return yystr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------.
|
||||||
|
| Print this symbol on YYOUTPUT. |
|
||||||
|
`--------------------------------*/
|
||||||
|
|
||||||
|
private void yy_symbol_print (String s, int yytype,
|
||||||
|
]b4_yystype[ yyvaluep]dnl
|
||||||
|
b4_locations_if([, Object yylocationp])[)
|
||||||
|
{
|
||||||
|
if (yydebug > 0)
|
||||||
|
yycdebug (s + (yytype < yyntokens_ ? " token " : " nterm ")
|
||||||
|
+ yytname_[yytype] + " ("]b4_locations_if([
|
||||||
|
+ yylocationp + ": "])[
|
||||||
|
+ (yyvaluep == null ? "(null)" : yyvaluep.toString ()) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse input from the scanner that was specified at object construction
|
||||||
|
* time. Return whether the end of the input was reached successfully.
|
||||||
|
*
|
||||||
|
* @@return <tt>true</tt> if the parsing succeeds. Note that this does not
|
||||||
|
* imply that there were no syntax errors.
|
||||||
|
*/
|
||||||
|
public boolean parse () ]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[
|
||||||
|
{
|
||||||
|
/// Lookahead and lookahead in internal form.
|
||||||
|
int yychar = yyempty_;
|
||||||
|
int yytoken = 0;
|
||||||
|
|
||||||
|
/* State. */
|
||||||
|
int yyn = 0;
|
||||||
|
int yylen = 0;
|
||||||
|
int yystate = 0;
|
||||||
|
|
||||||
|
YYStack yystack = new YYStack ();
|
||||||
|
|
||||||
|
/* Error handling. */
|
||||||
|
int yynerrs_ = 0;
|
||||||
|
]b4_locations_if([/// The location where the error started.
|
||||||
|
]b4_location_type[ yyerrloc = null;
|
||||||
|
|
||||||
|
/// ]b4_location_type[ of the lookahead.
|
||||||
|
]b4_location_type[ yylloc = new ]b4_location_type[ (null, null);
|
||||||
|
|
||||||
|
/// @@$.
|
||||||
|
]b4_location_type[ yyloc;])
|
||||||
|
|
||||||
|
/// Semantic value of the lookahead.
|
||||||
|
b4_yystype[ yylval = null;
|
||||||
|
|
||||||
|
yycdebug ("Starting parse\n");
|
||||||
|
yyerrstatus_ = 0;
|
||||||
|
|
||||||
|
]m4_ifdef([b4_initial_action], [
|
||||||
|
b4_dollar_pushdef([yylval], [], [yylloc])dnl
|
||||||
|
/* User initialization code. */
|
||||||
|
b4_user_initial_action
|
||||||
|
b4_dollar_popdef])[]dnl
|
||||||
|
|
||||||
|
[ /* Initialize the stack. */
|
||||||
|
yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);
|
||||||
|
|
||||||
|
int label = YYNEWSTATE;
|
||||||
|
for (;;)
|
||||||
|
switch (label)
|
||||||
|
{
|
||||||
|
/* New state. Unlike in the C/C++ skeletons, the state is already
|
||||||
|
pushed when we come here. */
|
||||||
|
case YYNEWSTATE:
|
||||||
|
yycdebug ("Entering state " + yystate + "\n");
|
||||||
|
if (yydebug > 0)
|
||||||
|
yystack.print (yyDebugStream);
|
||||||
|
|
||||||
|
/* Accept? */
|
||||||
|
if (yystate == yyfinal_)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* Take a decision. First try without lookahead. */
|
||||||
|
yyn = yypact_[yystate];
|
||||||
|
if (yy_pact_value_is_default_ (yyn))
|
||||||
|
{
|
||||||
|
label = YYDEFAULT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read a lookahead token. */
|
||||||
|
if (yychar == yyempty_)
|
||||||
|
{
|
||||||
|
yycdebug ("Reading a token: ");
|
||||||
|
yychar = yylex ();]
|
||||||
|
b4_locations_if([[
|
||||||
|
yylloc = new ]b4_location_type[(yylexer.getStartPos (),
|
||||||
|
yylexer.getEndPos ());]])
|
||||||
|
yylval = yylexer.getLVal ();[
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert token to internal form. */
|
||||||
|
if (yychar <= EOF)
|
||||||
|
{
|
||||||
|
yychar = yytoken = EOF;
|
||||||
|
yycdebug ("Now at end of input.\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
yytoken = yytranslate_ (yychar);
|
||||||
|
yy_symbol_print ("Next token is", yytoken,
|
||||||
|
yylval]b4_locations_if([, yylloc])[);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the proper action on seeing token YYTOKEN is to reduce or to
|
||||||
|
detect an error, take that action. */
|
||||||
|
yyn += yytoken;
|
||||||
|
if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yytoken)
|
||||||
|
label = YYDEFAULT;
|
||||||
|
|
||||||
|
/* <= 0 means reduce or error. */
|
||||||
|
else if ((yyn = yytable_[yyn]) <= 0)
|
||||||
|
{
|
||||||
|
if (yy_table_value_is_error_ (yyn))
|
||||||
|
label = YYERRLAB;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
yyn = -yyn;
|
||||||
|
label = YYREDUCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Shift the lookahead token. */
|
||||||
|
yy_symbol_print ("Shifting", yytoken,
|
||||||
|
yylval]b4_locations_if([, yylloc])[);
|
||||||
|
|
||||||
|
/* Discard the token being shifted. */
|
||||||
|
yychar = yyempty_;
|
||||||
|
|
||||||
|
/* Count tokens shifted since error; after three, turn off error
|
||||||
|
status. */
|
||||||
|
if (yyerrstatus_ > 0)
|
||||||
|
--yyerrstatus_;
|
||||||
|
|
||||||
|
yystate = yyn;
|
||||||
|
yystack.push (yystate, yylval]b4_locations_if([, yylloc])[);
|
||||||
|
label = YYNEWSTATE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------.
|
||||||
|
| yydefault -- do the default action for the current state. |
|
||||||
|
`-----------------------------------------------------------*/
|
||||||
|
case YYDEFAULT:
|
||||||
|
yyn = yydefact_[yystate];
|
||||||
|
if (yyn == 0)
|
||||||
|
label = YYERRLAB;
|
||||||
|
else
|
||||||
|
label = YYREDUCE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*-----------------------------.
|
||||||
|
| yyreduce -- Do a reduction. |
|
||||||
|
`-----------------------------*/
|
||||||
|
case YYREDUCE:
|
||||||
|
yylen = yyr2_[yyn];
|
||||||
|
label = yyaction (yyn, yystack, yylen);
|
||||||
|
yystate = yystack.stateAt (0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*------------------------------------.
|
||||||
|
| yyerrlab -- here on detecting error |
|
||||||
|
`------------------------------------*/
|
||||||
|
case YYERRLAB:
|
||||||
|
/* If not already recovering from an error, report this error. */
|
||||||
|
if (yyerrstatus_ == 0)
|
||||||
|
{
|
||||||
|
++yynerrs_;
|
||||||
|
if (yychar == yyempty_)
|
||||||
|
yytoken = yyempty_;
|
||||||
|
yyerror (]b4_locations_if([yylloc, ])[yysyntax_error (yystate, yytoken));
|
||||||
|
}
|
||||||
|
|
||||||
|
]b4_locations_if([yyerrloc = yylloc;])[
|
||||||
|
if (yyerrstatus_ == 3)
|
||||||
|
{
|
||||||
|
/* If just tried and failed to reuse lookahead token after an
|
||||||
|
error, discard it. */
|
||||||
|
|
||||||
|
if (yychar <= EOF)
|
||||||
|
{
|
||||||
|
/* Return failure if at end of input. */
|
||||||
|
if (yychar == EOF)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
yychar = yyempty_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Else will try to reuse lookahead token after shifting the error
|
||||||
|
token. */
|
||||||
|
label = YYERRLAB1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*---------------------------------------------------.
|
||||||
|
| errorlab -- error raised explicitly by YYERROR. |
|
||||||
|
`---------------------------------------------------*/
|
||||||
|
case YYERROR:
|
||||||
|
|
||||||
|
]b4_locations_if([yyerrloc = yystack.locationAt (yylen - 1);])[
|
||||||
|
/* Do not reclaim the symbols of the rule which action triggered
|
||||||
|
this YYERROR. */
|
||||||
|
yystack.pop (yylen);
|
||||||
|
yylen = 0;
|
||||||
|
yystate = yystack.stateAt (0);
|
||||||
|
label = YYERRLAB1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------.
|
||||||
|
| yyerrlab1 -- common code for both syntax error and YYERROR. |
|
||||||
|
`-------------------------------------------------------------*/
|
||||||
|
case YYERRLAB1:
|
||||||
|
yyerrstatus_ = 3; /* Each real token shifted decrements this. */
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
yyn = yypact_[yystate];
|
||||||
|
if (!yy_pact_value_is_default_ (yyn))
|
||||||
|
{
|
||||||
|
yyn += yyterror_;
|
||||||
|
if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_)
|
||||||
|
{
|
||||||
|
yyn = yytable_[yyn];
|
||||||
|
if (0 < yyn)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pop the current state because it cannot handle the error token. */
|
||||||
|
if (yystack.height == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
]b4_locations_if([yyerrloc = yystack.locationAt (0);])[
|
||||||
|
yystack.pop ();
|
||||||
|
yystate = yystack.stateAt (0);
|
||||||
|
if (yydebug > 0)
|
||||||
|
yystack.print (yyDebugStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
]b4_locations_if([
|
||||||
|
/* Muck with the stack to setup for yylloc. */
|
||||||
|
yystack.push (0, null, yylloc);
|
||||||
|
yystack.push (0, null, yyerrloc);
|
||||||
|
yyloc = yylloc (yystack, 2);
|
||||||
|
yystack.pop (2);])[
|
||||||
|
|
||||||
|
/* Shift the error token. */
|
||||||
|
yy_symbol_print ("Shifting", yystos_[yyn],
|
||||||
|
yylval]b4_locations_if([, yyloc])[);
|
||||||
|
|
||||||
|
yystate = yyn;
|
||||||
|
yystack.push (yyn, yylval]b4_locations_if([, yyloc])[);
|
||||||
|
label = YYNEWSTATE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Accept. */
|
||||||
|
case YYACCEPT:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* Abort. */
|
||||||
|
case YYABORT:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate an error message.
|
||||||
|
private String yysyntax_error (int yystate, int tok)
|
||||||
|
{
|
||||||
|
if (errorVerbose)
|
||||||
|
{
|
||||||
|
/* There are many possibilities here to consider:
|
||||||
|
- Assume YYFAIL is not used. It's too flawed to consider.
|
||||||
|
See
|
||||||
|
<http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
|
||||||
|
for details. YYERROR is fine as it does not invoke this
|
||||||
|
function.
|
||||||
|
- If this state is a consistent state with a default action,
|
||||||
|
then the only way this function was invoked is if the
|
||||||
|
default action is an error action. In that case, don't
|
||||||
|
check for expected tokens because there are none.
|
||||||
|
- The only way there can be no lookahead present (in tok) is
|
||||||
|
if this state is a consistent state with a default action.
|
||||||
|
Thus, detecting the absence of a lookahead is sufficient to
|
||||||
|
determine that there is no unexpected or expected token to
|
||||||
|
report. In that case, just report a simple "syntax error".
|
||||||
|
- Don't assume there isn't a lookahead just because this
|
||||||
|
state is a consistent state with a default action. There
|
||||||
|
might have been a previous inconsistent state, consistent
|
||||||
|
state with a non-default action, or user semantic action
|
||||||
|
that manipulated yychar. (However, yychar is currently out
|
||||||
|
of scope during semantic actions.)
|
||||||
|
- Of course, the expected token list depends on states to
|
||||||
|
have correct lookahead information, and it depends on the
|
||||||
|
parser not to perform extra reductions after fetching a
|
||||||
|
lookahead from the scanner and before detecting a syntax
|
||||||
|
error. Thus, state merging (from LALR or IELR) and default
|
||||||
|
reductions corrupt the expected token list. However, the
|
||||||
|
list is correct for canonical LR with one exception: it
|
||||||
|
will still contain any token that will not be accepted due
|
||||||
|
to an error action in a later state.
|
||||||
|
*/
|
||||||
|
if (tok != yyempty_)
|
||||||
|
{
|
||||||
|
// FIXME: This method of building the message is not compatible
|
||||||
|
// with internationalization.
|
||||||
|
StringBuffer res =
|
||||||
|
new StringBuffer ("syntax error, unexpected ");
|
||||||
|
res.append (yytnamerr_ (yytname_[tok]));
|
||||||
|
int yyn = yypact_[yystate];
|
||||||
|
if (!yy_pact_value_is_default_ (yyn))
|
||||||
|
{
|
||||||
|
/* Start YYX at -YYN if negative to avoid negative
|
||||||
|
indexes in YYCHECK. In other words, skip the first
|
||||||
|
-YYN actions for this state because they are default
|
||||||
|
actions. */
|
||||||
|
int yyxbegin = yyn < 0 ? -yyn : 0;
|
||||||
|
/* Stay within bounds of both yycheck and yytname. */
|
||||||
|
int yychecklim = yylast_ - yyn + 1;
|
||||||
|
int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;
|
||||||
|
int count = 0;
|
||||||
|
for (int x = yyxbegin; x < yyxend; ++x)
|
||||||
|
if (yycheck_[x + yyn] == x && x != yyterror_
|
||||||
|
&& !yy_table_value_is_error_ (yytable_[x + yyn]))
|
||||||
|
++count;
|
||||||
|
if (count < 5)
|
||||||
|
{
|
||||||
|
count = 0;
|
||||||
|
for (int x = yyxbegin; x < yyxend; ++x)
|
||||||
|
if (yycheck_[x + yyn] == x && x != yyterror_
|
||||||
|
&& !yy_table_value_is_error_ (yytable_[x + yyn]))
|
||||||
|
{
|
||||||
|
res.append (count++ == 0 ? ", expecting " : " or ");
|
||||||
|
res.append (yytnamerr_ (yytname_[x]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res.toString ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "syntax error";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the given <code>yypact_</code> value indicates a defaulted state.
|
||||||
|
* @@param yyvalue the value to check
|
||||||
|
*/
|
||||||
|
private static boolean yy_pact_value_is_default_ (int yyvalue)
|
||||||
|
{
|
||||||
|
return yyvalue == yypact_ninf_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the given <code>yytable_</code> value indicates a syntax error.
|
||||||
|
* @@param yyvalue the value to check
|
||||||
|
*/
|
||||||
|
private static boolean yy_table_value_is_error_ (int yyvalue)
|
||||||
|
{
|
||||||
|
return yyvalue == yytable_ninf_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
|
||||||
|
STATE-NUM. */
|
||||||
|
private static final ]b4_int_type_for([b4_pact])[ yypact_ninf_ = ]b4_pact_ninf[;
|
||||||
|
private static final ]b4_int_type_for([b4_pact])[ yypact_[] =
|
||||||
|
{
|
||||||
|
]b4_pact[
|
||||||
|
};
|
||||||
|
|
||||||
|
/* YYDEFACT[S] -- default reduction number in state S. Performed when
|
||||||
|
YYTABLE doesn't specify something else to do. Zero means the
|
||||||
|
default is an error. */
|
||||||
|
private static final ]b4_int_type_for([b4_defact])[ yydefact_[] =
|
||||||
|
{
|
||||||
|
]b4_defact[
|
||||||
|
};
|
||||||
|
|
||||||
|
/* YYPGOTO[NTERM-NUM]. */
|
||||||
|
private static final ]b4_int_type_for([b4_pgoto])[ yypgoto_[] =
|
||||||
|
{
|
||||||
|
]b4_pgoto[
|
||||||
|
};
|
||||||
|
|
||||||
|
/* YYDEFGOTO[NTERM-NUM]. */
|
||||||
|
private static final ]b4_int_type_for([b4_defgoto])[
|
||||||
|
yydefgoto_[] =
|
||||||
|
{
|
||||||
|
]b4_defgoto[
|
||||||
|
};
|
||||||
|
|
||||||
|
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
|
||||||
|
positive, shift that token. If negative, reduce the rule which
|
||||||
|
number is the opposite. If YYTABLE_NINF_, syntax error. */
|
||||||
|
private static final ]b4_int_type_for([b4_table])[ yytable_ninf_ = ]b4_table_ninf[;
|
||||||
|
private static final ]b4_int_type_for([b4_table])[
|
||||||
|
yytable_[] =
|
||||||
|
{
|
||||||
|
]b4_table[
|
||||||
|
};
|
||||||
|
|
||||||
|
/* YYCHECK. */
|
||||||
|
private static final ]b4_int_type_for([b4_check])[
|
||||||
|
yycheck_[] =
|
||||||
|
{
|
||||||
|
]b4_check[
|
||||||
|
};
|
||||||
|
|
||||||
|
/* STOS_[STATE-NUM] -- The (internal number of the) accessing
|
||||||
|
symbol of state STATE-NUM. */
|
||||||
|
private static final ]b4_int_type_for([b4_stos])[
|
||||||
|
yystos_[] =
|
||||||
|
{
|
||||||
|
]b4_stos[
|
||||||
|
};
|
||||||
|
|
||||||
|
/* TOKEN_NUMBER_[YYLEX-NUM] -- Internal symbol number corresponding
|
||||||
|
to YYLEX-NUM. */
|
||||||
|
private static final ]b4_int_type_for([b4_toknum])[
|
||||||
|
yytoken_number_[] =
|
||||||
|
{
|
||||||
|
]b4_toknum[
|
||||||
|
};
|
||||||
|
|
||||||
|
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
|
||||||
|
private static final ]b4_int_type_for([b4_r1])[
|
||||||
|
yyr1_[] =
|
||||||
|
{
|
||||||
|
]b4_r1[
|
||||||
|
};
|
||||||
|
|
||||||
|
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
|
||||||
|
private static final ]b4_int_type_for([b4_r2])[
|
||||||
|
yyr2_[] =
|
||||||
|
{
|
||||||
|
]b4_r2[
|
||||||
|
};
|
||||||
|
|
||||||
|
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
|
||||||
|
First, the terminals, then, starting at \a yyntokens_, nonterminals. */
|
||||||
|
private static final String yytname_[] =
|
||||||
|
{
|
||||||
|
]b4_tname[
|
||||||
|
};
|
||||||
|
|
||||||
|
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
|
||||||
|
private static final ]b4_int_type_for([b4_rhs])[ yyrhs_[] =
|
||||||
|
{
|
||||||
|
]b4_rhs[
|
||||||
|
};
|
||||||
|
|
||||||
|
/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
|
||||||
|
YYRHS. */
|
||||||
|
private static final ]b4_int_type_for([b4_prhs])[ yyprhs_[] =
|
||||||
|
{
|
||||||
|
]b4_prhs[
|
||||||
|
};
|
||||||
|
|
||||||
|
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
|
||||||
|
private static final ]b4_int_type_for([b4_rline])[ yyrline_[] =
|
||||||
|
{
|
||||||
|
]b4_rline[
|
||||||
|
};
|
||||||
|
|
||||||
|
// Report on the debug stream that the rule yyrule is going to be reduced.
|
||||||
|
private void yy_reduce_print (int yyrule, YYStack yystack)
|
||||||
|
{
|
||||||
|
if (yydebug == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int yylno = yyrline_[yyrule];
|
||||||
|
int yynrhs = yyr2_[yyrule];
|
||||||
|
/* Print the symbols being reduced, and their result. */
|
||||||
|
yycdebug ("Reducing stack by rule " + (yyrule - 1)
|
||||||
|
+ " (line " + yylno + "), ");
|
||||||
|
|
||||||
|
/* The symbols being reduced. */
|
||||||
|
for (int yyi = 0; yyi < yynrhs; yyi++)
|
||||||
|
yy_symbol_print (" $" + (yyi + 1) + " =",
|
||||||
|
yyrhs_[yyprhs_[yyrule] + yyi],
|
||||||
|
]b4_rhs_value(yynrhs, yyi + 1)b4_locations_if([,
|
||||||
|
b4_rhs_location(yynrhs, yyi + 1)])[);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
|
||||||
|
private static final ]b4_int_type_for([b4_translate])[ yytranslate_table_[] =
|
||||||
|
{
|
||||||
|
]b4_translate[
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final ]b4_int_type_for([b4_translate])[ yytranslate_ (int t)
|
||||||
|
{
|
||||||
|
if (t >= 0 && t <= yyuser_token_number_max_)
|
||||||
|
return yytranslate_table_[t];
|
||||||
|
else
|
||||||
|
return yyundef_token_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int yylast_ = ]b4_last[;
|
||||||
|
private static final int yynnts_ = ]b4_nterms_number[;
|
||||||
|
private static final int yyempty_ = -2;
|
||||||
|
private static final int yyfinal_ = ]b4_final_state_number[;
|
||||||
|
private static final int yyterror_ = 1;
|
||||||
|
private static final int yyerrcode_ = 256;
|
||||||
|
private static final int yyntokens_ = ]b4_tokens_number[;
|
||||||
|
|
||||||
|
private static final int yyuser_token_number_max_ = ]b4_user_token_number_max[;
|
||||||
|
private static final int yyundef_token_ = ]b4_undef_token_number[;
|
||||||
|
|
||||||
|
]/* User implementation code. */
|
||||||
|
b4_percent_code_get[]dnl
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
b4_epilogue
|
||||||
|
b4_output_end()
|
||||||
299
tools/data/location.cc
Normal file
299
tools/data/location.cc
Normal file
@@ -0,0 +1,299 @@
|
|||||||
|
# C++ skeleton for Bison
|
||||||
|
|
||||||
|
# Copyright (C) 2002-2007, 2009-2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
b4_output_begin([b4_dir_prefix[]position.hh])
|
||||||
|
b4_copyright([Positions for Bison parsers in C++],
|
||||||
|
[2002-2007, 2009-2012])[
|
||||||
|
|
||||||
|
/**
|
||||||
|
** \file ]b4_dir_prefix[position.hh
|
||||||
|
** Define the ]b4_namespace_ref[::position class.
|
||||||
|
*/
|
||||||
|
|
||||||
|
]b4_cpp_guard_open([b4_dir_prefix[]position.hh])[
|
||||||
|
|
||||||
|
# include <algorithm> // std::max
|
||||||
|
# include <iostream>
|
||||||
|
# include <string>
|
||||||
|
|
||||||
|
]b4_null_define[
|
||||||
|
|
||||||
|
]b4_namespace_open[
|
||||||
|
/// Abstract a position.
|
||||||
|
class position
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
]m4_ifdef([b4_location_constructors], [[
|
||||||
|
/// Construct a position.
|
||||||
|
explicit position (]b4_percent_define_get([[filename_type]])[* f = YY_NULL,
|
||||||
|
unsigned int l = ]b4_location_initial_line[u,
|
||||||
|
unsigned int c = ]b4_location_initial_column[u)
|
||||||
|
: filename (f)
|
||||||
|
, line (l)
|
||||||
|
, column (c)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
]])[
|
||||||
|
/// Initialization.
|
||||||
|
void initialize (]b4_percent_define_get([[filename_type]])[* fn = YY_NULL,
|
||||||
|
unsigned int l = ]b4_location_initial_line[u,
|
||||||
|
unsigned int c = ]b4_location_initial_column[u)
|
||||||
|
{
|
||||||
|
filename = fn;
|
||||||
|
line = l;
|
||||||
|
column = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \name Line and Column related manipulators
|
||||||
|
** \{ */
|
||||||
|
/// (line related) Advance to the COUNT next lines.
|
||||||
|
void lines (int count = 1)
|
||||||
|
{
|
||||||
|
column = ]b4_location_initial_column[u;
|
||||||
|
line += count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// (column related) Advance to the COUNT next columns.
|
||||||
|
void columns (int count = 1)
|
||||||
|
{
|
||||||
|
column = std::max (]b4_location_initial_column[u, column + count);
|
||||||
|
}
|
||||||
|
/** \} */
|
||||||
|
|
||||||
|
/// File name to which this position refers.
|
||||||
|
]b4_percent_define_get([[filename_type]])[* filename;
|
||||||
|
/// Current line number.
|
||||||
|
unsigned int line;
|
||||||
|
/// Current column number.
|
||||||
|
unsigned int column;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Add and assign a position.
|
||||||
|
inline position&
|
||||||
|
operator+= (position& res, const int width)
|
||||||
|
{
|
||||||
|
res.columns (width);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add two position objects.
|
||||||
|
inline const position
|
||||||
|
operator+ (const position& begin, const int width)
|
||||||
|
{
|
||||||
|
position res = begin;
|
||||||
|
return res += width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add and assign a position.
|
||||||
|
inline position&
|
||||||
|
operator-= (position& res, const int width)
|
||||||
|
{
|
||||||
|
return res += -width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add two position objects.
|
||||||
|
inline const position
|
||||||
|
operator- (const position& begin, const int width)
|
||||||
|
{
|
||||||
|
return begin + -width;
|
||||||
|
}
|
||||||
|
]b4_percent_define_flag_if([[define_location_comparison]], [[
|
||||||
|
/// Compare two position objects.
|
||||||
|
inline bool
|
||||||
|
operator== (const position& pos1, const position& pos2)
|
||||||
|
{
|
||||||
|
return (pos1.line == pos2.line
|
||||||
|
&& pos1.column == pos2.column
|
||||||
|
&& (pos1.filename == pos2.filename
|
||||||
|
|| (pos1.filename && pos2.filename
|
||||||
|
&& *pos1.filename == *pos2.filename)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compare two position objects.
|
||||||
|
inline bool
|
||||||
|
operator!= (const position& pos1, const position& pos2)
|
||||||
|
{
|
||||||
|
return !(pos1 == pos2);
|
||||||
|
}
|
||||||
|
]])[
|
||||||
|
/** \brief Intercept output stream redirection.
|
||||||
|
** \param ostr the destination output stream
|
||||||
|
** \param pos a reference to the position to redirect
|
||||||
|
*/
|
||||||
|
template <typename YYChar>
|
||||||
|
inline std::basic_ostream<YYChar>&
|
||||||
|
operator<< (std::basic_ostream<YYChar>& ostr, const position& pos)
|
||||||
|
{
|
||||||
|
if (pos.filename)
|
||||||
|
ostr << *pos.filename << ':';
|
||||||
|
return ostr << pos.line << '.' << pos.column;
|
||||||
|
}
|
||||||
|
|
||||||
|
]b4_namespace_close[
|
||||||
|
]b4_cpp_guard_close([b4_dir_prefix[]position.hh])
|
||||||
|
b4_output_end()
|
||||||
|
|
||||||
|
|
||||||
|
b4_output_begin([b4_dir_prefix[]location.hh])
|
||||||
|
b4_copyright([Locations for Bison parsers in C++],
|
||||||
|
[2002-2007, 2009-2012])[
|
||||||
|
|
||||||
|
/**
|
||||||
|
** \file ]b4_dir_prefix[location.hh
|
||||||
|
** Define the ]b4_namespace_ref[::location class.
|
||||||
|
*/
|
||||||
|
|
||||||
|
]b4_cpp_guard_open([b4_dir_prefix[]location.hh])[
|
||||||
|
|
||||||
|
# include "position.hh"
|
||||||
|
|
||||||
|
]b4_namespace_open[
|
||||||
|
|
||||||
|
/// Abstract a location.
|
||||||
|
class location
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
]m4_ifdef([b4_location_constructors], [
|
||||||
|
/// Construct a location from \a b to \a e.
|
||||||
|
location (const position& b, const position& e)
|
||||||
|
: begin (b)
|
||||||
|
, end (e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a 0-width location in \a p.
|
||||||
|
explicit location (const position& p = position ())
|
||||||
|
: begin (p)
|
||||||
|
, end (p)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a 0-width location in \a f, \a l, \a c.
|
||||||
|
explicit location (]b4_percent_define_get([[filename_type]])[* f,
|
||||||
|
unsigned int l = ]b4_location_initial_line[u,
|
||||||
|
unsigned int c = ]b4_location_initial_column[u)
|
||||||
|
: begin (f, l, c)
|
||||||
|
, end (f, l, c)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
])[
|
||||||
|
/// Initialization.
|
||||||
|
void initialize (]b4_percent_define_get([[filename_type]])[* f = YY_NULL,
|
||||||
|
unsigned int l = ]b4_location_initial_line[u,
|
||||||
|
unsigned int c = ]b4_location_initial_column[u)
|
||||||
|
{
|
||||||
|
begin.initialize (f, l, c);
|
||||||
|
end = begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \name Line and Column related manipulators
|
||||||
|
** \{ */
|
||||||
|
public:
|
||||||
|
/// Reset initial location to final location.
|
||||||
|
void step ()
|
||||||
|
{
|
||||||
|
begin = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extend the current location to the COUNT next columns.
|
||||||
|
void columns (unsigned int count = 1)
|
||||||
|
{
|
||||||
|
end += count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extend the current location to the COUNT next lines.
|
||||||
|
void lines (unsigned int count = 1)
|
||||||
|
{
|
||||||
|
end.lines (count);
|
||||||
|
}
|
||||||
|
/** \} */
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Beginning of the located region.
|
||||||
|
position begin;
|
||||||
|
/// End of the located region.
|
||||||
|
position end;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Join two location objects to create a location.
|
||||||
|
inline const location operator+ (const location& begin, const location& end)
|
||||||
|
{
|
||||||
|
location res = begin;
|
||||||
|
res.end = end.end;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add two location objects.
|
||||||
|
inline const location operator+ (const location& begin, unsigned int width)
|
||||||
|
{
|
||||||
|
location res = begin;
|
||||||
|
res.columns (width);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add and assign a location.
|
||||||
|
inline location& operator+= (location& res, unsigned int width)
|
||||||
|
{
|
||||||
|
res.columns (width);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
]b4_percent_define_flag_if([[define_location_comparison]], [[
|
||||||
|
/// Compare two location objects.
|
||||||
|
inline bool
|
||||||
|
operator== (const location& loc1, const location& loc2)
|
||||||
|
{
|
||||||
|
return loc1.begin == loc2.begin && loc1.end == loc2.end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compare two location objects.
|
||||||
|
inline bool
|
||||||
|
operator!= (const location& loc1, const location& loc2)
|
||||||
|
{
|
||||||
|
return !(loc1 == loc2);
|
||||||
|
}
|
||||||
|
]])[
|
||||||
|
/** \brief Intercept output stream redirection.
|
||||||
|
** \param ostr the destination output stream
|
||||||
|
** \param loc a reference to the location to redirect
|
||||||
|
**
|
||||||
|
** Avoid duplicate information.
|
||||||
|
*/
|
||||||
|
template <typename YYChar>
|
||||||
|
inline std::basic_ostream<YYChar>&
|
||||||
|
operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)
|
||||||
|
{
|
||||||
|
position last = loc.end - 1;
|
||||||
|
ostr << loc.begin;
|
||||||
|
if (last.filename
|
||||||
|
&& (!loc.begin.filename
|
||||||
|
|| *loc.begin.filename != *last.filename))
|
||||||
|
ostr << '-' << last;
|
||||||
|
else if (loc.begin.line != last.line)
|
||||||
|
ostr << '-' << last.line << '.' << last.column;
|
||||||
|
else if (loc.begin.column != last.column)
|
||||||
|
ostr << '-' << last.column;
|
||||||
|
return ostr;
|
||||||
|
}
|
||||||
|
|
||||||
|
]b4_namespace_close[
|
||||||
|
|
||||||
|
]b4_cpp_guard_close([b4_dir_prefix[]location.hh])
|
||||||
|
b4_output_end()
|
||||||
362
tools/data/m4sugar/foreach.m4
Normal file
362
tools/data/m4sugar/foreach.m4
Normal file
@@ -0,0 +1,362 @@
|
|||||||
|
# -*- Autoconf -*-
|
||||||
|
# This file is part of Autoconf.
|
||||||
|
# foreach-based replacements for recursive functions.
|
||||||
|
# Speeds up GNU M4 1.4.x by avoiding quadratic $@ recursion, but penalizes
|
||||||
|
# GNU M4 1.6 by requiring more memory and macro expansions.
|
||||||
|
#
|
||||||
|
# Copyright (C) 2008-2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This file is part of Autoconf. This program is free
|
||||||
|
# software; you can redistribute it and/or modify it under the
|
||||||
|
# terms of the GNU General Public License as published by the
|
||||||
|
# Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
# permissions described in the Autoconf Configure Script Exception,
|
||||||
|
# version 3.0, as published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# and a copy of the Autoconf Configure Script Exception along with
|
||||||
|
# this program; see the files COPYINGv3 and COPYING.EXCEPTION
|
||||||
|
# respectively. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# Written by Eric Blake.
|
||||||
|
|
||||||
|
# In M4 1.4.x, every byte of $@ is rescanned. This means that an
|
||||||
|
# algorithm on n arguments that recurses with one less argument each
|
||||||
|
# iteration will scan n * (n + 1) / 2 arguments, for O(n^2) time. In
|
||||||
|
# M4 1.6, this was fixed so that $@ is only scanned once, then
|
||||||
|
# back-references are made to information stored about the scan.
|
||||||
|
# Thus, n iterations need only scan n arguments, for O(n) time.
|
||||||
|
# Additionally, in M4 1.4.x, recursive algorithms did not clean up
|
||||||
|
# memory very well, requiring O(n^2) memory rather than O(n) for n
|
||||||
|
# iterations.
|
||||||
|
#
|
||||||
|
# This file is designed to overcome the quadratic nature of $@
|
||||||
|
# recursion by writing a variant of m4_foreach that uses m4_for rather
|
||||||
|
# than $@ recursion to operate on the list. This involves more macro
|
||||||
|
# expansions, but avoids the need to rescan a quadratic number of
|
||||||
|
# arguments, making these replacements very attractive for M4 1.4.x.
|
||||||
|
# On the other hand, in any version of M4, expanding additional macros
|
||||||
|
# costs additional time; therefore, in M4 1.6, where $@ recursion uses
|
||||||
|
# fewer macros, these replacements actually pessimize performance.
|
||||||
|
# Additionally, the use of $10 to mean the tenth argument violates
|
||||||
|
# POSIX; although all versions of m4 1.4.x support this meaning, a
|
||||||
|
# future m4 version may switch to take it as the first argument
|
||||||
|
# concatenated with a literal 0, so the implementations in this file
|
||||||
|
# are not future-proof. Thus, this file is conditionally included as
|
||||||
|
# part of m4_init(), only when it is detected that M4 probably has
|
||||||
|
# quadratic behavior (ie. it lacks the macro __m4_version__).
|
||||||
|
#
|
||||||
|
# Please keep this file in sync with m4sugar.m4.
|
||||||
|
|
||||||
|
# _m4_foreach(PRE, POST, IGNORED, ARG...)
|
||||||
|
# ---------------------------------------
|
||||||
|
# Form the common basis of the m4_foreach and m4_map macros. For each
|
||||||
|
# ARG, expand PRE[ARG]POST[]. The IGNORED argument makes recursion
|
||||||
|
# easier, and must be supplied rather than implicit.
|
||||||
|
#
|
||||||
|
# This version minimizes the number of times that $@ is evaluated by
|
||||||
|
# using m4_for to generate a boilerplate into _m4_f then passing $@ to
|
||||||
|
# that temporary macro. Thus, the recursion is done in m4_for without
|
||||||
|
# reparsing any user input, and is not quadratic. For an idea of how
|
||||||
|
# this works, note that m4_foreach(i,[1,2],[i]) calls
|
||||||
|
# _m4_foreach([m4_define([i],],[)i],[],[1],[2])
|
||||||
|
# which defines _m4_f:
|
||||||
|
# $1[$4]$2[]$1[$5]$2[]_m4_popdef([_m4_f])
|
||||||
|
# then calls _m4_f([m4_define([i],],[)i],[],[1],[2]) for a net result:
|
||||||
|
# m4_define([i],[1])i[]m4_define([i],[2])i[]_m4_popdef([_m4_f]).
|
||||||
|
m4_define([_m4_foreach],
|
||||||
|
[m4_if([$#], [3], [],
|
||||||
|
[m4_pushdef([_m4_f], _m4_for([4], [$#], [1],
|
||||||
|
[$0_([1], [2],], [)])[_m4_popdef([_m4_f])])_m4_f($@)])])
|
||||||
|
|
||||||
|
m4_define([_m4_foreach_],
|
||||||
|
[[$$1[$$3]$$2[]]])
|
||||||
|
|
||||||
|
# m4_case(SWITCH, VAL1, IF-VAL1, VAL2, IF-VAL2, ..., DEFAULT)
|
||||||
|
# -----------------------------------------------------------
|
||||||
|
# Find the first VAL that SWITCH matches, and expand the corresponding
|
||||||
|
# IF-VAL. If there are no matches, expand DEFAULT.
|
||||||
|
#
|
||||||
|
# Use m4_for to create a temporary macro in terms of a boilerplate
|
||||||
|
# m4_if with final cleanup. If $# is even, we have DEFAULT; if it is
|
||||||
|
# odd, then rounding the last $# up in the temporary macro is
|
||||||
|
# harmless. For example, both m4_case(1,2,3,4,5) and
|
||||||
|
# m4_case(1,2,3,4,5,6) result in the intermediate _m4_case being
|
||||||
|
# m4_if([$1],[$2],[$3],[$1],[$4],[$5],_m4_popdef([_m4_case])[$6])
|
||||||
|
m4_define([m4_case],
|
||||||
|
[m4_if(m4_eval([$# <= 2]), [1], [$2],
|
||||||
|
[m4_pushdef([_$0], [m4_if(]_m4_for([2], m4_eval([($# - 1) / 2 * 2]), [2],
|
||||||
|
[_$0_(], [)])[_m4_popdef(
|
||||||
|
[_$0])]m4_dquote($m4_eval([($# + 1) & ~1]))[)])_$0($@)])])
|
||||||
|
|
||||||
|
m4_define([_m4_case_],
|
||||||
|
[$0_([1], [$1], m4_incr([$1]))])
|
||||||
|
|
||||||
|
m4_define([_m4_case__],
|
||||||
|
[[[$$1],[$$2],[$$3],]])
|
||||||
|
|
||||||
|
# m4_bmatch(SWITCH, RE1, VAL1, RE2, VAL2, ..., DEFAULT)
|
||||||
|
# -----------------------------------------------------
|
||||||
|
# m4 equivalent of
|
||||||
|
#
|
||||||
|
# if (SWITCH =~ RE1)
|
||||||
|
# VAL1;
|
||||||
|
# elif (SWITCH =~ RE2)
|
||||||
|
# VAL2;
|
||||||
|
# elif ...
|
||||||
|
# ...
|
||||||
|
# else
|
||||||
|
# DEFAULT
|
||||||
|
#
|
||||||
|
# We build the temporary macro _m4_b:
|
||||||
|
# m4_define([_m4_b], _m4_defn([_m4_bmatch]))_m4_b([$1], [$2], [$3])...
|
||||||
|
# _m4_b([$1], [$m-1], [$m])_m4_b([], [], [$m+1]_m4_popdef([_m4_b]))
|
||||||
|
# then invoke m4_unquote(_m4_b($@)), for concatenation with later text.
|
||||||
|
m4_define([m4_bmatch],
|
||||||
|
[m4_if([$#], 0, [m4_fatal([$0: too few arguments: $#])],
|
||||||
|
[$#], 1, [m4_fatal([$0: too few arguments: $#: $1])],
|
||||||
|
[$#], 2, [$2],
|
||||||
|
[m4_pushdef([_m4_b], [m4_define([_m4_b],
|
||||||
|
_m4_defn([_$0]))]_m4_for([3], m4_eval([($# + 1) / 2 * 2 - 1]),
|
||||||
|
[2], [_$0_(], [)])[_m4_b([], [],]m4_dquote([$]m4_eval(
|
||||||
|
[($# + 1) / 2 * 2]))[_m4_popdef([_m4_b]))])m4_unquote(_m4_b($@))])])
|
||||||
|
|
||||||
|
m4_define([_m4_bmatch],
|
||||||
|
[m4_if(m4_bregexp([$1], [$2]), [-1], [], [[$3]m4_define([$0])])])
|
||||||
|
|
||||||
|
m4_define([_m4_bmatch_],
|
||||||
|
[$0_([1], m4_decr([$1]), [$1])])
|
||||||
|
|
||||||
|
m4_define([_m4_bmatch__],
|
||||||
|
[[_m4_b([$$1], [$$2], [$$3])]])
|
||||||
|
|
||||||
|
|
||||||
|
# m4_cond(TEST1, VAL1, IF-VAL1, TEST2, VAL2, IF-VAL2, ..., [DEFAULT])
|
||||||
|
# -------------------------------------------------------------------
|
||||||
|
# Similar to m4_if, except that each TEST is expanded when encountered.
|
||||||
|
# If the expansion of TESTn matches the string VALn, the result is IF-VALn.
|
||||||
|
# The result is DEFAULT if no tests passed. This macro allows
|
||||||
|
# short-circuiting of expensive tests, where it pays to arrange quick
|
||||||
|
# filter tests to run first.
|
||||||
|
#
|
||||||
|
# m4_cond already guarantees either 3*n or 3*n + 1 arguments, 1 <= n.
|
||||||
|
# We only have to speed up _m4_cond, by building the temporary _m4_c:
|
||||||
|
# m4_define([_m4_c], _m4_defn([m4_unquote]))_m4_c([m4_if(($1), [($2)],
|
||||||
|
# [[$3]m4_define([_m4_c])])])_m4_c([m4_if(($4), [($5)],
|
||||||
|
# [[$6]m4_define([_m4_c])])])..._m4_c([m4_if(($m-2), [($m-1)],
|
||||||
|
# [[$m]m4_define([_m4_c])])])_m4_c([[$m+1]]_m4_popdef([_m4_c]))
|
||||||
|
# We invoke m4_unquote(_m4_c($@)), for concatenation with later text.
|
||||||
|
m4_define([_m4_cond],
|
||||||
|
[m4_pushdef([_m4_c], [m4_define([_m4_c],
|
||||||
|
_m4_defn([m4_unquote]))]_m4_for([2], m4_eval([$# / 3 * 3 - 1]), [3],
|
||||||
|
[$0_(], [)])[_m4_c(]m4_dquote(m4_dquote(
|
||||||
|
[$]m4_eval([$# / 3 * 3 + 1])))[_m4_popdef([_m4_c]))])m4_unquote(_m4_c($@))])
|
||||||
|
|
||||||
|
m4_define([_m4_cond_],
|
||||||
|
[$0_(m4_decr([$1]), [$1], m4_incr([$1]))])
|
||||||
|
|
||||||
|
m4_define([_m4_cond__],
|
||||||
|
[[_m4_c([m4_if(($$1), [($$2)], [[$$3]m4_define([_m4_c])])])]])
|
||||||
|
|
||||||
|
# m4_bpatsubsts(STRING, RE1, SUBST1, RE2, SUBST2, ...)
|
||||||
|
# ----------------------------------------------------
|
||||||
|
# m4 equivalent of
|
||||||
|
#
|
||||||
|
# $_ = STRING;
|
||||||
|
# s/RE1/SUBST1/g;
|
||||||
|
# s/RE2/SUBST2/g;
|
||||||
|
# ...
|
||||||
|
#
|
||||||
|
# m4_bpatsubsts already validated an odd number of arguments; we only
|
||||||
|
# need to speed up _m4_bpatsubsts. To avoid nesting, we build the
|
||||||
|
# temporary _m4_p:
|
||||||
|
# m4_define([_m4_p], [$1])m4_define([_m4_p],
|
||||||
|
# m4_bpatsubst(m4_dquote(_m4_defn([_m4_p])), [$2], [$3]))m4_define([_m4_p],
|
||||||
|
# m4_bpatsubst(m4_dquote(_m4_defn([_m4_p])), [$4], [$5]))m4_define([_m4_p],...
|
||||||
|
# m4_bpatsubst(m4_dquote(_m4_defn([_m4_p])), [$m-1], [$m]))m4_unquote(
|
||||||
|
# _m4_defn([_m4_p])_m4_popdef([_m4_p]))
|
||||||
|
m4_define([_m4_bpatsubsts],
|
||||||
|
[m4_pushdef([_m4_p], [m4_define([_m4_p],
|
||||||
|
]m4_dquote([$]1)[)]_m4_for([3], [$#], [2], [$0_(],
|
||||||
|
[)])[m4_unquote(_m4_defn([_m4_p])_m4_popdef([_m4_p]))])_m4_p($@)])
|
||||||
|
|
||||||
|
m4_define([_m4_bpatsubsts_],
|
||||||
|
[$0_(m4_decr([$1]), [$1])])
|
||||||
|
|
||||||
|
m4_define([_m4_bpatsubsts__],
|
||||||
|
[[m4_define([_m4_p],
|
||||||
|
m4_bpatsubst(m4_dquote(_m4_defn([_m4_p])), [$$1], [$$2]))]])
|
||||||
|
|
||||||
|
# m4_shiftn(N, ...)
|
||||||
|
# -----------------
|
||||||
|
# Returns ... shifted N times. Useful for recursive "varargs" constructs.
|
||||||
|
#
|
||||||
|
# m4_shiftn already validated arguments; we only need to speed up
|
||||||
|
# _m4_shiftn. If N is 3, then we build the temporary _m4_s, defined as
|
||||||
|
# ,[$5],[$6],...,[$m]_m4_popdef([_m4_s])
|
||||||
|
# before calling m4_shift(_m4_s($@)).
|
||||||
|
m4_define([_m4_shiftn],
|
||||||
|
[m4_if(m4_incr([$1]), [$#], [], [m4_pushdef([_m4_s],
|
||||||
|
_m4_for(m4_eval([$1 + 2]), [$#], [1],
|
||||||
|
[[,]m4_dquote($], [)])[_m4_popdef([_m4_s])])m4_shift(_m4_s($@))])])
|
||||||
|
|
||||||
|
# m4_do(STRING, ...)
|
||||||
|
# ------------------
|
||||||
|
# This macro invokes all its arguments (in sequence, of course). It is
|
||||||
|
# useful for making your macros more structured and readable by dropping
|
||||||
|
# unnecessary dnl's and have the macros indented properly.
|
||||||
|
#
|
||||||
|
# Here, we use the temporary macro _m4_do, defined as
|
||||||
|
# $1[]$2[]...[]$n[]_m4_popdef([_m4_do])
|
||||||
|
m4_define([m4_do],
|
||||||
|
[m4_if([$#], [0], [],
|
||||||
|
[m4_pushdef([_$0], _m4_for([1], [$#], [1],
|
||||||
|
[$], [[[]]])[_m4_popdef([_$0])])_$0($@)])])
|
||||||
|
|
||||||
|
# m4_dquote_elt(ARGS)
|
||||||
|
# -------------------
|
||||||
|
# Return ARGS as an unquoted list of double-quoted arguments.
|
||||||
|
#
|
||||||
|
# _m4_foreach to the rescue.
|
||||||
|
m4_define([m4_dquote_elt],
|
||||||
|
[m4_if([$#], [0], [], [[[$1]]_m4_foreach([,m4_dquote(], [)], $@)])])
|
||||||
|
|
||||||
|
# m4_reverse(ARGS)
|
||||||
|
# ----------------
|
||||||
|
# Output ARGS in reverse order.
|
||||||
|
#
|
||||||
|
# Invoke _m4_r($@) with the temporary _m4_r built as
|
||||||
|
# [$m], [$m-1], ..., [$2], [$1]_m4_popdef([_m4_r])
|
||||||
|
m4_define([m4_reverse],
|
||||||
|
[m4_if([$#], [0], [], [$#], [1], [[$1]],
|
||||||
|
[m4_pushdef([_m4_r], [[$$#]]_m4_for(m4_decr([$#]), [1], [-1],
|
||||||
|
[[, ]m4_dquote($], [)])[_m4_popdef([_m4_r])])_m4_r($@)])])
|
||||||
|
|
||||||
|
|
||||||
|
# m4_map_args_pair(EXPRESSION, [END-EXPR = EXPRESSION], ARG...)
|
||||||
|
# -------------------------------------------------------------
|
||||||
|
# Perform a pairwise grouping of consecutive ARGs, by expanding
|
||||||
|
# EXPRESSION([ARG1], [ARG2]). If there are an odd number of ARGs, the
|
||||||
|
# final argument is expanded with END-EXPR([ARGn]).
|
||||||
|
#
|
||||||
|
# Build the temporary macro _m4_map_args_pair, with the $2([$m+1])
|
||||||
|
# only output if $# is odd:
|
||||||
|
# $1([$3], [$4])[]$1([$5], [$6])[]...$1([$m-1],
|
||||||
|
# [$m])[]m4_default([$2], [$1])([$m+1])[]_m4_popdef([_m4_map_args_pair])
|
||||||
|
m4_define([m4_map_args_pair],
|
||||||
|
[m4_if([$#], [0], [m4_fatal([$0: too few arguments: $#])],
|
||||||
|
[$#], [1], [m4_fatal([$0: too few arguments: $#: $1])],
|
||||||
|
[$#], [2], [],
|
||||||
|
[$#], [3], [m4_default([$2], [$1])([$3])[]],
|
||||||
|
[m4_pushdef([_$0], _m4_for([3],
|
||||||
|
m4_eval([$# / 2 * 2 - 1]), [2], [_$0_(], [)])_$0_end(
|
||||||
|
[1], [2], [$#])[_m4_popdef([_$0])])_$0($@)])])
|
||||||
|
|
||||||
|
m4_define([_m4_map_args_pair_],
|
||||||
|
[$0_([1], [$1], m4_incr([$1]))])
|
||||||
|
|
||||||
|
m4_define([_m4_map_args_pair__],
|
||||||
|
[[$$1([$$2], [$$3])[]]])
|
||||||
|
|
||||||
|
m4_define([_m4_map_args_pair_end],
|
||||||
|
[m4_if(m4_eval([$3 & 1]), [1], [[m4_default([$$2], [$$1])([$$3])[]]])])
|
||||||
|
|
||||||
|
# m4_join(SEP, ARG1, ARG2...)
|
||||||
|
# ---------------------------
|
||||||
|
# Produce ARG1SEPARG2...SEPARGn. Avoid back-to-back SEP when a given ARG
|
||||||
|
# is the empty string. No expansion is performed on SEP or ARGs.
|
||||||
|
#
|
||||||
|
# Use a self-modifying separator, since we don't know how many
|
||||||
|
# arguments might be skipped before a separator is first printed, but
|
||||||
|
# be careful if the separator contains $. _m4_foreach to the rescue.
|
||||||
|
m4_define([m4_join],
|
||||||
|
[m4_pushdef([_m4_sep], [m4_define([_m4_sep], _m4_defn([m4_echo]))])]dnl
|
||||||
|
[_m4_foreach([_$0([$1],], [)], $@)_m4_popdef([_m4_sep])])
|
||||||
|
|
||||||
|
m4_define([_m4_join],
|
||||||
|
[m4_if([$2], [], [], [_m4_sep([$1])[$2]])])
|
||||||
|
|
||||||
|
# m4_joinall(SEP, ARG1, ARG2...)
|
||||||
|
# ------------------------------
|
||||||
|
# Produce ARG1SEPARG2...SEPARGn. An empty ARG results in back-to-back SEP.
|
||||||
|
# No expansion is performed on SEP or ARGs.
|
||||||
|
#
|
||||||
|
# A bit easier than m4_join. _m4_foreach to the rescue.
|
||||||
|
m4_define([m4_joinall],
|
||||||
|
[[$2]m4_if(m4_eval([$# <= 2]), [1], [],
|
||||||
|
[_m4_foreach([$1], [], m4_shift($@))])])
|
||||||
|
|
||||||
|
# m4_list_cmp(A, B)
|
||||||
|
# -----------------
|
||||||
|
# Compare the two lists of integer expressions A and B.
|
||||||
|
#
|
||||||
|
# m4_list_cmp takes care of any side effects; we only override
|
||||||
|
# _m4_list_cmp_raw, where we can safely expand lists multiple times.
|
||||||
|
# First, insert padding so that both lists are the same length; the
|
||||||
|
# trailing +0 is necessary to handle a missing list. Next, create a
|
||||||
|
# temporary macro to perform pairwise comparisons until an inequality
|
||||||
|
# is found. For example, m4_list_cmp([1], [1,2]) creates _m4_cmp as
|
||||||
|
# m4_if(m4_eval([($1) != ($3)]), [1], [m4_cmp([$1], [$3])],
|
||||||
|
# m4_eval([($2) != ($4)]), [1], [m4_cmp([$2], [$4])],
|
||||||
|
# [0]_m4_popdef([_m4_cmp]))
|
||||||
|
# then calls _m4_cmp([1+0], [0*2], [1], [2+0])
|
||||||
|
m4_define([_m4_list_cmp_raw],
|
||||||
|
[m4_if([$1], [$2], 0,
|
||||||
|
[_m4_list_cmp($1+0_m4_list_pad(m4_count($1), m4_count($2)),
|
||||||
|
$2+0_m4_list_pad(m4_count($2), m4_count($1)))])])
|
||||||
|
|
||||||
|
m4_define([_m4_list_pad],
|
||||||
|
[m4_if(m4_eval($1 < $2), [1],
|
||||||
|
[_m4_for(m4_incr([$1]), [$2], [1], [,0*])])])
|
||||||
|
|
||||||
|
m4_define([_m4_list_cmp],
|
||||||
|
[m4_pushdef([_m4_cmp], [m4_if(]_m4_for(
|
||||||
|
[1], m4_eval([$# >> 1]), [1], [$0_(], [,]m4_eval([$# >> 1])[)])[
|
||||||
|
[0]_m4_popdef([_m4_cmp]))])_m4_cmp($@)])
|
||||||
|
|
||||||
|
m4_define([_m4_list_cmp_],
|
||||||
|
[$0_([$1], m4_eval([$1 + $2]))])
|
||||||
|
|
||||||
|
m4_define([_m4_list_cmp__],
|
||||||
|
[[m4_eval([($$1) != ($$2)]), [1], [m4_cmp([$$1], [$$2])],
|
||||||
|
]])
|
||||||
|
|
||||||
|
# m4_max(EXPR, ...)
|
||||||
|
# m4_min(EXPR, ...)
|
||||||
|
# -----------------
|
||||||
|
# Return the decimal value of the maximum (or minimum) in a series of
|
||||||
|
# integer expressions.
|
||||||
|
#
|
||||||
|
# _m4_foreach to the rescue; we only need to replace _m4_minmax. Here,
|
||||||
|
# we need a temporary macro to track the best answer so far, so that
|
||||||
|
# the foreach expression is tractable.
|
||||||
|
m4_define([_m4_minmax],
|
||||||
|
[m4_pushdef([_m4_best], m4_eval([$2]))_m4_foreach(
|
||||||
|
[m4_define([_m4_best], $1(_m4_best,], [))], m4_shift($@))]dnl
|
||||||
|
[_m4_best[]_m4_popdef([_m4_best])])
|
||||||
|
|
||||||
|
# m4_set_add_all(SET, VALUE...)
|
||||||
|
# -----------------------------
|
||||||
|
# Add each VALUE into SET. This is O(n) in the number of VALUEs, and
|
||||||
|
# can be faster than calling m4_set_add for each VALUE.
|
||||||
|
#
|
||||||
|
# _m4_foreach to the rescue. If no deletions have occurred, then
|
||||||
|
# avoid the speed penalty of m4_set_add.
|
||||||
|
m4_define([m4_set_add_all],
|
||||||
|
[m4_if([$#], [0], [], [$#], [1], [],
|
||||||
|
[m4_define([_m4_set_size($1)], m4_eval(m4_set_size([$1])
|
||||||
|
+ m4_len(_m4_foreach(m4_ifdef([_m4_set_cleanup($1)],
|
||||||
|
[[m4_set_add]], [[_$0]])[([$1],], [)], $@))))])])
|
||||||
|
|
||||||
|
m4_define([_m4_set_add_all],
|
||||||
|
[m4_ifdef([_m4_set([$1],$2)], [],
|
||||||
|
[m4_define([_m4_set([$1],$2)],
|
||||||
|
[1])m4_pushdef([_m4_set([$1])], [$2])-])])
|
||||||
3301
tools/data/m4sugar/m4sugar.m4
Normal file
3301
tools/data/m4sugar/m4sugar.m4
Normal file
File diff suppressed because it is too large
Load Diff
121
tools/data/stack.hh
Normal file
121
tools/data/stack.hh
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
# C++ skeleton for Bison
|
||||||
|
|
||||||
|
# Copyright (C) 2002-2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
m4_pushdef([b4_copyright_years],
|
||||||
|
[2002-2012])
|
||||||
|
|
||||||
|
b4_output_begin([b4_dir_prefix[]stack.hh])
|
||||||
|
b4_copyright([Stack handling for Bison parsers in C++],
|
||||||
|
[2002-2012])[
|
||||||
|
|
||||||
|
/**
|
||||||
|
** \file ]b4_dir_prefix[stack.hh
|
||||||
|
** Define the ]b4_namespace_ref[::stack class.
|
||||||
|
*/
|
||||||
|
|
||||||
|
]b4_cpp_guard_open([b4_dir_prefix[]stack.hh])[
|
||||||
|
|
||||||
|
# include <deque>
|
||||||
|
|
||||||
|
]b4_namespace_open[
|
||||||
|
template <class T, class S = std::deque<T> >
|
||||||
|
class stack
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Hide our reversed order.
|
||||||
|
typedef typename S::reverse_iterator iterator;
|
||||||
|
typedef typename S::const_reverse_iterator const_iterator;
|
||||||
|
|
||||||
|
stack () : seq_ ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
stack (unsigned int n) : seq_ (n)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
T&
|
||||||
|
operator [] (unsigned int i)
|
||||||
|
{
|
||||||
|
return seq_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
const T&
|
||||||
|
operator [] (unsigned int i) const
|
||||||
|
{
|
||||||
|
return seq_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
push (const T& t)
|
||||||
|
{
|
||||||
|
seq_.push_front (t);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
pop (unsigned int n = 1)
|
||||||
|
{
|
||||||
|
for (; n; --n)
|
||||||
|
seq_.pop_front ();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
unsigned int
|
||||||
|
height () const
|
||||||
|
{
|
||||||
|
return seq_.size ();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const_iterator begin () const { return seq_.rbegin (); }
|
||||||
|
inline const_iterator end () const { return seq_.rend (); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
S seq_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Present a slice of the top of a stack.
|
||||||
|
template <class T, class S = stack<T> >
|
||||||
|
class slice
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
slice (const S& stack, unsigned int range)
|
||||||
|
: stack_ (stack)
|
||||||
|
, range_ (range)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
const T&
|
||||||
|
operator [] (unsigned int i) const
|
||||||
|
{
|
||||||
|
return stack_[range_ - i];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const S& stack_;
|
||||||
|
unsigned int range_;
|
||||||
|
};
|
||||||
|
]b4_namespace_close[
|
||||||
|
|
||||||
|
]b4_cpp_guard_close([b4_dir_prefix[]stack.hh])
|
||||||
|
b4_output_end()
|
||||||
|
|
||||||
|
m4_popdef([b4_copyright_years])
|
||||||
105
tools/data/xslt/bison.xsl
Normal file
105
tools/data/xslt/bison.xsl
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
bison.xsl - common templates for Bison XSLT.
|
||||||
|
|
||||||
|
Copyright (C) 2007-2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Bison, the GNU Compiler Compiler.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<xsl:stylesheet version="1.0"
|
||||||
|
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||||
|
xmlns:bison="http://www.gnu.org/software/bison/">
|
||||||
|
|
||||||
|
<xsl:key
|
||||||
|
name="bison:symbolByName"
|
||||||
|
match="/bison-xml-report/grammar/nonterminals/nonterminal"
|
||||||
|
use="@name"
|
||||||
|
/>
|
||||||
|
<xsl:key
|
||||||
|
name="bison:symbolByName"
|
||||||
|
match="/bison-xml-report/grammar/terminals/terminal"
|
||||||
|
use="@name"
|
||||||
|
/>
|
||||||
|
<xsl:key
|
||||||
|
name="bison:ruleByNumber"
|
||||||
|
match="/bison-xml-report/grammar/rules/rule"
|
||||||
|
use="@number"
|
||||||
|
/>
|
||||||
|
<xsl:key
|
||||||
|
name="bison:ruleByLhs"
|
||||||
|
match="/bison-xml-report/grammar/rules/rule[
|
||||||
|
@usefulness != 'useless-in-grammar']"
|
||||||
|
use="lhs"
|
||||||
|
/>
|
||||||
|
<xsl:key
|
||||||
|
name="bison:ruleByRhs"
|
||||||
|
match="/bison-xml-report/grammar/rules/rule[
|
||||||
|
@usefulness != 'useless-in-grammar']"
|
||||||
|
use="rhs/symbol"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- For the specified state, output: #sr-conflicts,#rr-conflicts -->
|
||||||
|
<xsl:template match="state" mode="bison:count-conflicts">
|
||||||
|
<xsl:variable name="transitions" select="actions/transitions"/>
|
||||||
|
<xsl:variable name="reductions" select="actions/reductions"/>
|
||||||
|
<xsl:variable
|
||||||
|
name="terminals"
|
||||||
|
select="
|
||||||
|
$transitions/transition[@type='shift']/@symbol
|
||||||
|
| $reductions/reduction/@symbol
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
<xsl:variable name="conflict-data">
|
||||||
|
<xsl:for-each select="$terminals">
|
||||||
|
<xsl:variable name="name" select="."/>
|
||||||
|
<xsl:if test="generate-id($terminals[. = $name][1]) = generate-id(.)">
|
||||||
|
<xsl:variable
|
||||||
|
name="shift-count"
|
||||||
|
select="count($transitions/transition[@symbol=$name])"
|
||||||
|
/>
|
||||||
|
<xsl:variable
|
||||||
|
name="reduce-count"
|
||||||
|
select="count($reductions/reduction[@symbol=$name])"
|
||||||
|
/>
|
||||||
|
<xsl:if test="$shift-count > 0 and $reduce-count > 0">
|
||||||
|
<xsl:text>s</xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:if test="$reduce-count > 1">
|
||||||
|
<xsl:text>r</xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:variable>
|
||||||
|
<xsl:value-of select="string-length(translate($conflict-data, 'r', ''))"/>
|
||||||
|
<xsl:text>,</xsl:text>
|
||||||
|
<xsl:value-of select="string-length(translate($conflict-data, 's', ''))"/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="space">
|
||||||
|
<xsl:param name="repeat">0</xsl:param>
|
||||||
|
<xsl:param name="fill" select="' '"/>
|
||||||
|
<xsl:if test="number($repeat) >= 1">
|
||||||
|
<xsl:call-template name="space">
|
||||||
|
<xsl:with-param name="repeat" select="$repeat - 1"/>
|
||||||
|
<xsl:with-param name="fill" select="$fill"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:value-of select="$fill"/>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
</xsl:stylesheet>
|
||||||
397
tools/data/xslt/xml2dot.xsl
Normal file
397
tools/data/xslt/xml2dot.xsl
Normal file
@@ -0,0 +1,397 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
xml2dot.xsl - transform Bison XML Report into DOT.
|
||||||
|
|
||||||
|
Copyright (C) 2007-2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Bison, the GNU Compiler Compiler.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Written by Wojciech Polak <polak@gnu.org>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<xsl:stylesheet version="1.0"
|
||||||
|
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||||
|
xmlns:bison="http://www.gnu.org/software/bison/">
|
||||||
|
|
||||||
|
<xsl:import href="bison.xsl"/>
|
||||||
|
<xsl:output method="text" encoding="UTF-8" indent="no"/>
|
||||||
|
|
||||||
|
<xsl:template match="/">
|
||||||
|
<xsl:apply-templates select="bison-xml-report"/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="bison-xml-report">
|
||||||
|
<xsl:text>// Generated by GNU Bison </xsl:text>
|
||||||
|
<xsl:value-of select="@version"/>
|
||||||
|
<xsl:text>. </xsl:text>
|
||||||
|
<xsl:text>// Report bugs to <</xsl:text>
|
||||||
|
<xsl:value-of select="@bug-report"/>
|
||||||
|
<xsl:text>>. </xsl:text>
|
||||||
|
<xsl:text>// Home page: <</xsl:text>
|
||||||
|
<xsl:value-of select="@url"/>
|
||||||
|
<xsl:text>>. </xsl:text>
|
||||||
|
<xsl:apply-templates select="automaton">
|
||||||
|
<xsl:with-param name="filename" select="filename"/>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="automaton">
|
||||||
|
<xsl:param name="filename"/>
|
||||||
|
<xsl:text>digraph "</xsl:text>
|
||||||
|
<xsl:call-template name="escape">
|
||||||
|
<xsl:with-param name="subject" select="$filename"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:text>" {
|
||||||
|
node [fontname = courier, shape = box, colorscheme = paired6]
|
||||||
|
edge [fontname = courier]
|
||||||
|
|
||||||
|
</xsl:text>
|
||||||
|
<xsl:apply-templates select="state"/>
|
||||||
|
<xsl:text>} </xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="automaton/state">
|
||||||
|
<xsl:call-template name="output-node">
|
||||||
|
<xsl:with-param name="number" select="@number"/>
|
||||||
|
<xsl:with-param name="label">
|
||||||
|
<xsl:apply-templates select="itemset/item"/>
|
||||||
|
</xsl:with-param>
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:apply-templates select="actions/transitions"/>
|
||||||
|
<xsl:apply-templates select="actions/reductions">
|
||||||
|
<xsl:with-param name="staten">
|
||||||
|
<xsl:value-of select="@number"/>
|
||||||
|
</xsl:with-param>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="actions/reductions">
|
||||||
|
<xsl:param name="staten"/>
|
||||||
|
<xsl:for-each select='reduction'>
|
||||||
|
<!-- These variables are needed because the current context can't be
|
||||||
|
refered to directly in XPath expressions. -->
|
||||||
|
<xsl:variable name="rul">
|
||||||
|
<xsl:value-of select="@rule"/>
|
||||||
|
</xsl:variable>
|
||||||
|
<xsl:variable name="ena">
|
||||||
|
<xsl:value-of select="@enabled"/>
|
||||||
|
</xsl:variable>
|
||||||
|
<!-- The foreach's body is protected by this, so that we are actually
|
||||||
|
going to iterate once per reduction rule, and not per lookahead. -->
|
||||||
|
<xsl:if test='not(preceding-sibling::*[@rule=$rul and @enabled=$ena])'>
|
||||||
|
<xsl:variable name="rule">
|
||||||
|
<xsl:choose>
|
||||||
|
<!-- The acceptation state is refered to as 'accept' in the XML, but
|
||||||
|
just as '0' in the DOT. -->
|
||||||
|
<xsl:when test="@rule='accept'">
|
||||||
|
<xsl:text>0</xsl:text>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<xsl:value-of select="@rule"/>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</xsl:variable>
|
||||||
|
|
||||||
|
<!-- The edge's beginning -->
|
||||||
|
<xsl:call-template name="reduction-edge-start">
|
||||||
|
<xsl:with-param name="state" select="$staten"/>
|
||||||
|
<xsl:with-param name="rule" select="$rule"/>
|
||||||
|
<xsl:with-param name="enabled" select="@enabled"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
|
||||||
|
<!-- The edge's tokens -->
|
||||||
|
<!-- Don't show labels for the default action. In other cases, there will
|
||||||
|
always be at least one token, so 'label="[]"' will not occur. -->
|
||||||
|
<xsl:if test='$rule!=0 and not(../reduction[@enabled=$ena and @rule=$rule and @symbol="$default"])'>
|
||||||
|
<xsl:text>label="[</xsl:text>
|
||||||
|
<xsl:for-each select='../reduction[@enabled=$ena and @rule=$rule]'>
|
||||||
|
<xsl:call-template name="escape">
|
||||||
|
<xsl:with-param name="subject" select="@symbol"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:if test="position() != last ()">
|
||||||
|
<xsl:text>, </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:for-each>
|
||||||
|
<xsl:text>]", </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
|
||||||
|
<!-- The edge's end -->
|
||||||
|
<xsl:text>style=solid] </xsl:text>
|
||||||
|
|
||||||
|
<!-- The diamond representing the reduction -->
|
||||||
|
<xsl:call-template name="reduction-node">
|
||||||
|
<xsl:with-param name="state" select="$staten"/>
|
||||||
|
<xsl:with-param name="rule" select="$rule"/>
|
||||||
|
<xsl:with-param name="color">
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test='@enabled="true"'>
|
||||||
|
<xsl:text>3</xsl:text>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<xsl:text>5</xsl:text>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</xsl:with-param>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="actions/transitions">
|
||||||
|
<xsl:apply-templates select="transition"/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="item">
|
||||||
|
<xsl:param name="prev-rule-number"
|
||||||
|
select="preceding-sibling::item[1]/@rule-number"/>
|
||||||
|
<xsl:apply-templates select="key('bison:ruleByNumber', @rule-number)">
|
||||||
|
<xsl:with-param name="point" select="@point"/>
|
||||||
|
<xsl:with-param name="num" select="@rule-number"/>
|
||||||
|
<xsl:with-param name="prev-lhs"
|
||||||
|
select="key('bison:ruleByNumber', $prev-rule-number)/lhs[text()]"
|
||||||
|
/>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
<xsl:apply-templates select="lookaheads"/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="rule">
|
||||||
|
<xsl:param name="point"/>
|
||||||
|
<xsl:param name="num"/>
|
||||||
|
<xsl:param name="prev-lhs"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="$num < 10">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:when test="$num < 100">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<xsl:text></xsl:text>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
<xsl:value-of select="$num"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="$prev-lhs = lhs[text()]">
|
||||||
|
<xsl:call-template name="lpad">
|
||||||
|
<xsl:with-param name="str" select="'|'"/>
|
||||||
|
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 1"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<xsl:value-of select="lhs"/>
|
||||||
|
<xsl:text>:</xsl:text>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
<xsl:if test="$point = 0">
|
||||||
|
<xsl:text> .</xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:for-each select="rhs/symbol|rhs/empty">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
<xsl:if test="$point = position()">
|
||||||
|
<xsl:text> .</xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="symbol">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:value-of select="."/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="empty"/>
|
||||||
|
|
||||||
|
<xsl:template match="lookaheads">
|
||||||
|
<xsl:text> [</xsl:text>
|
||||||
|
<xsl:apply-templates select="symbol"/>
|
||||||
|
<xsl:text>]</xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="lookaheads/symbol">
|
||||||
|
<xsl:value-of select="."/>
|
||||||
|
<xsl:if test="position() != last()">
|
||||||
|
<xsl:text>, </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="reduction-edge-start">
|
||||||
|
<xsl:param name="state"/>
|
||||||
|
<xsl:param name="rule"/>
|
||||||
|
<xsl:param name="enabled"/>
|
||||||
|
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:value-of select="$state"/>
|
||||||
|
<xsl:text> -> "</xsl:text>
|
||||||
|
<xsl:value-of select="$state"/>
|
||||||
|
<xsl:text>R</xsl:text>
|
||||||
|
<xsl:value-of select="$rule"/>
|
||||||
|
<xsl:if test='$enabled = "false"'>
|
||||||
|
<xsl:text>d</xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:text>" [</xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="reduction-node">
|
||||||
|
<xsl:param name="state"/>
|
||||||
|
<xsl:param name="rule"/>
|
||||||
|
<xsl:param name="color"/>
|
||||||
|
|
||||||
|
<xsl:text> "</xsl:text>
|
||||||
|
<xsl:value-of select="$state"/>
|
||||||
|
<xsl:text>R</xsl:text>
|
||||||
|
<xsl:value-of select="$rule"/>
|
||||||
|
<xsl:if test="$color = 5">
|
||||||
|
<xsl:text>d</xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:text>" [label="</xsl:text>
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="$rule = 0">
|
||||||
|
<xsl:text>Acc", fillcolor=1</xsl:text>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<xsl:text>R</xsl:text>
|
||||||
|
<xsl:value-of select="$rule"/>
|
||||||
|
<xsl:text>", fillcolor=</xsl:text>
|
||||||
|
<xsl:value-of select="$color"/>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
<xsl:text>, shape=diamond, style=filled] </xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="transition">
|
||||||
|
<xsl:call-template name="output-edge">
|
||||||
|
<xsl:with-param name="src" select="../../../@number"/>
|
||||||
|
<xsl:with-param name="dst" select="@state"/>
|
||||||
|
<xsl:with-param name="style">
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="@symbol = 'error'">
|
||||||
|
<xsl:text>dotted</xsl:text>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:when test="@type = 'shift'">
|
||||||
|
<xsl:text>solid</xsl:text>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<xsl:text>dashed</xsl:text>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</xsl:with-param>
|
||||||
|
<xsl:with-param name="label">
|
||||||
|
<xsl:if test="not(@symbol = 'error')">
|
||||||
|
<xsl:value-of select="@symbol"/>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:with-param>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="output-node">
|
||||||
|
<xsl:param name="number"/>
|
||||||
|
<xsl:param name="label"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:value-of select="$number"/>
|
||||||
|
<xsl:text> [label="</xsl:text>
|
||||||
|
<xsl:text>State </xsl:text>
|
||||||
|
<xsl:value-of select="$number"/>
|
||||||
|
<xsl:text>\n</xsl:text>
|
||||||
|
<xsl:call-template name="escape">
|
||||||
|
<xsl:with-param name="subject" select="$label"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:text>\l"] </xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="output-edge">
|
||||||
|
<xsl:param name="src"/>
|
||||||
|
<xsl:param name="dst"/>
|
||||||
|
<xsl:param name="style"/>
|
||||||
|
<xsl:param name="label"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:value-of select="$src"/>
|
||||||
|
<xsl:text> -> </xsl:text>
|
||||||
|
<xsl:value-of select="$dst"/>
|
||||||
|
<xsl:text> [style=</xsl:text>
|
||||||
|
<xsl:value-of select="$style"/>
|
||||||
|
<xsl:if test="$label and $label != ''">
|
||||||
|
<xsl:text> label="</xsl:text>
|
||||||
|
<xsl:call-template name="escape">
|
||||||
|
<xsl:with-param name="subject" select="$label"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:text>"</xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:text>] </xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="escape">
|
||||||
|
<xsl:param name="subject"/> <!-- required -->
|
||||||
|
<xsl:call-template name="string-replace">
|
||||||
|
<xsl:with-param name="subject">
|
||||||
|
<xsl:call-template name="string-replace">
|
||||||
|
<xsl:with-param name="subject">
|
||||||
|
<xsl:call-template name="string-replace">
|
||||||
|
<xsl:with-param name="subject" select="$subject"/>
|
||||||
|
<xsl:with-param name="search" select="'\'"/>
|
||||||
|
<xsl:with-param name="replace" select="'\\'"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:with-param>
|
||||||
|
<xsl:with-param name="search" select="'"'"/>
|
||||||
|
<xsl:with-param name="replace" select="'\"'"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:with-param>
|
||||||
|
<xsl:with-param name="search" select="' '"/>
|
||||||
|
<xsl:with-param name="replace" select="'\l'"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="string-replace">
|
||||||
|
<xsl:param name="subject"/>
|
||||||
|
<xsl:param name="search"/>
|
||||||
|
<xsl:param name="replace"/>
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="contains($subject, $search)">
|
||||||
|
<xsl:variable name="before" select="substring-before($subject, $search)"/>
|
||||||
|
<xsl:variable name="after" select="substring-after($subject, $search)"/>
|
||||||
|
<xsl:value-of select="$before"/>
|
||||||
|
<xsl:value-of select="$replace"/>
|
||||||
|
<xsl:call-template name="string-replace">
|
||||||
|
<xsl:with-param name="subject" select="$after"/>
|
||||||
|
<xsl:with-param name="search" select="$search"/>
|
||||||
|
<xsl:with-param name="replace" select="$replace"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<xsl:value-of select="$subject"/>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="lpad">
|
||||||
|
<xsl:param name="str" select="''"/>
|
||||||
|
<xsl:param name="pad" select="0"/>
|
||||||
|
<xsl:variable name="diff" select="$pad - string-length($str)" />
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="$diff < 0">
|
||||||
|
<xsl:value-of select="$str"/>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<xsl:call-template name="space">
|
||||||
|
<xsl:with-param name="repeat" select="$diff"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:value-of select="$str"/>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
</xsl:stylesheet>
|
||||||
569
tools/data/xslt/xml2text.xsl
Normal file
569
tools/data/xslt/xml2text.xsl
Normal file
@@ -0,0 +1,569 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
xml2text.xsl - transform Bison XML Report into plain text.
|
||||||
|
|
||||||
|
Copyright (C) 2007-2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Bison, the GNU Compiler Compiler.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Written by Wojciech Polak <polak@gnu.org>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<xsl:stylesheet version="1.0"
|
||||||
|
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||||
|
xmlns:bison="http://www.gnu.org/software/bison/">
|
||||||
|
|
||||||
|
<xsl:import href="bison.xsl"/>
|
||||||
|
<xsl:output method="text" encoding="UTF-8" indent="no"/>
|
||||||
|
|
||||||
|
<xsl:template match="/">
|
||||||
|
<xsl:apply-templates select="bison-xml-report"/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="bison-xml-report">
|
||||||
|
<xsl:apply-templates select="grammar" mode="reductions"/>
|
||||||
|
<xsl:apply-templates select="grammar" mode="useless-in-parser"/>
|
||||||
|
<xsl:apply-templates select="automaton" mode="conflicts"/>
|
||||||
|
<xsl:apply-templates select="grammar"/>
|
||||||
|
<xsl:apply-templates select="automaton"/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="grammar" mode="reductions">
|
||||||
|
<xsl:apply-templates select="nonterminals" mode="useless-in-grammar"/>
|
||||||
|
<xsl:apply-templates select="terminals" mode="unused-in-grammar"/>
|
||||||
|
<xsl:apply-templates select="rules" mode="useless-in-grammar"/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="nonterminals" mode="useless-in-grammar">
|
||||||
|
<xsl:if test="nonterminal[@usefulness='useless-in-grammar']">
|
||||||
|
<xsl:text>Nonterminals useless in grammar </xsl:text>
|
||||||
|
<xsl:for-each select="nonterminal[@usefulness='useless-in-grammar']">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:value-of select="@name"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:for-each>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="terminals" mode="unused-in-grammar">
|
||||||
|
<xsl:if test="terminal[@usefulness='unused-in-grammar']">
|
||||||
|
<xsl:text>Terminals unused in grammar </xsl:text>
|
||||||
|
<xsl:for-each select="terminal[@usefulness='unused-in-grammar']">
|
||||||
|
<xsl:sort select="@symbol-number" data-type="number"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:value-of select="@name"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:for-each>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="rules" mode="useless-in-grammar">
|
||||||
|
<xsl:variable name="set" select="rule[@usefulness='useless-in-grammar']"/>
|
||||||
|
<xsl:if test="$set">
|
||||||
|
<xsl:text>Rules useless in grammar </xsl:text>
|
||||||
|
<xsl:call-template name="style-rule-set">
|
||||||
|
<xsl:with-param name="rule-set" select="$set"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="grammar" mode="useless-in-parser">
|
||||||
|
<xsl:variable
|
||||||
|
name="set" select="rules/rule[@usefulness='useless-in-parser']"
|
||||||
|
/>
|
||||||
|
<xsl:if test="$set">
|
||||||
|
<xsl:text>Rules useless in parser due to conflicts </xsl:text>
|
||||||
|
<xsl:call-template name="style-rule-set">
|
||||||
|
<xsl:with-param name="rule-set" select="$set"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="grammar">
|
||||||
|
<xsl:text>Grammar </xsl:text>
|
||||||
|
<xsl:call-template name="style-rule-set">
|
||||||
|
<xsl:with-param
|
||||||
|
name="rule-set" select="rules/rule[@usefulness!='useless-in-grammar']"
|
||||||
|
/>
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:apply-templates select="terminals"/>
|
||||||
|
<xsl:apply-templates select="nonterminals"/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="style-rule-set">
|
||||||
|
<xsl:param name="rule-set"/>
|
||||||
|
<xsl:for-each select="$rule-set">
|
||||||
|
<xsl:apply-templates select=".">
|
||||||
|
<xsl:with-param name="pad" select="'3'"/>
|
||||||
|
<xsl:with-param name="prev-lhs">
|
||||||
|
<xsl:if test="position()>1">
|
||||||
|
<xsl:variable name="position" select="position()"/>
|
||||||
|
<xsl:value-of select="$rule-set[$position - 1]/lhs"/>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:with-param>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="grammar/terminals">
|
||||||
|
<xsl:text>Terminals, with rules where they appear </xsl:text>
|
||||||
|
<xsl:apply-templates select="terminal"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="grammar/nonterminals">
|
||||||
|
<xsl:text>Nonterminals, with rules where they appear </xsl:text>
|
||||||
|
<xsl:apply-templates select="nonterminal[@usefulness!='useless-in-grammar']"/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="terminal">
|
||||||
|
<xsl:value-of select="@name"/>
|
||||||
|
<xsl:call-template name="line-wrap">
|
||||||
|
<xsl:with-param name="first-line-length">
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="string-length(@name) > 66">0</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<xsl:value-of select="66 - string-length(@name)" />
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</xsl:with-param>
|
||||||
|
<xsl:with-param name="line-length" select="66" />
|
||||||
|
<xsl:with-param name="text">
|
||||||
|
<xsl:value-of select="concat(' (', @token-number, ')')"/>
|
||||||
|
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
||||||
|
<xsl:value-of select="concat(' ', @number)"/>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:with-param>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="nonterminal">
|
||||||
|
<xsl:value-of select="@name"/>
|
||||||
|
<xsl:value-of select="concat(' (', @symbol-number, ')')"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:variable name="output">
|
||||||
|
<xsl:call-template name="line-wrap">
|
||||||
|
<xsl:with-param name="line-length" select="66" />
|
||||||
|
<xsl:with-param name="text">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:if test="key('bison:ruleByLhs', @name)">
|
||||||
|
<xsl:text>on@left:</xsl:text>
|
||||||
|
<xsl:for-each select="key('bison:ruleByLhs', @name)">
|
||||||
|
<xsl:value-of select="concat(' ', @number)"/>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:if test="key('bison:ruleByRhs', @name)">
|
||||||
|
<xsl:if test="key('bison:ruleByLhs', @name)">
|
||||||
|
<xsl:text>, </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:text>on@right:</xsl:text>
|
||||||
|
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
||||||
|
<xsl:value-of select="concat(' ', @number)"/>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:with-param>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:variable>
|
||||||
|
<xsl:value-of select="translate($output, '@', ' ')" />
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="automaton" mode="conflicts">
|
||||||
|
<xsl:variable name="conflict-report">
|
||||||
|
<xsl:apply-templates select="state" mode="conflicts"/>
|
||||||
|
</xsl:variable>
|
||||||
|
<xsl:if test="string-length($conflict-report) != 0">
|
||||||
|
<xsl:value-of select="$conflict-report"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="state" mode="conflicts">
|
||||||
|
<xsl:variable name="conflict-counts">
|
||||||
|
<xsl:apply-templates select="." mode="bison:count-conflicts" />
|
||||||
|
</xsl:variable>
|
||||||
|
<xsl:variable
|
||||||
|
name="sr-count" select="substring-before($conflict-counts, ',')"
|
||||||
|
/>
|
||||||
|
<xsl:variable
|
||||||
|
name="rr-count" select="substring-after($conflict-counts, ',')"
|
||||||
|
/>
|
||||||
|
<xsl:if test="$sr-count > 0 or $rr-count > 0">
|
||||||
|
<xsl:value-of select="concat('State ', @number, ' conflicts:')"/>
|
||||||
|
<xsl:if test="$sr-count > 0">
|
||||||
|
<xsl:value-of select="concat(' ', $sr-count, ' shift/reduce')"/>
|
||||||
|
<xsl:if test="$rr-count > 0">
|
||||||
|
<xsl:value-of select="(',')"/>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:if test="$rr-count > 0">
|
||||||
|
<xsl:value-of select="concat(' ', $rr-count, ' reduce/reduce')"/>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:value-of select="' '"/>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="automaton">
|
||||||
|
<xsl:apply-templates select="state">
|
||||||
|
<xsl:with-param name="pad" select="'3'"/>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="automaton/state">
|
||||||
|
<xsl:param name="pad"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:text>State </xsl:text>
|
||||||
|
<xsl:value-of select="@number"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:apply-templates select="itemset/item">
|
||||||
|
<xsl:with-param name="pad" select="$pad"/>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
<xsl:apply-templates select="actions/transitions">
|
||||||
|
<xsl:with-param name="type" select="'shift'"/>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
<xsl:apply-templates select="actions/errors"/>
|
||||||
|
<xsl:apply-templates select="actions/reductions"/>
|
||||||
|
<xsl:apply-templates select="actions/transitions">
|
||||||
|
<xsl:with-param name="type" select="'goto'"/>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
<xsl:apply-templates select="solved-conflicts"/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="actions/transitions">
|
||||||
|
<xsl:param name="type"/>
|
||||||
|
<xsl:if test="transition[@type = $type]">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:apply-templates select="transition[@type = $type]">
|
||||||
|
<xsl:with-param name="pad">
|
||||||
|
<xsl:call-template name="max-width-symbol">
|
||||||
|
<xsl:with-param name="node" select="transition[@type = $type]"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:with-param>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="actions/errors">
|
||||||
|
<xsl:if test="error">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:apply-templates select="error">
|
||||||
|
<xsl:with-param name="pad">
|
||||||
|
<xsl:call-template name="max-width-symbol">
|
||||||
|
<xsl:with-param name="node" select="error"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:with-param>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="actions/reductions">
|
||||||
|
<xsl:if test="reduction">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:apply-templates select="reduction">
|
||||||
|
<xsl:with-param name="pad">
|
||||||
|
<xsl:call-template name="max-width-symbol">
|
||||||
|
<xsl:with-param name="node" select="reduction"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:with-param>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="item">
|
||||||
|
<xsl:param name="pad"/>
|
||||||
|
<xsl:param name="prev-rule-number"
|
||||||
|
select="preceding-sibling::item[1]/@rule-number"/>
|
||||||
|
<xsl:apply-templates
|
||||||
|
select="key('bison:ruleByNumber', current()/@rule-number)"
|
||||||
|
>
|
||||||
|
<xsl:with-param name="itemset" select="'true'"/>
|
||||||
|
<xsl:with-param name="pad" select="$pad"/>
|
||||||
|
<xsl:with-param
|
||||||
|
name="prev-lhs"
|
||||||
|
select="key('bison:ruleByNumber', $prev-rule-number)/lhs[text()]"
|
||||||
|
/>
|
||||||
|
<xsl:with-param name="point" select="@point"/>
|
||||||
|
<xsl:with-param name="lookaheads">
|
||||||
|
<xsl:apply-templates select="lookaheads"/>
|
||||||
|
</xsl:with-param>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="rule">
|
||||||
|
<xsl:param name="itemset"/>
|
||||||
|
<xsl:param name="pad"/>
|
||||||
|
<xsl:param name="prev-lhs"/>
|
||||||
|
<xsl:param name="point"/>
|
||||||
|
<xsl:param name="lookaheads"/>
|
||||||
|
|
||||||
|
<xsl:if test="$itemset != 'true' and not($prev-lhs = lhs[text()])">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:call-template name="lpad">
|
||||||
|
<xsl:with-param name="str" select="string(@number)"/>
|
||||||
|
<xsl:with-param name="pad" select="number($pad)"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
|
||||||
|
<!-- LHS -->
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="$itemset != 'true' and $prev-lhs = lhs[text()]">
|
||||||
|
<xsl:call-template name="lpad">
|
||||||
|
<xsl:with-param name="str" select="'|'"/>
|
||||||
|
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 1"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:when test="$itemset = 'true' and $prev-lhs = lhs[text()]">
|
||||||
|
<xsl:call-template name="lpad">
|
||||||
|
<xsl:with-param name="str" select="'|'"/>
|
||||||
|
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 1"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<xsl:value-of select="lhs"/>
|
||||||
|
<xsl:text>:</xsl:text>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
|
||||||
|
<!-- RHS -->
|
||||||
|
<xsl:for-each select="rhs/*">
|
||||||
|
<xsl:if test="position() = $point + 1">
|
||||||
|
<xsl:text> .</xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:if test="$itemset = 'true' and name(.) != 'empty'">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:if test="$itemset != 'true'">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:if test="position() = last() and position() = $point">
|
||||||
|
<xsl:text> .</xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:for-each>
|
||||||
|
<xsl:if test="$lookaheads">
|
||||||
|
<xsl:value-of select="$lookaheads"/>
|
||||||
|
</xsl:if>
|
||||||
|
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="symbol">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:value-of select="."/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="empty">
|
||||||
|
<xsl:text> /* empty */</xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="lookaheads">
|
||||||
|
<xsl:text> [</xsl:text>
|
||||||
|
<xsl:apply-templates select="symbol"/>
|
||||||
|
<xsl:text>]</xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="lookaheads/symbol">
|
||||||
|
<xsl:value-of select="."/>
|
||||||
|
<xsl:if test="position() != last()">
|
||||||
|
<xsl:text>, </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="transition">
|
||||||
|
<xsl:param name="pad"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:call-template name="rpad">
|
||||||
|
<xsl:with-param name="str" select="string(@symbol)"/>
|
||||||
|
<xsl:with-param name="pad" select="number($pad) + 2"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="@type = 'shift'">
|
||||||
|
<xsl:text>shift, and go to state </xsl:text>
|
||||||
|
<xsl:value-of select="@state"/>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:when test="@type = 'goto'">
|
||||||
|
<xsl:text>go to state </xsl:text>
|
||||||
|
<xsl:value-of select="@state"/>
|
||||||
|
</xsl:when>
|
||||||
|
</xsl:choose>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="error">
|
||||||
|
<xsl:param name="pad"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:call-template name="rpad">
|
||||||
|
<xsl:with-param name="str" select="string(@symbol)"/>
|
||||||
|
<xsl:with-param name="pad" select="number($pad) + 2"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:text>error</xsl:text>
|
||||||
|
<xsl:text> (</xsl:text>
|
||||||
|
<xsl:value-of select="text()"/>
|
||||||
|
<xsl:text>)</xsl:text>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="reduction">
|
||||||
|
<xsl:param name="pad"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:call-template name="rpad">
|
||||||
|
<xsl:with-param name="str" select="string(@symbol)"/>
|
||||||
|
<xsl:with-param name="pad" select="number($pad) + 2"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:if test="@enabled = 'false'">
|
||||||
|
<xsl:text>[</xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="@rule = 'accept'">
|
||||||
|
<xsl:text>accept</xsl:text>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<xsl:text>reduce using rule </xsl:text>
|
||||||
|
<xsl:value-of select="@rule"/>
|
||||||
|
<xsl:text> (</xsl:text>
|
||||||
|
<xsl:value-of
|
||||||
|
select="key('bison:ruleByNumber', current()/@rule)/lhs[text()]"/>
|
||||||
|
<xsl:text>)</xsl:text>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
<xsl:if test="@enabled = 'false'">
|
||||||
|
<xsl:text>]</xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="solved-conflicts">
|
||||||
|
<xsl:if test="resolution">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:apply-templates select="resolution"/>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="resolution">
|
||||||
|
<xsl:text> Conflict between rule </xsl:text>
|
||||||
|
<xsl:value-of select="@rule"/>
|
||||||
|
<xsl:text> and token </xsl:text>
|
||||||
|
<xsl:value-of select="@symbol"/>
|
||||||
|
<xsl:text> resolved as </xsl:text>
|
||||||
|
<xsl:if test="@type = 'error'">
|
||||||
|
<xsl:text>an </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:value-of select="@type"/>
|
||||||
|
<xsl:text> (</xsl:text>
|
||||||
|
<xsl:value-of select="."/>
|
||||||
|
<xsl:text>). </xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="max-width-symbol">
|
||||||
|
<xsl:param name="node"/>
|
||||||
|
<xsl:variable name="longest">
|
||||||
|
<xsl:for-each select="$node">
|
||||||
|
<xsl:sort data-type="number" select="string-length(@symbol)"
|
||||||
|
order="descending"/>
|
||||||
|
<xsl:if test="position() = 1">
|
||||||
|
<xsl:value-of select="string-length(@symbol)"/>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:variable>
|
||||||
|
<xsl:value-of select="$longest"/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="lpad">
|
||||||
|
<xsl:param name="str" select="''"/>
|
||||||
|
<xsl:param name="pad" select="0"/>
|
||||||
|
<xsl:variable name="diff" select="$pad - string-length($str)" />
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="$diff < 0">
|
||||||
|
<xsl:value-of select="$str"/>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<xsl:call-template name="space">
|
||||||
|
<xsl:with-param name="repeat" select="$diff"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:value-of select="$str"/>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="rpad">
|
||||||
|
<xsl:param name="str" select="''"/>
|
||||||
|
<xsl:param name="pad" select="0"/>
|
||||||
|
<xsl:variable name="diff" select="$pad - string-length($str)"/>
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="$diff < 0">
|
||||||
|
<xsl:value-of select="$str"/>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<xsl:value-of select="$str"/>
|
||||||
|
<xsl:call-template name="space">
|
||||||
|
<xsl:with-param name="repeat" select="$diff"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="line-wrap">
|
||||||
|
<xsl:param name="line-length"/> <!-- required -->
|
||||||
|
<xsl:param name="first-line-length" select="$line-length"/>
|
||||||
|
<xsl:param name="text"/> <!-- required -->
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="normalize-space($text) = ''" />
|
||||||
|
<xsl:when test="string-length($text) <= $first-line-length">
|
||||||
|
<xsl:value-of select="concat($text, ' ')" />
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<xsl:variable name="break-pos">
|
||||||
|
<xsl:call-template name="ws-search">
|
||||||
|
<xsl:with-param name="text" select="$text" />
|
||||||
|
<xsl:with-param name="start" select="$first-line-length+1" />
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:variable>
|
||||||
|
<xsl:value-of select="substring($text, 1, $break-pos - 1)" />
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:call-template name="line-wrap">
|
||||||
|
<xsl:with-param name="line-length" select="$line-length" />
|
||||||
|
<xsl:with-param
|
||||||
|
name="text" select="concat(' ', substring($text, $break-pos+1))"
|
||||||
|
/>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="ws-search">
|
||||||
|
<xsl:param name="text"/> <!-- required -->
|
||||||
|
<xsl:param name="start"/> <!-- required -->
|
||||||
|
<xsl:variable name="search-text" select="substring($text, $start)" />
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="not(contains($search-text, ' '))">
|
||||||
|
<xsl:value-of select="string-length($text)+1" />
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<xsl:value-of
|
||||||
|
select="$start + string-length(substring-before($search-text, ' '))"
|
||||||
|
/>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
</xsl:stylesheet>
|
||||||
745
tools/data/xslt/xml2xhtml.xsl
Normal file
745
tools/data/xslt/xml2xhtml.xsl
Normal file
@@ -0,0 +1,745 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
xml2html.xsl - transform Bison XML Report into XHTML.
|
||||||
|
|
||||||
|
Copyright (C) 2007-2012 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of Bison, the GNU Compiler Compiler.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Written by Wojciech Polak <polak@gnu.org>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<xsl:stylesheet version="1.0"
|
||||||
|
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||||
|
xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:bison="http://www.gnu.org/software/bison/">
|
||||||
|
|
||||||
|
<xsl:import href="bison.xsl"/>
|
||||||
|
|
||||||
|
<xsl:output method="xml" encoding="UTF-8"
|
||||||
|
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||||
|
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
|
||||||
|
indent="yes"/>
|
||||||
|
|
||||||
|
<xsl:template match="/">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>
|
||||||
|
<xsl:value-of select="bison-xml-report/filename"/>
|
||||||
|
<xsl:text> - GNU Bison XML Automaton Report</xsl:text>
|
||||||
|
</title>
|
||||||
|
<style type="text/css"><![CDATA[
|
||||||
|
body {
|
||||||
|
font-family: "Nimbus Sans L", Arial, sans-serif;
|
||||||
|
font-size: 9pt;
|
||||||
|
}
|
||||||
|
a:link {
|
||||||
|
color: #1f00ff;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
a:visited {
|
||||||
|
color: #1f00ff;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
#menu a {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.i {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
.pre {
|
||||||
|
font-family: monospace;
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
ol.decimal {
|
||||||
|
list-style-type: decimal;
|
||||||
|
}
|
||||||
|
ol.lower-alpha {
|
||||||
|
list-style-type: lower-alpha;
|
||||||
|
}
|
||||||
|
.point {
|
||||||
|
color: #cc0000;
|
||||||
|
}
|
||||||
|
#footer {
|
||||||
|
margin-top: 3.5em;
|
||||||
|
font-size: 7pt;
|
||||||
|
}
|
||||||
|
]]></style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<xsl:apply-templates select="bison-xml-report"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<div id="footer"><hr />This document was generated using
|
||||||
|
<a href="http://www.gnu.org/software/bison/" title="GNU Bison">
|
||||||
|
GNU Bison <xsl:value-of select="/bison-xml-report/@version"/></a>
|
||||||
|
XML Automaton Report.<br />
|
||||||
|
<!-- default copying notice -->
|
||||||
|
Verbatim copying and distribution of this entire page is
|
||||||
|
permitted in any medium, provided this notice is preserved.</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="bison-xml-report">
|
||||||
|
<h1>GNU Bison XML Automaton Report</h1>
|
||||||
|
<p>
|
||||||
|
input grammar: <span class="i"><xsl:value-of select="filename"/></span>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<h3>Table of Contents</h3>
|
||||||
|
<ul id="menu">
|
||||||
|
<li>
|
||||||
|
<a href="#reductions">Reductions</a>
|
||||||
|
<ul class="lower-alpha">
|
||||||
|
<li><a href="#nonterminals_useless_in_grammar">Nonterminals useless in grammar</a></li>
|
||||||
|
<li><a href="#terminals_unused_in_grammar">Terminals unused in grammar</a></li>
|
||||||
|
<li><a href="#rules_useless_in_grammar">Rules useless in grammar</a></li>
|
||||||
|
<xsl:if test="grammar/rules/rule[@usefulness='useless-in-parser']">
|
||||||
|
<li><a href="#rules_useless_in_parser">Rules useless in parser due to conflicts</a></li>
|
||||||
|
</xsl:if>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><a href="#conflicts">Conflicts</a></li>
|
||||||
|
<li>
|
||||||
|
<a href="#grammar">Grammar</a>
|
||||||
|
<ul class="lower-alpha">
|
||||||
|
<li><a href="#grammar">Itemset</a></li>
|
||||||
|
<li><a href="#terminals">Terminal symbols</a></li>
|
||||||
|
<li><a href="#nonterminals">Nonterminal symbols</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><a href="#automaton">Automaton</a></li>
|
||||||
|
</ul>
|
||||||
|
<xsl:apply-templates select="grammar" mode="reductions"/>
|
||||||
|
<xsl:apply-templates select="grammar" mode="useless-in-parser"/>
|
||||||
|
<xsl:apply-templates select="automaton" mode="conflicts"/>
|
||||||
|
<xsl:apply-templates select="grammar"/>
|
||||||
|
<xsl:apply-templates select="automaton"/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="grammar" mode="reductions">
|
||||||
|
<h2>
|
||||||
|
<a name="reductions"/>
|
||||||
|
<xsl:text> Reductions</xsl:text>
|
||||||
|
</h2>
|
||||||
|
<xsl:apply-templates select="nonterminals" mode="useless-in-grammar"/>
|
||||||
|
<xsl:apply-templates select="terminals" mode="unused-in-grammar"/>
|
||||||
|
<xsl:apply-templates select="rules" mode="useless-in-grammar"/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="nonterminals" mode="useless-in-grammar">
|
||||||
|
<h3>
|
||||||
|
<a name="nonterminals_useless_in_grammar"/>
|
||||||
|
<xsl:text> Nonterminals useless in grammar</xsl:text>
|
||||||
|
</h3>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:if test="nonterminal[@usefulness='useless-in-grammar']">
|
||||||
|
<p class="pre">
|
||||||
|
<xsl:for-each select="nonterminal[@usefulness='useless-in-grammar']">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:value-of select="@name"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:for-each>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</p>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="terminals" mode="unused-in-grammar">
|
||||||
|
<h3>
|
||||||
|
<a name="terminals_unused_in_grammar"/>
|
||||||
|
<xsl:text> Terminals unused in grammar</xsl:text>
|
||||||
|
</h3>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:if test="terminal[@usefulness='unused-in-grammar']">
|
||||||
|
<p class="pre">
|
||||||
|
<xsl:for-each select="terminal[@usefulness='unused-in-grammar']">
|
||||||
|
<xsl:sort select="@symbol-number" data-type="number"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:value-of select="@name"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:for-each>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</p>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="rules" mode="useless-in-grammar">
|
||||||
|
<h3>
|
||||||
|
<a name="rules_useless_in_grammar"/>
|
||||||
|
<xsl:text> Rules useless in grammar</xsl:text>
|
||||||
|
</h3>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:variable name="set" select="rule[@usefulness='useless-in-grammar']"/>
|
||||||
|
<xsl:if test="$set">
|
||||||
|
<p class="pre">
|
||||||
|
<xsl:call-template name="style-rule-set">
|
||||||
|
<xsl:with-param name="rule-set" select="$set"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</p>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="grammar" mode="useless-in-parser">
|
||||||
|
<xsl:variable
|
||||||
|
name="set" select="rules/rule[@usefulness='useless-in-parser']"
|
||||||
|
/>
|
||||||
|
<xsl:if test="$set">
|
||||||
|
<h2>
|
||||||
|
<a name="rules_useless_in_parser"/>
|
||||||
|
<xsl:text> Rules useless in parser due to conflicts</xsl:text>
|
||||||
|
</h2>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<p class="pre">
|
||||||
|
<xsl:call-template name="style-rule-set">
|
||||||
|
<xsl:with-param name="rule-set" select="$set"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
</p>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="grammar">
|
||||||
|
<h2>
|
||||||
|
<a name="grammar"/>
|
||||||
|
<xsl:text> Grammar</xsl:text>
|
||||||
|
</h2>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<p class="pre">
|
||||||
|
<xsl:call-template name="style-rule-set">
|
||||||
|
<xsl:with-param
|
||||||
|
name="rule-set" select="rules/rule[@usefulness!='useless-in-grammar']"
|
||||||
|
/>
|
||||||
|
</xsl:call-template>
|
||||||
|
</p>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:apply-templates select="terminals"/>
|
||||||
|
<xsl:apply-templates select="nonterminals"/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="style-rule-set">
|
||||||
|
<xsl:param name="rule-set"/>
|
||||||
|
<xsl:for-each select="$rule-set">
|
||||||
|
<xsl:apply-templates select=".">
|
||||||
|
<xsl:with-param name="pad" select="'3'"/>
|
||||||
|
<xsl:with-param name="prev-lhs">
|
||||||
|
<xsl:if test="position()>1">
|
||||||
|
<xsl:variable name="position" select="position()"/>
|
||||||
|
<xsl:value-of select="$rule-set[$position - 1]/lhs"/>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:with-param>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="automaton" mode="conflicts">
|
||||||
|
<h2>
|
||||||
|
<a name="conflicts"/>
|
||||||
|
<xsl:text> Conflicts</xsl:text>
|
||||||
|
</h2>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:variable name="conflict-report">
|
||||||
|
<xsl:apply-templates select="state" mode="conflicts"/>
|
||||||
|
</xsl:variable>
|
||||||
|
<xsl:if test="string-length($conflict-report) != 0">
|
||||||
|
<p class="pre">
|
||||||
|
<xsl:copy-of select="$conflict-report"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</p>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="state" mode="conflicts">
|
||||||
|
<xsl:variable name="conflict-counts">
|
||||||
|
<xsl:apply-templates select="." mode="bison:count-conflicts" />
|
||||||
|
</xsl:variable>
|
||||||
|
<xsl:variable
|
||||||
|
name="sr-count" select="substring-before($conflict-counts, ',')"
|
||||||
|
/>
|
||||||
|
<xsl:variable
|
||||||
|
name="rr-count" select="substring-after($conflict-counts, ',')"
|
||||||
|
/>
|
||||||
|
<xsl:if test="$sr-count > 0 or $rr-count > 0">
|
||||||
|
<a>
|
||||||
|
<xsl:attribute name="href">
|
||||||
|
<xsl:value-of select="concat('#state_', @number)"/>
|
||||||
|
</xsl:attribute>
|
||||||
|
<xsl:value-of select="concat('State ', @number)"/>
|
||||||
|
</a>
|
||||||
|
<xsl:text> conflicts:</xsl:text>
|
||||||
|
<xsl:if test="$sr-count > 0">
|
||||||
|
<xsl:value-of select="concat(' ', $sr-count, ' shift/reduce')"/>
|
||||||
|
<xsl:if test="$rr-count > 0">
|
||||||
|
<xsl:value-of select="(',')"/>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:if test="$rr-count > 0">
|
||||||
|
<xsl:value-of select="concat(' ', $rr-count, ' reduce/reduce')"/>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:value-of select="' '"/>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="grammar/terminals">
|
||||||
|
<h3>
|
||||||
|
<a name="terminals"/>
|
||||||
|
<xsl:text> Terminals, with rules where they appear</xsl:text>
|
||||||
|
</h3>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<p class="pre">
|
||||||
|
<xsl:apply-templates select="terminal"/>
|
||||||
|
</p>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="grammar/nonterminals">
|
||||||
|
<h3>
|
||||||
|
<a name="nonterminals"/>
|
||||||
|
<xsl:text> Nonterminals, with rules where they appear</xsl:text>
|
||||||
|
</h3>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<p class="pre">
|
||||||
|
<xsl:apply-templates
|
||||||
|
select="nonterminal[@usefulness!='useless-in-grammar']"
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="terminal">
|
||||||
|
<b><xsl:value-of select="@name"/></b>
|
||||||
|
<xsl:value-of select="concat(' (', @token-number, ')')"/>
|
||||||
|
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
||||||
|
<xsl:apply-templates select="." mode="number-link"/>
|
||||||
|
</xsl:for-each>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="nonterminal">
|
||||||
|
<b><xsl:value-of select="@name"/></b>
|
||||||
|
<xsl:value-of select="concat(' (', @symbol-number, ')')"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:if test="key('bison:ruleByLhs', @name)">
|
||||||
|
<xsl:text>on left:</xsl:text>
|
||||||
|
<xsl:for-each select="key('bison:ruleByLhs', @name)">
|
||||||
|
<xsl:apply-templates select="." mode="number-link"/>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:if test="key('bison:ruleByRhs', @name)">
|
||||||
|
<xsl:if test="key('bison:ruleByLhs', @name)">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:text>on right:</xsl:text>
|
||||||
|
<xsl:for-each select="key('bison:ruleByRhs', @name)">
|
||||||
|
<xsl:apply-templates select="." mode="number-link"/>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="rule" mode="number-link">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<a>
|
||||||
|
<xsl:attribute name="href">
|
||||||
|
<xsl:value-of select="concat('#rule_', @number)"/>
|
||||||
|
</xsl:attribute>
|
||||||
|
<xsl:value-of select="@number"/>
|
||||||
|
</a>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="automaton">
|
||||||
|
<h2>
|
||||||
|
<a name="automaton"/>
|
||||||
|
<xsl:text> Automaton</xsl:text>
|
||||||
|
</h2>
|
||||||
|
<xsl:apply-templates select="state">
|
||||||
|
<xsl:with-param name="pad" select="'3'"/>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="automaton/state">
|
||||||
|
<xsl:param name="pad"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<h3>
|
||||||
|
<a>
|
||||||
|
<xsl:attribute name="name">
|
||||||
|
<xsl:value-of select="concat('state_', @number)"/>
|
||||||
|
</xsl:attribute>
|
||||||
|
</a>
|
||||||
|
<xsl:text>state </xsl:text>
|
||||||
|
<xsl:value-of select="@number"/>
|
||||||
|
</h3>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<p class="pre">
|
||||||
|
<xsl:apply-templates select="itemset/item">
|
||||||
|
<xsl:with-param name="pad" select="$pad"/>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
<xsl:apply-templates select="actions/transitions">
|
||||||
|
<xsl:with-param name="type" select="'shift'"/>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
<xsl:apply-templates select="actions/errors"/>
|
||||||
|
<xsl:apply-templates select="actions/reductions"/>
|
||||||
|
<xsl:apply-templates select="actions/transitions">
|
||||||
|
<xsl:with-param name="type" select="'goto'"/>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
<xsl:apply-templates select="solved-conflicts"/>
|
||||||
|
</p>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="actions/transitions">
|
||||||
|
<xsl:param name="type"/>
|
||||||
|
<xsl:if test="transition[@type = $type]">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:apply-templates select="transition[@type = $type]">
|
||||||
|
<xsl:with-param name="pad">
|
||||||
|
<xsl:call-template name="max-width-symbol">
|
||||||
|
<xsl:with-param name="node" select="transition[@type = $type]"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:with-param>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="actions/errors">
|
||||||
|
<xsl:if test="error">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:apply-templates select="error">
|
||||||
|
<xsl:with-param name="pad">
|
||||||
|
<xsl:call-template name="max-width-symbol">
|
||||||
|
<xsl:with-param name="node" select="error"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:with-param>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="actions/reductions">
|
||||||
|
<xsl:if test="reduction">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:apply-templates select="reduction">
|
||||||
|
<xsl:with-param name="pad">
|
||||||
|
<xsl:call-template name="max-width-symbol">
|
||||||
|
<xsl:with-param name="node" select="reduction"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:with-param>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="item">
|
||||||
|
<xsl:param name="pad"/>
|
||||||
|
<xsl:param name="prev-rule-number"
|
||||||
|
select="preceding-sibling::item[1]/@rule-number"/>
|
||||||
|
<xsl:apply-templates
|
||||||
|
select="key('bison:ruleByNumber', current()/@rule-number)"
|
||||||
|
>
|
||||||
|
<xsl:with-param name="itemset" select="'true'"/>
|
||||||
|
<xsl:with-param name="pad" select="$pad"/>
|
||||||
|
<xsl:with-param name="prev-lhs"
|
||||||
|
select="key('bison:ruleByNumber', $prev-rule-number)/lhs[text()]"
|
||||||
|
/>
|
||||||
|
<xsl:with-param name="point" select="@point"/>
|
||||||
|
<xsl:with-param name="lookaheads">
|
||||||
|
<xsl:apply-templates select="lookaheads"/>
|
||||||
|
</xsl:with-param>
|
||||||
|
</xsl:apply-templates>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="rule">
|
||||||
|
<xsl:param name="itemset"/>
|
||||||
|
<xsl:param name="pad"/>
|
||||||
|
<xsl:param name="prev-lhs"/>
|
||||||
|
<xsl:param name="point"/>
|
||||||
|
<xsl:param name="lookaheads"/>
|
||||||
|
|
||||||
|
<xsl:if test="$itemset != 'true' and not($prev-lhs = lhs[text()])">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
|
||||||
|
<xsl:if test="$itemset != 'true'">
|
||||||
|
<a>
|
||||||
|
<xsl:attribute name="name">
|
||||||
|
<xsl:value-of select="concat('rule_', @number)"/>
|
||||||
|
</xsl:attribute>
|
||||||
|
</a>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="$itemset = 'true'">
|
||||||
|
<a>
|
||||||
|
<xsl:attribute name="href">
|
||||||
|
<xsl:value-of select="concat('#rule_', @number)"/>
|
||||||
|
</xsl:attribute>
|
||||||
|
<xsl:call-template name="lpad">
|
||||||
|
<xsl:with-param name="str" select="string(@number)"/>
|
||||||
|
<xsl:with-param name="pad" select="number($pad)"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
</a>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<xsl:call-template name="lpad">
|
||||||
|
<xsl:with-param name="str" select="string(@number)"/>
|
||||||
|
<xsl:with-param name="pad" select="number($pad)"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
|
||||||
|
<!-- LHS -->
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="$itemset != 'true' and $prev-lhs = lhs[text()]">
|
||||||
|
<xsl:call-template name="lpad">
|
||||||
|
<xsl:with-param name="str" select="'|'"/>
|
||||||
|
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 2"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:when test="$itemset = 'true' and $prev-lhs = lhs[text()]">
|
||||||
|
<xsl:call-template name="lpad">
|
||||||
|
<xsl:with-param name="str" select="'|'"/>
|
||||||
|
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 2"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<span class="i">
|
||||||
|
<xsl:value-of select="lhs"/>
|
||||||
|
</span>
|
||||||
|
<xsl:text> →</xsl:text>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
|
||||||
|
<!-- RHS -->
|
||||||
|
<xsl:for-each select="rhs/*">
|
||||||
|
<xsl:if test="position() = $point + 1">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<span class="point">.</span>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:if test="$itemset = 'true' and name(.) != 'empty'">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:if test="$itemset != 'true'">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:if test="position() = last() and position() = $point">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<span class="point">.</span>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:for-each>
|
||||||
|
<xsl:if test="$lookaheads">
|
||||||
|
<xsl:value-of select="$lookaheads"/>
|
||||||
|
</xsl:if>
|
||||||
|
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="symbol">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="name(key('bison:symbolByName', .)) = 'nonterminal'">
|
||||||
|
<span class="i"><xsl:value-of select="."/></span>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<b><xsl:value-of select="."/></b>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="empty">
|
||||||
|
<xsl:text> ε</xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="lookaheads">
|
||||||
|
<xsl:text> [</xsl:text>
|
||||||
|
<xsl:apply-templates select="symbol"/>
|
||||||
|
<xsl:text>]</xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="lookaheads/symbol">
|
||||||
|
<xsl:value-of select="."/>
|
||||||
|
<xsl:if test="position() != last()">
|
||||||
|
<xsl:text>, </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="transition">
|
||||||
|
<xsl:param name="pad"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:call-template name="rpad">
|
||||||
|
<xsl:with-param name="str" select="string(@symbol)"/>
|
||||||
|
<xsl:with-param name="pad" select="number($pad) + 2"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="@type = 'shift'">
|
||||||
|
<a>
|
||||||
|
<xsl:attribute name="href">
|
||||||
|
<xsl:value-of select="concat('#state_', @state)"/>
|
||||||
|
</xsl:attribute>
|
||||||
|
<xsl:value-of select="concat('shift, and go to state ', @state)"/>
|
||||||
|
</a>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:when test="@type = 'goto'">
|
||||||
|
<a>
|
||||||
|
<xsl:attribute name="href">
|
||||||
|
<xsl:value-of select="concat('#state_', @state)"/>
|
||||||
|
</xsl:attribute>
|
||||||
|
<xsl:value-of select="concat('go to state ', @state)"/>
|
||||||
|
</a>
|
||||||
|
</xsl:when>
|
||||||
|
</xsl:choose>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="error">
|
||||||
|
<xsl:param name="pad"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:call-template name="rpad">
|
||||||
|
<xsl:with-param name="str" select="string(@symbol)"/>
|
||||||
|
<xsl:with-param name="pad" select="number($pad) + 2"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:text>error</xsl:text>
|
||||||
|
<xsl:text> (</xsl:text>
|
||||||
|
<xsl:value-of select="text()"/>
|
||||||
|
<xsl:text>)</xsl:text>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="reduction">
|
||||||
|
<xsl:param name="pad"/>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:call-template name="rpad">
|
||||||
|
<xsl:with-param name="str" select="string(@symbol)"/>
|
||||||
|
<xsl:with-param name="pad" select="number($pad) + 2"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:if test="@enabled = 'false'">
|
||||||
|
<xsl:text>[</xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="@rule = 'accept'">
|
||||||
|
<xsl:text>accept</xsl:text>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<a>
|
||||||
|
<xsl:attribute name="href">
|
||||||
|
<xsl:value-of select="concat('#rule_', @rule)"/>
|
||||||
|
</xsl:attribute>
|
||||||
|
<xsl:value-of select="concat('reduce using rule ', @rule)"/>
|
||||||
|
</a>
|
||||||
|
<xsl:text> (</xsl:text>
|
||||||
|
<xsl:value-of
|
||||||
|
select="key('bison:ruleByNumber', current()/@rule)/lhs[text()]"
|
||||||
|
/>
|
||||||
|
<xsl:text>)</xsl:text>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
<xsl:if test="@enabled = 'false'">
|
||||||
|
<xsl:text>]</xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="solved-conflicts">
|
||||||
|
<xsl:if test="resolution">
|
||||||
|
<xsl:text> </xsl:text>
|
||||||
|
<xsl:apply-templates select="resolution"/>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="resolution">
|
||||||
|
<xsl:text> Conflict between </xsl:text>
|
||||||
|
<a>
|
||||||
|
<xsl:attribute name="href">
|
||||||
|
<xsl:value-of select="concat('#rule_', @rule)"/>
|
||||||
|
</xsl:attribute>
|
||||||
|
<xsl:value-of select="concat('rule ',@rule)"/>
|
||||||
|
</a>
|
||||||
|
<xsl:text> and token </xsl:text>
|
||||||
|
<xsl:value-of select="@symbol"/>
|
||||||
|
<xsl:text> resolved as </xsl:text>
|
||||||
|
<xsl:if test="@type = 'error'">
|
||||||
|
<xsl:text>an </xsl:text>
|
||||||
|
</xsl:if>
|
||||||
|
<xsl:value-of select="@type"/>
|
||||||
|
<xsl:text> (</xsl:text>
|
||||||
|
<xsl:value-of select="."/>
|
||||||
|
<xsl:text>). </xsl:text>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="max-width-symbol">
|
||||||
|
<xsl:param name="node"/>
|
||||||
|
<xsl:variable name="longest">
|
||||||
|
<xsl:for-each select="$node">
|
||||||
|
<xsl:sort data-type="number" select="string-length(@symbol)"
|
||||||
|
order="descending"/>
|
||||||
|
<xsl:if test="position() = 1">
|
||||||
|
<xsl:value-of select="string-length(@symbol)"/>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:variable>
|
||||||
|
<xsl:value-of select="$longest"/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="lpad">
|
||||||
|
<xsl:param name="str" select="''"/>
|
||||||
|
<xsl:param name="pad" select="0"/>
|
||||||
|
<xsl:variable name="diff" select="$pad - string-length($str)" />
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="$diff < 0">
|
||||||
|
<xsl:value-of select="$str"/>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<xsl:call-template name="space">
|
||||||
|
<xsl:with-param name="repeat" select="$diff"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:value-of select="$str"/>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="rpad">
|
||||||
|
<xsl:param name="str" select="''"/>
|
||||||
|
<xsl:param name="pad" select="0"/>
|
||||||
|
<xsl:variable name="diff" select="$pad - string-length($str)"/>
|
||||||
|
<xsl:choose>
|
||||||
|
<xsl:when test="$diff < 0">
|
||||||
|
<xsl:value-of select="$str"/>
|
||||||
|
</xsl:when>
|
||||||
|
<xsl:otherwise>
|
||||||
|
<xsl:value-of select="$str"/>
|
||||||
|
<xsl:call-template name="space">
|
||||||
|
<xsl:with-param name="repeat" select="$diff"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:otherwise>
|
||||||
|
</xsl:choose>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template name="space">
|
||||||
|
<xsl:param name="repeat">0</xsl:param>
|
||||||
|
<xsl:param name="fill" select="' '"/>
|
||||||
|
<xsl:if test="number($repeat) >= 1">
|
||||||
|
<xsl:call-template name="space">
|
||||||
|
<xsl:with-param name="repeat" select="$repeat - 1"/>
|
||||||
|
<xsl:with-param name="fill" select="$fill"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:value-of select="$fill"/>
|
||||||
|
</xsl:if>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
</xsl:stylesheet>
|
||||||
2065
tools/data/yacc.c
Normal file
2065
tools/data/yacc.c
Normal file
File diff suppressed because it is too large
Load Diff
BIN
tools/flex.exe
BIN
tools/flex.exe
Binary file not shown.
Reference in New Issue
Block a user