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:
John Kessenich
2013-07-08 19:39:16 +00:00
parent 5f1a0b7998
commit 7213324259
59 changed files with 18949 additions and 4503 deletions

View File

@@ -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;

View File

@@ -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" />

View File

@@ -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">

View File

@@ -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_

View File

@@ -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

View File

@@ -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; return true;
}
} }
if (*cpp->PaStrLen > 0) { yyparse((void*)this);
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;
}
delete writeablePreamble; return numErrors == 0;
return true;
} }
// 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
@@ -707,8 +535,8 @@ void TParseContext::variableCheck(TIntermTyped*& nodePtr)
symbolTable.insert(*fakeVariable); symbolTable.insert(*fakeVariable);
// substitute a symbol node for this new variable // substitute a symbol node for this new variable
nodePtr = intermediate.addSymbol(fakeVariable->getUniqueId(), nodePtr = intermediate.addSymbol(fakeVariable->getUniqueId(),
fakeVariable->getName(), fakeVariable->getName(),
fakeVariable->getType(), symbol->getLoc()); fakeVariable->getType(), symbol->getLoc());
} else { } else {
switch (symbol->getQualifier().storage) { switch (symbol->getQualifier().storage) {
@@ -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);
}

View File

@@ -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_

View File

@@ -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;

View File

@@ -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;
} }

View File

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

View File

@@ -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.
// //

View File

@@ -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

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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); ii + 1, collision[ii], GetAtomString(atable, atable->htable.entry[collision[ii]].value));
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));
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;
@@ -669,7 +627,7 @@ int InitAtomTable(AtomTable *atable, int htsize)
// Add single character tokens to the atom table: // Add single character tokens to the atom table:
{ {
const char *s = "~!%^&*()-+=|,.<>/?;:[]{}#"; const char *s = "~!%^&*()-+=|,.<>/?;:[]{}#";
char t[2]; char t[2];
t[1] = '\0'; t[1] = '\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,48 +653,45 @@ 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]];
return chr_str; return chr_str;
} // 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);

View File

@@ -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;
}
}

View 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

View File

@@ -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;
} }

View File

@@ -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,140 +87,104 @@ 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));
memset(in, 0, sizeof(StringInputSrc)); memset(in, 0, sizeof(StringInputSrc));
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,36 +195,36 @@ 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;
int isDouble = 0; int isDouble = 0;
HasDecimal = 0; HasDecimal = 0;
declen = 0; declen = 0;
exp = 0; exp = 0;
str_len=len; str_len=len;
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;
@@ -346,32 +311,31 @@ 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:
return ch; // Single character token return ch; // Single character token
case EOF: case EOF:
return EOF; return EOF;
case 'A': case 'B': case 'C': case 'D': case 'E': case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I': case 'J': case 'F': case 'G': case 'H': case 'I': case 'J':
case 'K': case 'L': case 'M': case 'N': case 'O': case 'K': case 'L': case 'M': case 'N': case 'O':
case 'P': case 'Q': case 'R': case 'S': case 'T': case 'P': case 'Q': case 'R': case 'S': case 'T':
@@ -386,43 +350,43 @@ 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') ||
(ch >= '0' && ch <= '9') || (ch >= '0' && ch <= '9') ||
ch == '_' || ch == '_' ||
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,16 +798,14 @@ 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;
} }
/////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -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;
@@ -117,7 +115,7 @@ Scope *NewScopeInPool(MemoryPool *pool)
lScope->parent = NULL; lScope->parent = NULL;
lScope->funScope = NULL; lScope->funScope = NULL;
lScope->symbols = NULL; lScope->symbols = NULL;
lScope->level = 0; lScope->level = 0;
lScope->programs = NULL; lScope->programs = NULL;
@@ -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;
@@ -143,9 +142,9 @@ void PushScope(Scope *fScope)
if (fScope->level == 1) { if (fScope->level == 1) {
if (!GlobalScope) { if (!GlobalScope) {
/* HACK - CTD -- if GlobalScope==NULL and level==1, we're /* HACK - CTD -- if GlobalScope==NULL and level==1, we're
* defining a function in the superglobal scope. Things * defining a function in the superglobal scope. Things
* will break if we leave the level as 1, so we arbitrarily * will break if we leave the level as 1, so we arbitrarily
* set it to 2 */ * set it to 2 */
fScope->level = 2; fScope->level = 2;
} }
} }
@@ -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;
@@ -195,7 +194,7 @@ Symbol *NewSymbol(SourceLoc *loc, Scope *fScope, int name, symbolkind kind)
lSymb->name = name; lSymb->name = name;
lSymb->loc = *loc; lSymb->loc = *loc;
lSymb->kind = kind; lSymb->kind = kind;
// Clear union area: // Clear union area:
pch = (char *) &lSymb->details; pch = (char *) &lSymb->details;
@@ -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;

View File

@@ -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;
@@ -112,7 +114,7 @@ static char *idstr(const char *fstr, MemoryPool *pool)
str = (char *) malloc(len + 1); str = (char *) malloc(len + 1);
else else
str = (char *) mem_Alloc(pool, len + 1); str = (char *) mem_Alloc(pool, len + 1);
for (f=fstr, t=str; *f; f++) { for (f=fstr, t=str; *f; f++) {
if (isalnum(*f)) *t++ = *f; if (isalnum(*f)) *t++ = *f;
else if (*f == '.' || *f == '/') *t++ = '_'; else if (*f == '.' || *f == '/') *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,26 +263,26 @@ 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++;
} }
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;
@@ -311,35 +314,35 @@ int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
len = 0; len = 0;
ch = lReadByte(pTok); ch = lReadByte(pTok);
while ((ch >= 'a' && ch <= 'z') || while ((ch >= 'a' && ch <= 'z') ||
(ch >= 'A' && ch <= 'Z') || (ch >= 'A' && ch <= 'Z') ||
(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);
} }
} }

