From: helly Date: Mon, 17 Apr 2006 14:14:17 +0000 (+0000) Subject: - Update lessons X-Git-Tag: 0.13.6~374 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=857ffe1033ad938597bdf4ad5b28562710284731;p=re2c - Update lessons --- diff --git a/lessons/001_upn_calculator/calc_001.c b/lessons/001_upn_calculator/calc_001.c index 8a9c2e93..a4171120 100755 --- a/lessons/001_upn_calculator/calc_001.c +++ b/lessons/001_upn_calculator/calc_001.c @@ -1,6 +1,6 @@ /* Generated by re2c */ #line 1 "calc_001.re" -/* re2c lesson_001, calc_001, (c) M. Boerger 2006 */ +/* re2c lesson 001_upn_calculator, calc_001, (c) M. Boerger 2006 */ #line 43 "calc_001.re" #include diff --git a/lessons/001_upn_calculator/calc_001.re b/lessons/001_upn_calculator/calc_001.re index 911f89bf..a810f18c 100755 --- a/lessons/001_upn_calculator/calc_001.re +++ b/lessons/001_upn_calculator/calc_001.re @@ -1,4 +1,4 @@ -/* re2c lesson_001, calc_001, (c) M. Boerger 2006 */ +/* re2c lesson 001_upn_calculator, calc_001, (c) M. Boerger 2006 */ /*!ignore:re2c - basic interface for string reading @@ -12,7 +12,7 @@ expression handlers, the code blocks after re2c expressions, this can be used to identify the end of the token. . YYMARKER is not always being used so we set an initial value to avoid - a compiler warning. + a compiler warning. Here we could also omit it compleley. . YYLIMIT stores the end of the input. Unfortunatley we have to use strlen() in this lesson. In the next example we see one way to get rid of it. . We use a 'for(;;)'-loop around the scanner block. We could have used a diff --git a/lessons/001_upn_calculator/calc_002.c b/lessons/001_upn_calculator/calc_002.c index c1810aee..b380d064 100755 --- a/lessons/001_upn_calculator/calc_002.c +++ b/lessons/001_upn_calculator/calc_002.c @@ -1,6 +1,6 @@ /* Generated by re2c */ #line 1 "calc_002.re" -/* re2c lesson_001, calc_002, (c) M. Boerger 2006 */ +/* re2c lesson 001_upn_calculator, calc_002, (c) M. Boerger 2006 */ #line 19 "calc_002.re" #include diff --git a/lessons/001_upn_calculator/calc_002.re b/lessons/001_upn_calculator/calc_002.re index e8dadae3..0f045241 100755 --- a/lessons/001_upn_calculator/calc_002.re +++ b/lessons/001_upn_calculator/calc_002.re @@ -1,4 +1,4 @@ -/* re2c lesson_001, calc_002, (c) M. Boerger 2006 */ +/* re2c lesson 001_upn_calculator, calc_002, (c) M. Boerger 2006 */ /*!ignore:re2c - making use of YYFILL diff --git a/lessons/001_upn_calculator/calc_003.c b/lessons/001_upn_calculator/calc_003.c index 763e5eb3..2a2e65ff 100755 --- a/lessons/001_upn_calculator/calc_003.c +++ b/lessons/001_upn_calculator/calc_003.c @@ -1,6 +1,6 @@ /* Generated by re2c */ #line 1 "calc_003.re" -/* re2c lesson_001, calc_003, (c) M. Boerger 2006 */ +/* re2c lesson 001_upn_calculator, calc_003, (c) M. Boerger 2006 */ #line 19 "calc_003.re" #include diff --git a/lessons/001_upn_calculator/calc_003.re b/lessons/001_upn_calculator/calc_003.re index 4112cb3c..a868be55 100755 --- a/lessons/001_upn_calculator/calc_003.re +++ b/lessons/001_upn_calculator/calc_003.re @@ -1,4 +1,4 @@ -/* re2c lesson_001, calc_003, (c) M. Boerger 2006 */ +/* re2c lesson 001_upn_calculator, calc_003, (c) M. Boerger 2006 */ /*!ignore:re2c - making use of YYFILL diff --git a/lessons/001_upn_calculator/calc_004.c b/lessons/001_upn_calculator/calc_004.c index d830ef21..0cff796b 100755 --- a/lessons/001_upn_calculator/calc_004.c +++ b/lessons/001_upn_calculator/calc_004.c @@ -1,6 +1,6 @@ /* Generated by re2c */ #line 1 "calc_004.re" -/* re2c lesson_001, calc_004, (c) M. Boerger 2006 */ +/* re2c lesson 001_upn_calculator, calc_004, (c) M. Boerger 2006 */ #line 20 "calc_004.re" #include diff --git a/lessons/001_upn_calculator/calc_004.re b/lessons/001_upn_calculator/calc_004.re index f892afb9..885e8be3 100755 --- a/lessons/001_upn_calculator/calc_004.re +++ b/lessons/001_upn_calculator/calc_004.re @@ -1,4 +1,4 @@ -/* re2c lesson_001, calc_004, (c) M. Boerger 2006 */ +/* re2c lesson 001_upn_calculator, calc_004, (c) M. Boerger 2006 */ /*!ignore:re2c - making use of definitions diff --git a/lessons/001_upn_calculator/calc_005.c b/lessons/001_upn_calculator/calc_005.c index 6babb634..c7ff80be 100755 --- a/lessons/001_upn_calculator/calc_005.c +++ b/lessons/001_upn_calculator/calc_005.c @@ -1,6 +1,6 @@ /* Generated by re2c */ #line 1 "calc_005.re" -/* re2c lesson_001, calc_005, (c) M. Boerger 2006 */ +/* re2c lesson 001_upn_calculator, calc_005, (c) M. Boerger 2006 */ #line 19 "calc_005.re" #include diff --git a/lessons/001_upn_calculator/calc_005.re b/lessons/001_upn_calculator/calc_005.re index 9e3c50b4..ae4c4755 100755 --- a/lessons/001_upn_calculator/calc_005.re +++ b/lessons/001_upn_calculator/calc_005.re @@ -1,4 +1,4 @@ -/* re2c lesson_001, calc_005, (c) M. Boerger 2006 */ +/* re2c lesson 001_upn_calculator, calc_005, (c) M. Boerger 2006 */ /*!ignore:re2c - turning this lesson into an easy calculator diff --git a/lessons/001_upn_calculator/calc_006.s.c b/lessons/001_upn_calculator/calc_006.s.c index 66b4e292..941b94c7 100755 --- a/lessons/001_upn_calculator/calc_006.s.c +++ b/lessons/001_upn_calculator/calc_006.s.c @@ -1,6 +1,6 @@ /* Generated by re2c */ #line 1 "calc_006.s.re" -/* re2c lesson_001, calc_006, (c) M. Boerger 2006 */ +/* re2c lesson 001_upn_calculator, calc_006, (c) M. Boerger 2006 */ #line 34 "calc_006.s.re" #include diff --git a/lessons/001_upn_calculator/calc_006.s.re b/lessons/001_upn_calculator/calc_006.s.re index 830af3dd..a49ef287 100755 --- a/lessons/001_upn_calculator/calc_006.s.re +++ b/lessons/001_upn_calculator/calc_006.s.re @@ -1,4 +1,4 @@ -/* re2c lesson_001, calc_006, (c) M. Boerger 2006 */ +/* re2c lesson 001_upn_calculator, calc_006, (c) M. Boerger 2006 */ /*!ignore:re2c - avoiding YYFILL() diff --git a/lessons/001_upn_calculator/calc_007.b.c b/lessons/001_upn_calculator/calc_007.b.c index 66d5b368..5ea4b190 100755 --- a/lessons/001_upn_calculator/calc_007.b.c +++ b/lessons/001_upn_calculator/calc_007.b.c @@ -1,6 +1,6 @@ /* Generated by re2c */ #line 1 "calc_007.b.re" -/* re2c lesson_001, calc_007, (c) M. Boerger 2006 */ +/* re2c lesson 001_upn_calculator, calc_007, (c) M. Boerger 2006 */ #line 8 "calc_007.b.re" #include diff --git a/lessons/001_upn_calculator/calc_007.b.re b/lessons/001_upn_calculator/calc_007.b.re index 469ae5e1..25263120 100755 --- a/lessons/001_upn_calculator/calc_007.b.re +++ b/lessons/001_upn_calculator/calc_007.b.re @@ -1,4 +1,4 @@ -/* re2c lesson_001, calc_007, (c) M. Boerger 2006 */ +/* re2c lesson 001_upn_calculator, calc_007, (c) M. Boerger 2006 */ /*!ignore:re2c - optimizing the generated code by using -b command line switch of re2c diff --git a/lessons/001_upn_calculator/readme.txt b/lessons/001_upn_calculator/readme.txt index 62860bb3..321b65e9 100755 --- a/lessons/001_upn_calculator/readme.txt +++ b/lessons/001_upn_calculator/readme.txt @@ -1,4 +1,4 @@ -re2c lesson_001, (c) M. Boerger 2006 +re2c lesson 001_upn_calculator, (c) M. Boerger 2006 This lesson gets you started with re2c. In the end you will have an easy UPN calculator for use at command line. @@ -15,7 +15,13 @@ directory and execute the following command: re2c calc_001.re > test.c -Then use your compiler to compile that code and run it. +Then use your compiler to compile that code and run it. If you are using gcc +you simply do the following: + + gcc -o test.o test.c + ./test.o + +If you are using windows you might want to read till the end of this lesson. When you want to debug the code it helps to make re2c generate working #line information. To do so you simply specify the output file using the -o switch @@ -38,3 +44,35 @@ Finally we use the -b switch to have the code use a decision table. The -b switch also contains the -s behavior. re2c -b -o test.c calc_007.b.re + + + +------------------------------------------------------------------------------- + +For windows users Lynn Allen provided some additional stuff to get you started +in the Microsoft world. This addon resides in the windows subdirectory and +gives you something to expereiment with. The code in that directory is based +on the first step and has the following changes: + +* vc6 .dsp/.dsw and vc7/vc8 .sln/.vcproj project files that have "Custom Build +Steps" that can tell when main.re changes, and know how to generate main.c +from main.re. They assume that you unpacked the zip package and have re2c +itself build or installed in Release and Release-2005 directory respectively. +If re2c cannot be found you need to modify the custom build step and correct +the path to re2c. + +* BuildAndRun.bat to do command line rec2 and then cl and then run the +executable (discontinues with message if errors). + +* built-in cppunit-like test to confirm it worked as expected. + +* array of test strings "fed" to scan rather than file contents to facilitate +testing and also reduce the newbie learning curve. + +* HiResTimer output for 10,000 loops and 100,000 loops. While this might be +excessive for this lesson, it illustrates how to do it for subsequent lessons +and your own stuff using windows. Also it shows that Release build is as fast +as strncmp for this test and can probably be made significantly faster. + +* If you want to build the other steps of this lesson using windows tools +simply copy the *.re files into the windows directory as main.re and rebuild. diff --git a/lessons/001_upn_calculator/windows/.cvsignore b/lessons/001_upn_calculator/windows/.cvsignore new file mode 100755 index 00000000..ab030f2e --- /dev/null +++ b/lessons/001_upn_calculator/windows/.cvsignore @@ -0,0 +1,11 @@ +*.diff +*.exe +*.ncb +*.opt +*.plg +*.scc +*.suo +*.temp +*.user +Debug +Release diff --git a/lessons/001_upn_calculator/windows/BuildAndRun.bat b/lessons/001_upn_calculator/windows/BuildAndRun.bat new file mode 100755 index 00000000..e40a7d43 --- /dev/null +++ b/lessons/001_upn_calculator/windows/BuildAndRun.bat @@ -0,0 +1,48 @@ +@echo OFF +goto Start +rem BuildAndRun.bat 06-Apr-15 lda +rem Assumes re2c.exe findable with PATH or . or .. or ..\.. or $(RE2C_HOME) +rem Assumes cl.exe findable with PATH or VcToolKit2003 installed + +:Start +if exist %RE2C_HOME%\re2c.exe goto ProceedWithGenerate +if exist .\re2c.exe set RE2C_HOME=. +if exist ..\re2c.exe set RE2C_HOME=.. +if exist ..\..\re2c.exe set RE2C_HOME=..\.. +if exist ..\..\..\re2c.exe set RE2C_HOME=..\..\.. +if exist ..\..\..\Release\re2c.exe set RE2C_HOME=..\..\..\Release +if exist ..\..\..\Release-2005\re2c.exe set RE2C_HOME=..\..\..\Release-2005 +if not exist %RE2C_HOME%\re2c.exe goto ReportSetupError + +:ProceedWithGenerate +set BASE_FILE_NAME=main +%RE2C_HOME%\re2c -b -o%BASE_FILE_NAME%.c %BASE_FILE_NAME%.re +rem echo ErrorLevel is set to %ERRORLEVEL% after re2c +IF ERRORLEVEL 1 goto ReportRe2cError + +rem (to test) set path= +cl 1>nul 2>nul +IF ERRORLEVEL 1 goto AttemptToSetupCompiler +goto ProceedWithCompile + +:AttemptToSetupCompiler +echo ErrorLevel is set to %ERRORLEVEL% after blank cl command line +call %VCToolkitInstallDir%\vcvars32.bat 1>nul 2>nul +cl 1>nul 2>nul +IF ERRORLEVEL 1 goto ReportClError + +:ProceedWithCompile +cl -O2 /DNDEBUG /D_CONSOLE /DWIN32 %BASE_FILE_NAME%.c +rem echo ErrorLevel is set to %ERRORLEVEL% after cl +IF ERRORLEVEL 1 goto ReportClError +%BASE_FILE_NAME% +goto AllDone + +:ReportSetupError +echo re2c.exe not found in ., .., ..\.., ..\..\.., ..\..\..\Release +echo or ..\..\..\Release-2005 Environment variable RE2C_HOME invalid or not set? + +:ReportClError +:ReportRe2cError +:AllDone +pause diff --git a/lessons/001_upn_calculator/windows/HiResTimer.h b/lessons/001_upn_calculator/windows/HiResTimer.h new file mode 100755 index 00000000..585a1d98 --- /dev/null +++ b/lessons/001_upn_calculator/windows/HiResTimer.h @@ -0,0 +1,54 @@ +/** + * @file HiResTimer.h + * @brief + * @note + */ + +#ifndef _HI_RES_TIMER_H_ +#define _HI_RES_TIMER_H_ + +#ifdef WIN32 +#include // probably already done in stdafx.h +static LARGE_INTEGER start; +static LARGE_INTEGER stop; +static LARGE_INTEGER freq; +static _int64 elapsedCounts; +static double elapsedMillis; +static double elapsedMicros; +static HANDLE processHandle; +static DWORD prevPriorityClass; + +void HrtInit() +{ + processHandle = GetCurrentProcess(); + prevPriorityClass = GetPriorityClass(processHandle); + QueryPerformanceFrequency(&freq); +} + +void HrtStart() +{ + QueryPerformanceCounter(&start); +} + +void HrtSetPriority(DWORD priority) +{ + int flag; + prevPriorityClass = GetPriorityClass(processHandle); + flag = SetPriorityClass(processHandle, priority); +} + +void HrtResetPriority(void) +{ + int flag = SetPriorityClass(processHandle, prevPriorityClass); +} + +double HrtElapsedMillis() +{ + QueryPerformanceCounter(&stop); + elapsedCounts = (stop.QuadPart - start.QuadPart); + elapsedMillis = ((elapsedCounts * 1000.0) / freq.QuadPart); + return elapsedMillis; +} + +#endif +#endif \ No newline at end of file diff --git a/lessons/001_upn_calculator/windows/TestRe2c-2005.sln b/lessons/001_upn_calculator/windows/TestRe2c-2005.sln new file mode 100755 index 00000000..1b4b4e5d --- /dev/null +++ b/lessons/001_upn_calculator/windows/TestRe2c-2005.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestRe2c", "TestRe2c-2005.vcproj", "{E2CEB3D0-066A-4C9A-B32C-B2197448A57A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Default = Debug|Default + Release|Default = Release|Default + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E2CEB3D0-066A-4C9A-B32C-B2197448A57A}.Debug|Default.ActiveCfg = Debug|Win32 + {E2CEB3D0-066A-4C9A-B32C-B2197448A57A}.Debug|Default.Build.0 = Debug|Win32 + {E2CEB3D0-066A-4C9A-B32C-B2197448A57A}.Release|Default.ActiveCfg = Release|Win32 + {E2CEB3D0-066A-4C9A-B32C-B2197448A57A}.Release|Default.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/lessons/001_upn_calculator/windows/TestRe2c-2005.vcproj b/lessons/001_upn_calculator/windows/TestRe2c-2005.vcproj new file mode 100755 index 00000000..1d3582bb --- /dev/null +++ b/lessons/001_upn_calculator/windows/TestRe2c-2005.vcproj @@ -0,0 +1,252 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lessons/001_upn_calculator/windows/TestRe2c.dsp b/lessons/001_upn_calculator/windows/TestRe2c.dsp new file mode 100755 index 00000000..7eb94630 --- /dev/null +++ b/lessons/001_upn_calculator/windows/TestRe2c.dsp @@ -0,0 +1,124 @@ +# Microsoft Developer Studio Project File - Name="TestRe2c" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** NICHT BEARBEITEN ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=TestRe2c - Win32 Debug +!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE +!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl +!MESSAGE +!MESSAGE NMAKE /f "TestRe2c.mak". +!MESSAGE +!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben +!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: +!MESSAGE +!MESSAGE NMAKE /f "TestRe2c.mak" CFG="TestRe2c - Win32 Debug" +!MESSAGE +!MESSAGE Für die Konfiguration stehen zur Auswahl: +!MESSAGE +!MESSAGE "TestRe2c - Win32 Release" (basierend auf "Win32 (x86) Console Application") +!MESSAGE "TestRe2c - Win32 Debug" (basierend auf "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +RSC=rc.exe + +!IF "$(CFG)" == "TestRe2c - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "TestRe2c - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "TestRe2c - Win32 Release" +# Name "TestRe2c - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\main.b.c +# End Source File +# Begin Source File + +SOURCE=.\main.b.re + +!IF "$(CFG)" == "TestRe2c - Win32 Release" + +# Begin Custom Build - Generate $(InputName).c from $(InputName).re using Re2c +InputPath=.\main.b.re +InputName=main.b + +"$(InputName).c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ..\..\..\Release-2005\re2c -b -o$(InputName).c $(InputName).re + +# End Custom Build + +!ELSEIF "$(CFG)" == "TestRe2c - Win32 Debug" + +# Begin Custom Build - Generate $(InputName).c from $(InputName).re using Re2c +InputPath=.\main.b.re +InputName=main.b + +"$(InputName).c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ..\..\..\Release-2005\re2c -b -o$(InputName).c $(InputName).re + +# End Custom Build + +!ENDIF + +# End Source File +# End Group +# End Target +# End Project diff --git a/lessons/001_upn_calculator/windows/TestRe2c.dsw b/lessons/001_upn_calculator/windows/TestRe2c.dsw new file mode 100755 index 00000000..eb8f630d --- /dev/null +++ b/lessons/001_upn_calculator/windows/TestRe2c.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "TestRe2c"=.\TestRe2c.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/lessons/001_upn_calculator/windows/TestRe2c.sln b/lessons/001_upn_calculator/windows/TestRe2c.sln new file mode 100755 index 00000000..8d051b8d --- /dev/null +++ b/lessons/001_upn_calculator/windows/TestRe2c.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 7.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestRe2c", "TestRe2c.vcproj", "{BEC086F1-62CD-4BA7-8E17-367B825FA721}" +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + ConfigName.0 = Debug + ConfigName.1 = Release + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {BEC086F1-62CD-4BA7-8E17-367B825FA721}.Debug.ActiveCfg = Debug|Win32 + {BEC086F1-62CD-4BA7-8E17-367B825FA721}.Debug.Build.0 = Debug|Win32 + {BEC086F1-62CD-4BA7-8E17-367B825FA721}.Release.ActiveCfg = Release|Win32 + {BEC086F1-62CD-4BA7-8E17-367B825FA721}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/lessons/001_upn_calculator/windows/TestRe2c.vcproj b/lessons/001_upn_calculator/windows/TestRe2c.vcproj new file mode 100755 index 00000000..1dca53dc --- /dev/null +++ b/lessons/001_upn_calculator/windows/TestRe2c.vcproj @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lessons/001_upn_calculator/windows/main.b.c b/lessons/001_upn_calculator/windows/main.b.c new file mode 100755 index 00000000..2f9e4987 --- /dev/null +++ b/lessons/001_upn_calculator/windows/main.b.c @@ -0,0 +1,456 @@ +/* Generated by re2c 0.10.2.dev on Mon Apr 17 16:07:31 2006 */ +#line 1 "main.b.re" +/* re2c lesson 001_upn_calculator, main.b.re, (c) M. Boerger 2006 */ +#line 43 "main.b.re" + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#if _MSC_VER > 1200 +#define WINVER 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later. +#endif // Prevents warning from vc7.1 complaining about redefinition + +#include +#include +#include +#include +#include +#include "HiResTimer.h" + +static char gTestBuf[1000] = ""; + +/** + * @brief Setup HiResolution timer and confirm it is working ok + */ +void InitHiResTimerAndVerifyWorking(void) +{ + double elapsed; + HrtInit(); + HrtSetPriority(ABOVE_NORMAL_PRIORITY_CLASS); + HrtStart(); + Sleep(100); + elapsed = HrtElapsedMillis(); + if ((elapsed < 90) || (elapsed > 110)) { + printf("HiResTimer misbehaving: %f\n", elapsed); + exit(2); + } +} + +/** + * @brief Scan for numbers in different formats + */ +int ScanFullSpeed(char *pzStrToScan, size_t lenStrToScan) +{ + char *pzCurScanPos = pzStrToScan; + char *pzBacktrackInfo = 0; + #define YYCTYPE char + #define YYCURSOR pzCurScanPos + #define YYLIMIT (pzStrToScan+lenStrToScan) + #define YYMARKER pzBacktrackInfo + #define YYFILL(n) + + for(;;) + { + { + static unsigned char yybm[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }; + +#line 90 "main.b.c" + { + YYCTYPE yych; + + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if(yych <= ',') { + if(yych <= 0x00) goto yy10; + if(yych == '+') goto yy6; + goto yy12; + } else { + if(yych <= '/') { + if(yych <= '-') goto yy8; + goto yy12; + } else { + if(yych <= '0') goto yy4; + if(yych >= ':') goto yy12; + } + } + ++YYCURSOR; + yych = *YYCURSOR; + goto yy17; +yy3: +#line 93 "main.b.re" + { continue; } +#line 115 "main.b.c" +yy4: + ++YYCURSOR; + if(yybm[0+(yych = *YYCURSOR)] & 128) { + goto yy13; + } +yy5: +#line 98 "main.b.re" + { return 1; } +#line 124 "main.b.c" +yy6: + ++YYCURSOR; +#line 95 "main.b.re" + { continue; } +#line 129 "main.b.c" +yy8: + ++YYCURSOR; +#line 96 "main.b.re" + { continue; } +#line 134 "main.b.c" +yy10: + ++YYCURSOR; +#line 97 "main.b.re" + { return 0; } +#line 139 "main.b.c" +yy12: + yych = *++YYCURSOR; + goto yy5; +yy13: + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yybm[0+yych] & 128) { + goto yy13; + } +#line 94 "main.b.re" + { continue; } +#line 152 "main.b.c" +yy16: + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy17: + if(yych <= '/') goto yy3; + if(yych <= '9') goto yy16; + goto yy3; + } + } +#line 99 "main.b.re" + + } +} + +/** + * @brief Scan for numbers in different formats + */ +int scan(char *pzStrToScan, size_t lenStrToScan) +{ + char *pzCurScanPos = pzStrToScan; + char *pzBacktrackInfo = 0; + #define YYCTYPE char + #define YYCURSOR pzCurScanPos + #define YYLIMIT (pzStrToScan+lenStrToScan) + #define YYMARKER pzBacktrackInfo + #define YYFILL(n) + + for(;;) + { + { + static unsigned char yybm[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }; + +#line 219 "main.b.c" + { + YYCTYPE yych; + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if(yych <= ',') { + if(yych <= 0x00) goto yy28; + if(yych == '+') goto yy24; + goto yy30; + } else { + if(yych <= '/') { + if(yych <= '-') goto yy26; + goto yy30; + } else { + if(yych <= '0') goto yy22; + if(yych >= ':') goto yy30; + } + } + ++YYCURSOR; + yych = *YYCURSOR; + goto yy35; +yy21: +#line 120 "main.b.re" + { printf("Num\n"); strcat(gTestBuf, "Num "); continue; } +#line 243 "main.b.c" +yy22: + ++YYCURSOR; + if(yybm[0+(yych = *YYCURSOR)] & 128) { + goto yy31; + } +yy23: +#line 125 "main.b.re" + { printf("ERR\n"); strcat(gTestBuf, "ERR "); return 1; } +#line 252 "main.b.c" +yy24: + ++YYCURSOR; +#line 122 "main.b.re" + { printf("+\n"); strcat(gTestBuf, "+ "); continue; } +#line 257 "main.b.c" +yy26: + ++YYCURSOR; +#line 123 "main.b.re" + { printf("-\n"); strcat(gTestBuf, "- "); continue; } +#line 262 "main.b.c" +yy28: + ++YYCURSOR; +#line 124 "main.b.re" + { printf("EOF\n"); return 0; } +#line 267 "main.b.c" +yy30: + yych = *++YYCURSOR; + goto yy23; +yy31: + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yybm[0+yych] & 128) { + goto yy31; + } +#line 121 "main.b.re" + { printf("Oct\n"); strcat(gTestBuf, "Oct "); continue; } +#line 280 "main.b.c" +yy34: + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy35: + if(yych <= '/') goto yy21; + if(yych <= '9') goto yy34; + goto yy21; + } + } +#line 126 "main.b.re" + + } +} + +/** + * @brief Show high resolution elapsed time for 10,000 and 100,000 loops + */ +void DoTimingsOfStrnCmp(void) +{ + char testStr[] = "Hello, world"; + int totLoops = 10000; + int totFoundCount = 0; + int foundCount = 0; + int loop; + int rc; + const int progressAnd = 0xFFFFF000; + double elapsed; + + printf("\n\n%d loops with * every %d loops to confirm\n", totLoops, ((~progressAnd) + 1)); + + HrtStart(); + for (loop = 0; loop < totLoops; ++loop) { + foundCount = 0; + rc = strncmp(testStr, "Hello", 5); + if (rc == 0) { + foundCount++; + totFoundCount++; + if ((totFoundCount & progressAnd) == totFoundCount) { + printf("*"); + } + } + } + elapsed = HrtElapsedMillis(); + printf("\nstrncmp Elapsed for %7d loops milliseconds: %7.3f\n", totLoops, elapsed); + printf("FoundCount each loop: %d\n", foundCount); + printf("TotalFoundCount for all loops: %d\n", totFoundCount); + + totLoops = 100000; + HrtStart(); + for (loop = 0; loop < totLoops; ++loop) { + foundCount = 0; + rc = strncmp(testStr, "Hello", 5); + if (rc == 0) { + foundCount++; + totFoundCount++; + if ((totFoundCount & progressAnd) == totFoundCount) { + printf("*"); + } + } + } + elapsed = HrtElapsedMillis(); + printf("\nstrncmp Elapsed for %7d loops milliseconds: %7.3f\n", totLoops, elapsed); + printf("FoundCount each loop: %d\n", foundCount); + printf("TotalFoundCount for all loops: %d\n", totFoundCount); +} + +/** + * @brief Show high resolution elapsed time for 10,000 and 100,000 loops + */ +void DoTimingsOfRe2c(void) +{ + char* testStrings[] = { "123", "1234", "+123", "01234", "-04321", "abc", "123abc" }; + const int testCount = sizeof(testStrings) / sizeof(testStrings[0]); + int i; + int totLoops = 10000 / testCount; // Doing more than one per loop + int totFoundCount = 0; + int foundCount = 0; + int loop; + int rc; + const int progressAnd = 0xFFFFF000; + double elapsed; + + printf("\n\n%d loops with * every %d loops to confirm\n", totLoops, ((~progressAnd) + 1)); + + HrtStart(); + for (loop = 0; loop < totLoops; ++loop) { + foundCount = 0; + strcpy(gTestBuf, ""); + for (i = 0; i < testCount; ++i) { + char* pzCurStr = testStrings[i]; + size_t len = strlen(pzCurStr); // Calc of strlen slows things down ... std::string? + rc = ScanFullSpeed(pzCurStr, len); + if (rc == 0) { + foundCount++; + totFoundCount++; + if ((totFoundCount & progressAnd) == totFoundCount) { + printf("*"); + } + } + } + } + elapsed = HrtElapsedMillis(); + printf("\nRe2c Elapsed for %7d loops milliseconds: %7.3f\n", totLoops, elapsed); + printf("FoundCount each loop: %d\n", foundCount); + printf("TotalFoundCount for all loops: %d\n", totFoundCount); + + totLoops = 100000 / testCount; + printf("\n\n%d loops with * every %d loops to confirm\n", totLoops, ((~progressAnd) + 1)); + + HrtStart(); + for (loop = 0; loop < totLoops; ++loop) { + foundCount = 0; + strcpy(gTestBuf, ""); + for (i = 0; i < testCount; ++i) { + char* pzCurStr = testStrings[i]; + size_t len = strlen(pzCurStr); // Calc of strlen slows things down ... std::string? + rc = ScanFullSpeed(pzCurStr, len); + if (rc == 0) { + foundCount++; + totFoundCount++; + if ((totFoundCount & progressAnd) == totFoundCount) { + printf("*"); + } + } + } + } + elapsed = HrtElapsedMillis(); + printf("\nRe2c Elapsed for %7d loops milliseconds: %7.3f\n", totLoops, elapsed); + printf("FoundCount each loop: %d\n", foundCount); + printf("TotalFoundCount for all loops: %d\n", totFoundCount); +} + +/** + * @brief Entry point for console app + */ +int main(int argc, char **argv) +{ + char testStr_A[] = "123"; + char* testStr_B = "456"; + char* testStrings[] = { "123", "1234", "+123", "01234", "-04321", "abc", "123abc" }; + const int testCount = sizeof(testStrings) / sizeof(testStrings[0]); + int i; + + int rc = scan(testStr_A, 3); + printf("rc: %d\n", rc); + + rc = scan(testStr_B, 3); + printf("rc: %d\n", rc); + + rc = scan("789", 3); + printf("rc: %d\n", rc); + + strcpy(gTestBuf, ""); + for (i = 0; i < testCount; ++i) { + char* pzCurStr = testStrings[i]; + size_t len = strlen(pzCurStr); + scan(pzCurStr, len); + } + printf("%s\n", gTestBuf); + rc = strcmp(gTestBuf, "Num Num + Num Oct - Oct ERR Num ERR "); + if (rc == 0) { + printf("Success\n"); + } + else { + printf("Failure\n"); + } + assert(0 == rc); // Doesn't work with Release build + + InitHiResTimerAndVerifyWorking(); + + DoTimingsOfStrnCmp(); + + DoTimingsOfRe2c(); + + return 0; +} diff --git a/lessons/001_upn_calculator/windows/main.b.re b/lessons/001_upn_calculator/windows/main.b.re new file mode 100755 index 00000000..f782ec9c --- /dev/null +++ b/lessons/001_upn_calculator/windows/main.b.re @@ -0,0 +1,291 @@ +/* re2c lesson 001_upn_calculator, main.b.re, (c) M. Boerger 2006 */ +/*!ignore:re2c + +- basic interface for string reading + + . We define the macros YYCTYPE, YYCURSOR, YYLIMIT, YYMARKER, YYFILL + . YYCTYPE is the type re2c operates on or in other words the type that + it generates code for. While it is not a big difference when we were + using 'unsigned char' here we would need to run re2c with option -w + to fully support types with sieof() > 1. + . YYCURSOR is used internally and holds the current scanner position. In + expression handlers, the code blocks after re2c expressions, this can be + used to identify the end of the token. + . YYMARKER is not always being used so we set an initial value to avoid + a compiler warning. + . YYLIMIT stores the end of the input. Unfortunatley we have to use strlen() + in this lesson. In the next example we see one way to get rid of it. + . We use a 'for(;;)'-loop around the scanner block. We could have used a + 'while(1)'-loop instead but some compilers generate a warning for it. + . To make the output more readable we use 're2c:indent:top' scanenr + configuration that configures re2c to prepend a single tab (the default) + to the beginning of each output line. + . The following lines are expressions and for each expression we output the + token name and continue the scanner loop. + . The second last token detects the end of our input, the terminating zero in + out input string. In other scanners detecting the end of input may vary. + For example binary code may contain \0 as valid input. + . The last expression accepts any input character. It tells re2c to accept + the opposit of the empty range. This includes numbers and our tokens but + as re2c goes from top to botton when evaluating the expressions this is no + problem. + . The first three rules show that re2c actually prioritizes the expressions + from top to bottom. Octal number require a starting "0" and the actual + number. Normal numbers start with a digit greater 0. And zero is finally a + special case. A single "0" is detected by the last rule of this set. And + valid ocal number is already being detected by the first rule. This even + includes multi "0" sequences that in octal notation also means zero. + Another way would be to only use two rules: + "0" [0-9]+ + "0" | ( [1-9] [0-9]* ) + A full description of re2c rule syntax can be found in the manual. +*/ + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#if _MSC_VER > 1200 +#define WINVER 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later. +#endif // Prevents warning from vc7.1 complaining about redefinition + +#include +#include +#include +#include +#include +#include "HiResTimer.h" + +static char gTestBuf[1000] = ""; + +/** + * @brief Setup HiResolution timer and confirm it is working ok + */ +void InitHiResTimerAndVerifyWorking(void) +{ + double elapsed; + HrtInit(); + HrtSetPriority(ABOVE_NORMAL_PRIORITY_CLASS); + HrtStart(); + Sleep(100); + elapsed = HrtElapsedMillis(); + if ((elapsed < 90) || (elapsed > 110)) { + printf("HiResTimer misbehaving: %f\n", elapsed); + exit(2); + } +} + +/** + * @brief Scan for numbers in different formats + */ +int ScanFullSpeed(char *pzStrToScan, size_t lenStrToScan) +{ + char *pzCurScanPos = pzStrToScan; + char *pzBacktrackInfo = 0; + #define YYCTYPE char + #define YYCURSOR pzCurScanPos + #define YYLIMIT (pzStrToScan+lenStrToScan) + #define YYMARKER pzBacktrackInfo + #define YYFILL(n) + + for(;;) + { +/*!re2c + re2c:indent:top = 2; + [1-9][0-9]* { continue; } + [0][0-9]+ { continue; } + "+" { continue; } + "-" { continue; } + "\000" { return 0; } + [^] { return 1; } +*/ + } +} + +/** + * @brief Scan for numbers in different formats + */ +int scan(char *pzStrToScan, size_t lenStrToScan) +{ + char *pzCurScanPos = pzStrToScan; + char *pzBacktrackInfo = 0; + #define YYCTYPE char + #define YYCURSOR pzCurScanPos + #define YYLIMIT (pzStrToScan+lenStrToScan) + #define YYMARKER pzBacktrackInfo + #define YYFILL(n) + + for(;;) + { +/*!re2c + re2c:indent:top = 2; + [1-9][0-9]* { printf("Num\n"); strcat(gTestBuf, "Num "); continue; } + [0][0-9]+ { printf("Oct\n"); strcat(gTestBuf, "Oct "); continue; } + "+" { printf("+\n"); strcat(gTestBuf, "+ "); continue; } + "-" { printf("-\n"); strcat(gTestBuf, "- "); continue; } + "\000" { printf("EOF\n"); return 0; } + [^] { printf("ERR\n"); strcat(gTestBuf, "ERR "); return 1; } +*/ + } +} + +/** + * @brief Show high resolution elapsed time for 10,000 and 100,000 loops + */ +void DoTimingsOfStrnCmp(void) +{ + char testStr[] = "Hello, world"; + int totLoops = 10000; + int totFoundCount = 0; + int foundCount = 0; + int loop; + int rc; + const int progressAnd = 0xFFFFF000; + double elapsed; + + printf("\n\n%d loops with * every %d loops to confirm\n", totLoops, ((~progressAnd) + 1)); + + HrtStart(); + for (loop = 0; loop < totLoops; ++loop) { + foundCount = 0; + rc = strncmp(testStr, "Hello", 5); + if (rc == 0) { + foundCount++; + totFoundCount++; + if ((totFoundCount & progressAnd) == totFoundCount) { + printf("*"); + } + } + } + elapsed = HrtElapsedMillis(); + printf("\nstrncmp Elapsed for %7d loops milliseconds: %7.3f\n", totLoops, elapsed); + printf("FoundCount each loop: %d\n", foundCount); + printf("TotalFoundCount for all loops: %d\n", totFoundCount); + + totLoops = 100000; + HrtStart(); + for (loop = 0; loop < totLoops; ++loop) { + foundCount = 0; + rc = strncmp(testStr, "Hello", 5); + if (rc == 0) { + foundCount++; + totFoundCount++; + if ((totFoundCount & progressAnd) == totFoundCount) { + printf("*"); + } + } + } + elapsed = HrtElapsedMillis(); + printf("\nstrncmp Elapsed for %7d loops milliseconds: %7.3f\n", totLoops, elapsed); + printf("FoundCount each loop: %d\n", foundCount); + printf("TotalFoundCount for all loops: %d\n", totFoundCount); +} + +/** + * @brief Show high resolution elapsed time for 10,000 and 100,000 loops + */ +void DoTimingsOfRe2c(void) +{ + char* testStrings[] = { "123", "1234", "+123", "01234", "-04321", "abc", "123abc" }; + const int testCount = sizeof(testStrings) / sizeof(testStrings[0]); + int i; + int totLoops = 10000 / testCount; // Doing more than one per loop + int totFoundCount = 0; + int foundCount = 0; + int loop; + int rc; + const int progressAnd = 0xFFFFF000; + double elapsed; + + printf("\n\n%d loops with * every %d loops to confirm\n", totLoops, ((~progressAnd) + 1)); + + HrtStart(); + for (loop = 0; loop < totLoops; ++loop) { + foundCount = 0; + strcpy(gTestBuf, ""); + for (i = 0; i < testCount; ++i) { + char* pzCurStr = testStrings[i]; + size_t len = strlen(pzCurStr); // Calc of strlen slows things down ... std::string? + rc = ScanFullSpeed(pzCurStr, len); + if (rc == 0) { + foundCount++; + totFoundCount++; + if ((totFoundCount & progressAnd) == totFoundCount) { + printf("*"); + } + } + } + } + elapsed = HrtElapsedMillis(); + printf("\nRe2c Elapsed for %7d loops milliseconds: %7.3f\n", totLoops, elapsed); + printf("FoundCount each loop: %d\n", foundCount); + printf("TotalFoundCount for all loops: %d\n", totFoundCount); + + totLoops = 100000 / testCount; + printf("\n\n%d loops with * every %d loops to confirm\n", totLoops, ((~progressAnd) + 1)); + + HrtStart(); + for (loop = 0; loop < totLoops; ++loop) { + foundCount = 0; + strcpy(gTestBuf, ""); + for (i = 0; i < testCount; ++i) { + char* pzCurStr = testStrings[i]; + size_t len = strlen(pzCurStr); // Calc of strlen slows things down ... std::string? + rc = ScanFullSpeed(pzCurStr, len); + if (rc == 0) { + foundCount++; + totFoundCount++; + if ((totFoundCount & progressAnd) == totFoundCount) { + printf("*"); + } + } + } + } + elapsed = HrtElapsedMillis(); + printf("\nRe2c Elapsed for %7d loops milliseconds: %7.3f\n", totLoops, elapsed); + printf("FoundCount each loop: %d\n", foundCount); + printf("TotalFoundCount for all loops: %d\n", totFoundCount); +} + +/** + * @brief Entry point for console app + */ +int main(int argc, char **argv) +{ + char testStr_A[] = "123"; + char* testStr_B = "456"; + char* testStrings[] = { "123", "1234", "+123", "01234", "-04321", "abc", "123abc" }; + const int testCount = sizeof(testStrings) / sizeof(testStrings[0]); + int i; + + int rc = scan(testStr_A, 3); + printf("rc: %d\n", rc); + + rc = scan(testStr_B, 3); + printf("rc: %d\n", rc); + + rc = scan("789", 3); + printf("rc: %d\n", rc); + + strcpy(gTestBuf, ""); + for (i = 0; i < testCount; ++i) { + char* pzCurStr = testStrings[i]; + size_t len = strlen(pzCurStr); + scan(pzCurStr, len); + } + printf("%s\n", gTestBuf); + rc = strcmp(gTestBuf, "Num Num + Num Oct - Oct ERR Num ERR "); + if (rc == 0) { + printf("Success\n"); + } + else { + printf("Failure\n"); + } + assert(0 == rc); // Doesn't work with Release build + + InitHiResTimerAndVerifyWorking(); + + DoTimingsOfStrnCmp(); + + DoTimingsOfRe2c(); + + return 0; +} diff --git a/lessons/002_strip_comments/readme.txt b/lessons/002_strip_comments/readme.txt index 535a4ea7..9805d20b 100755 --- a/lessons/002_strip_comments/readme.txt +++ b/lessons/002_strip_comments/readme.txt @@ -1,4 +1,4 @@ -re2c lesson_002, (c) M. Boerger 2006 +re2c lesson 002_strip_comments, (c) M. Boerger 2006 In this lesson you will learn how to use multiple scanner blocks and how to read the input from a file instead of a zero terminated string. In the end you @@ -10,4 +10,4 @@ The first scanner can be generated with: re2c -s -o t.c strip_001.s.re In the second step we will learn about YYMARKER that stores backtracking -information and YYCTXMARKER that is used for trailing contexts. \ No newline at end of file +information and YYCTXMARKER that is used for trailing contexts. diff --git a/lessons/002_strip_comments/strip_001.s.c b/lessons/002_strip_comments/strip_001.s.c index ad0d85b8..c4ff9274 100755 --- a/lessons/002_strip_comments/strip_001.s.c +++ b/lessons/002_strip_comments/strip_001.s.c @@ -1,6 +1,6 @@ /* Generated by re2c */ #line 1 "strip_001.s.re" -/* re2c lesson_002, strip_001.s, (c) M. Boerger 2006 */ +/* re2c lesson 002_strip_comments, strip_001.s, (c) M. Boerger 2006 */ #line 32 "strip_001.s.re" #include diff --git a/lessons/002_strip_comments/strip_001.s.re b/lessons/002_strip_comments/strip_001.s.re index cf09d5e2..ca735180 100755 --- a/lessons/002_strip_comments/strip_001.s.re +++ b/lessons/002_strip_comments/strip_001.s.re @@ -1,4 +1,4 @@ -/* re2c lesson_002, strip_001.s, (c) M. Boerger 2006 */ +/* re2c lesson 002_strip_comments, strip_001.s, (c) M. Boerger 2006 */ /*!ignore:re2c - basic interface for file reading diff --git a/lessons/002_strip_comments/strip_002.s.c b/lessons/002_strip_comments/strip_002.s.c index 63d103cd..b87912cf 100755 --- a/lessons/002_strip_comments/strip_002.s.c +++ b/lessons/002_strip_comments/strip_002.s.c @@ -1,6 +1,6 @@ /* Generated by re2c */ #line 1 "strip_002.s.re" -/* re2c lesson_002, strip_002.s, (c) M. Boerger 2006 */ +/* re2c lesson 002_strip_comments, strip_002.s, (c) M. Boerger 2006 */ #line 27 "strip_002.s.re" #include diff --git a/lessons/002_strip_comments/strip_002.s.re b/lessons/002_strip_comments/strip_002.s.re index 282f00d3..9422005f 100755 --- a/lessons/002_strip_comments/strip_002.s.re +++ b/lessons/002_strip_comments/strip_002.s.re @@ -1,4 +1,4 @@ -/* re2c lesson_002, strip_002.s, (c) M. Boerger 2006 */ +/* re2c lesson 002_strip_comments, strip_002.s, (c) M. Boerger 2006 */ /*!ignore:re2c - complexity diff --git a/lessons/readme.txt b/lessons/readme.txt new file mode 100755 index 00000000..2d26179c --- /dev/null +++ b/lessons/readme.txt @@ -0,0 +1,20 @@ +re2c lessons, (c) M. Boerger 2006 + +001_upn_calculator + + This lesson gets you started with re2c. In the end you will have an easy UPN + calculator for use at command line. + + You will learn about the basic interface of re2c when scanning input strings. + How to detect the end of the input and use that to stop scanning in order to + avoid problems. + + The lesson also contains a windows subdirectory to get you started in the + Microsoft world. + +002_strip_comments + + In this lesson you will learn how to use multiple scanner blocks and how to + read the input from a file instead of a zero terminated string. In the end you + will have a scanner that filters comments out of c source files but keeps re2c + comments.