View File

@@ -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 */

View File

@@ -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

View File

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

View File

@@ -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 //////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -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 */

View File

@@ -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

View File

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

View File

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

View File

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

Binary file not shown.

View File

@@ -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;
}
$

View File

@@ -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
View 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

File diff suppressed because it is too large Load Diff

70
tools/data/README Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

346
tools/data/glr.cc Normal file
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

927
tools/data/lalr1.java Normal file
View 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
View 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()

View 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])-])])

File diff suppressed because it is too large Load Diff

121
tools/data/stack.hh Normal file
View 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
View 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) &gt;= 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
View 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>.&#10;</xsl:text>
<xsl:text>// Report bugs to &lt;</xsl:text>
<xsl:value-of select="@bug-report"/>
<xsl:text>&gt;.&#10;</xsl:text>
<xsl:text>// Home page: &lt;</xsl:text>
<xsl:value-of select="@url"/>
<xsl:text>&gt;.&#10;&#10;</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>"&#10;{
node [fontname = courier, shape = box, colorscheme = paired6]
edge [fontname = courier]
</xsl:text>
<xsl:apply-templates select="state"/>
<xsl:text>}&#10;</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]&#10;</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>&#10;</xsl:text>
<xsl:choose>
<xsl:when test="$num &lt; 10">
<xsl:text> </xsl:text>
</xsl:when>
<xsl:when test="$num &lt; 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]&#10;</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"]&#10;</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>]&#10;</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="'&quot;'"/>
<xsl:with-param name="replace" select="'\&quot;'"/>
</xsl:call-template>
</xsl:with-param>
<xsl:with-param name="search" select="'&#10;'"/>
<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 &lt; 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>

View 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&#10;&#10;</xsl:text>
<xsl:for-each select="nonterminal[@usefulness='useless-in-grammar']">
<xsl:text> </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text>&#10;</xsl:text>
</xsl:for-each>
<xsl:text>&#10;&#10;</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&#10;&#10;</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>&#10;</xsl:text>
</xsl:for-each>
<xsl:text>&#10;&#10;</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&#10;</xsl:text>
<xsl:call-template name="style-rule-set">
<xsl:with-param name="rule-set" select="$set"/>
</xsl:call-template>
<xsl:text>&#10;&#10;</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&#10;</xsl:text>
<xsl:call-template name="style-rule-set">
<xsl:with-param name="rule-set" select="$set"/>
</xsl:call-template>
<xsl:text>&#10;&#10;</xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="grammar">
<xsl:text>Grammar&#10;</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>&#10;&#10;</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&#10;&#10;</xsl:text>
<xsl:apply-templates select="terminal"/>
<xsl:text>&#10;&#10;</xsl:text>
</xsl:template>
<xsl:template match="grammar/nonterminals">
<xsl:text>Nonterminals, with rules where they appear&#10;&#10;</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) &gt; 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>&#10;</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>&#10;&#10;</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="'&#10;'"/>
</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>&#10;&#10;</xsl:text>
<xsl:text>State </xsl:text>
<xsl:value-of select="@number"/>
<xsl:text>&#10;&#10;</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>&#10;</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>&#10;</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>&#10;</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>&#10;</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>&#10;</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>&#10;</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>&#10;</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>&#10;</xsl:text>
</xsl:template>
<xsl:template match="solved-conflicts">
<xsl:if test="resolution">
<xsl:text>&#10;</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>).&#10;</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 &lt; 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 &lt; 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) &lt;= $first-line-length">
<xsl:value-of select="concat($text, '&#10;')" />
</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>&#10;</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>

View 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>&#10;&#10;</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>&#10;&#10;</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>&#10;&#10;</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>&#10;</xsl:text>
</xsl:for-each>
<xsl:text>&#10;&#10;</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>&#10;&#10;</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>&#10;</xsl:text>
</xsl:for-each>
<xsl:text>&#10;&#10;</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>&#10;</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>&#10;&#10;</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>&#10;</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>&#10;&#10;</xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="grammar">
<h2>
<a name="grammar"/>
<xsl:text> Grammar</xsl:text>
</h2>
<xsl:text>&#10;</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>&#10;&#10;</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>&#10;&#10;</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>&#10;&#10;</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="'&#10;'"/>
</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>&#10;&#10;</xsl:text>
<p class="pre">
<xsl:apply-templates select="terminal"/>
</p>
<xsl:text>&#10;&#10;</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>&#10;&#10;</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>&#10;</xsl:text>
</xsl:template>
<xsl:template match="nonterminal">
<b><xsl:value-of select="@name"/></b>
<xsl:value-of select="concat(' (', @symbol-number, ')')"/>
<xsl:text>&#10; </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>&#10; </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>&#10;</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>&#10;&#10;</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>&#10;&#10;</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>&#10;</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>&#10;</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>&#10;</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>&#10;</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> &#8594;</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>&#10;</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> &#949;</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>&#10;</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>&#10;</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>&#10;</xsl:text>
</xsl:template>
<xsl:template match="solved-conflicts">
<xsl:if test="resolution">
<xsl:text>&#10;</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>).&#10;</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 &lt; 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 &lt; 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) &gt;= 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

File diff suppressed because it is too large Load Diff

Binary file not shown.