Compare commits

..
Author SHA1 Message Date
Clifford Yapp e5a4784140 libnmg is separated in trunk now (svn branch delete)
svn:revision:69558
svn:branch:libnmg
svn:account:starseeker
2017-03-23 21:49:20 +00:00
Clifford Yapp 6ac17b25a5 Sync with trunk thru r68369
svn:revision:68372
svn:branch:libnmg
svn:account:starseeker
2016-07-19 17:08:57 +00:00
Clifford Yapp 565e5e0242 osl isn't really a proper src/other directory, and it's not currently active - put it in misc instead.
svn:revision:68369
svn:branch:trunk
svn:account:starseeker
2016-07-19 15:09:45 +00:00
Clifford Yapp 867d2b87d3 Strip down re2c directory.
svn:revision:68367
svn:branch:trunk
svn:account:starseeker
2016-07-19 02:39:44 +00:00
Clifford Yapp ef73c17b95 Except for the core Tcl/Tk packages and incrtcl extensions, remove more unnecessary files. The Tcl/Tk 8.6 upgrade will be the place to handle the former. Also not working on stepcode yet - we need to get re-synced with upstream first. That should be on the short list now that we've RELEASE branched for 7.26.0...
svn:revision:68366
svn:branch:trunk
svn:account:starseeker
2016-07-19 02:26:08 +00:00
Clifford Yapp 07d3ec5ae1 tweaks to src/other/CMakeLists.txt
svn:revision:68365
svn:branch:trunk
svn:account:starseeker
2016-07-19 02:12:06 +00:00
Clifford Yapp 01629532c8 update libpng dist file
svn:revision:68364
svn:branch:trunk
svn:account:starseeker
2016-07-19 02:11:40 +00:00
Clifford Yapp ad97489d26 Update dist file
svn:revision:68363
svn:branch:trunk
svn:account:starseeker
2016-07-19 02:11:16 +00:00
Clifford Yapp e4b5e8ebcb minimize libutahrle contents. while we're at it, clean up the CMakeLists.txt file
svn:revision:68362
svn:branch:trunk
svn:account:starseeker
2016-07-19 02:09:37 +00:00
Clifford Yapp 43d5886fef Remove old Makefile.am
svn:revision:68361
svn:branch:trunk
svn:account:starseeker
2016-07-19 01:48:29 +00:00
Clifford Yapp 86b559a5da strip libpng down to its minimal contents.
svn:revision:68360
svn:branch:trunk
svn:account:starseeker
2016-07-19 01:47:24 +00:00
Clifford Yapp 0ab871f46a Update to libpng 1.6.23. There have been significant CMake changes upstream - needs testing. So far, applied two minimal changes.
svn:revision:68359
svn:branch:trunk
svn:account:starseeker
2016-07-19 01:34:15 +00:00
Clifford Yapp eb8ef3c631 Strip down freetype directories to the minimum needed.
svn:revision:68358
svn:branch:trunk
svn:account:starseeker
2016-07-19 01:08:22 +00:00
Clifford Yapp 8465475f78 Update freetype to version 2.6.5 - adapted changes from earlier freetype CMake to current version, but needs testing.
svn:revision:68357
svn:branch:trunk
svn:account:starseeker
2016-07-19 00:46:26 +00:00
Clifford Yapp 08790a882e Remainder of changes needed for zlib 1.2.8 upgrade. Should be noted that per zlib site, 1.2.8 fixes a very rare bug in decompression.
svn:revision:68356
svn:branch:trunk
svn:account:starseeker
2016-07-19 00:06:21 +00:00
Clifford Yapp 00b6fe5031 Strip our zlib copy down to the minimum
svn:revision:68355
svn:branch:trunk
svn:account:starseeker
2016-07-18 23:58:42 +00:00
Clifford Yapp 434cabae66 Re-apply CMake and zconf simplifications
svn:revision:68354
svn:branch:trunk
svn:account:starseeker
2016-07-18 23:49:38 +00:00
Clifford Yapp f8c2dde741 Upgrade zlib to vanilla 1.2.8. Need to re-apply some changes, but first checkpoint the unmodified original.
svn:revision:68353
svn:branch:trunk
svn:account:starseeker
2016-07-18 23:35:11 +00:00
Clifford Yapp c8039f0a9d Make a note of the predef wiki on sourceforge.
svn:revision:68348
svn:branch:trunk
svn:account:starseeker
2016-07-18 16:03:32 +00:00
Clifford Yapp 12f694d220 Convert dashes to underscores while we're at it.
svn:revision:68326
svn:branch:trunk
svn:account:starseeker
2016-07-15 20:09:30 +00:00
Clifford Yapp 811b1f1848 Add support for skipping files
svn:revision:68325
svn:branch:trunk
svn:account:starseeker
2016-07-15 19:58:52 +00:00
Clifford Yapp d187b321d8 more rework
svn:revision:68324
svn:branch:trunk
svn:account:starseeker
2016-07-15 19:25:31 +00:00
Clifford Yapp cfaa401d57 Adjust flag checking, support both local and recursive scanning.
svn:revision:68323
svn:branch:trunk
svn:account:starseeker
2016-07-15 19:01:50 +00:00
Clifford Yapp 64a43c3ce7 Fix some headers whose guards didn't match convention after getting moved around.
svn:revision:68322
svn:branch:trunk
svn:account:starseeker
2016-07-15 18:45:55 +00:00
Clifford Yapp b25cbfa7ab Simplify header guard regex now that we're using unifdef
svn:revision:68321
svn:branch:trunk
svn:account:starseeker
2016-07-15 18:33:36 +00:00
Clifford Yapp 2f6763d30b fix unmatched endif
svn:revision:68320
svn:branch:trunk
svn:account:starseeker
2016-07-15 18:30:00 +00:00
Clifford Yapp 983520a1d9 Check for zero length lists before operating on them.
svn:revision:68319
svn:branch:trunk
svn:account:starseeker
2016-07-15 18:19:38 +00:00
Clifford Yapp 93177e87ad Use unifdef to extract the conditional preprocessor symbols out of source files, rather than attempting to hack it together ourselves in CMake. If this ends up being something we want to make a built-in capability unifdef is BSD licensed and has been ported to Windows.
svn:revision:68318
svn:branch:trunk
svn:account:starseeker
2016-07-15 18:02:49 +00:00
Clifford Yapp c65f295e3c Add more OS flags to ignore from Tcl - there's probably more, but this is a start...
svn:revision:68317
svn:branch:trunk
svn:account:starseeker
2016-07-15 15:53:25 +00:00
Clifford Yapp b0842b1718 Sync with trunk thru r68300
svn:revision:68313
svn:branch:libnmg
svn:account:starseeker
2016-07-14 19:18:49 +00:00
Clifford Yapp be6e927ae7 Add a couple missing include dir entries that were exposed by taking the tcl entry out of libbu
svn:revision:68310
svn:branch:trunk
svn:account:starseeker
2016-07-14 18:45:19 +00:00
Clifford Yapp 72bd5645aa Shouldn't need or use tcl includes in libbu any longer.
svn:revision:68306
svn:branch:trunk
svn:account:starseeker
2016-07-14 18:01:06 +00:00
Clifford Yapp c5f2a7cd94 Since we've got the RELEASE branch, go ahead and move the binary_attribute work into trunk under the CMake option BRLCAD_ENABLE_BINARY_ATTRIBUTES. Untested, but it looks like test_binary_attributes.c was a stub in the branch as well...
svn:revision:68289
svn:branch:trunk
svn:account:starseeker
2016-07-14 00:21:59 +00:00
Clifford Yapp a569144fb7 Add an UNDOCUMENTED flag to the ThirdParty macro, so we can add src/other logic for dev projects without forcing updates to INSTALL and configure.
svn:revision:68288
svn:branch:trunk
svn:account:starseeker
2016-07-13 23:48:50 +00:00
Clifford Yapp 362966205f Since the gecode work essentially consists of a few early experiments, there's not really any point in keeping the whole branch just for those files. gecode itself would need to be upgraded anyway, so just fold the essential bits into trunk under an if test. Not worth checking in gecode to src/other yet.
svn:revision:68286
svn:branch:trunk
svn:account:starseeker
2016-07-13 23:31:50 +00:00
Clifford Yapp c967eee423 Looks like the binary attributes bits in attributes.c were moved over a while back, but not synced with the latest changes from the branch.
svn:revision:68284
svn:branch:trunk
svn:account:starseeker
2016-07-13 22:50:15 +00:00
Jonathan Engbert 65b130a0e9 remove rt includes and separate rt-dependent code (in progress)
svn:revision:66876
svn:branch:libnmg
svn:account:ejno
2016-01-14 15:31:21 +00:00
Jonathan Engbert fbd958f453 remove rt includes and separate rt-dependent code (in progress) (preliminary file move commit) 2016-01-14 15:31:21 +00:00
Jonathan Engbert 0059765062 create a branch for work on extracting NMG to a library
svn:revision:66875
svn:branch:libnmg
svn:account:ejno
2016-01-14 15:07:18 +00:00
1975 changed files with 80423 additions and 660670 deletions
+7
View File
@@ -1134,6 +1134,13 @@ endif(BRLCAD_ENABLE_OPENCL)
option(BRLCAD_ENABLE_SPR "Enable features requiring Screened Poisson Surface Reconstruction" OFF)
mark_as_advanced(BRLCAD_ENABLE_SPR)
# Enable experimental support for binary attributes
option(BRLCAD_ENABLE_BINARY_ATTRIBUTES "Enable support for binary attributes" OFF)
mark_as_advanced(BRLCAD_ENABLE_BINARY_ATTRIBUTES)
if(BRLCAD_ENABLE_BINARY_ATTRIBUTES)
CONFIG_H_APPEND(BRLCAD "#define USE_BINARY_ATTRIBUTES 1\n")
endif(BRLCAD_ENABLE_BINARY_ATTRIBUTES)
#----------------------------------------------------------------------
# The following are fine-grained options for enabling/disabling compiler
# and source code definition settings. Typically these are set to
-9
View File
@@ -722,15 +722,6 @@ version if BRLCAD_BUNDLED_LIBS is also AUTO.
Aliases: ENABLE_SPR
--- BRLCAD_BSON ---
Option for enabling and disabling compilation of the Libbson library
provided with BRL-CAD's source code. Default is BUNDLED, using
the included other/src version.
Aliases: ENABLE_BSON
--- BRLCAD_SC ---
Option for enabling and disabling compilation of the NIST Step Class
+2
View File
@@ -13,6 +13,8 @@ changes made. See document footer for additional details.
--- 2016-07-XX Release 7.26.2 ---
----------------------------------------------------------------------
* upgraded freetype to version 2.6.5 - Cliff Yapp
* upgraded zlib to version 1.2.8 - Cliff Yapp
----------------------------------------------------------------------
+3
View File
@@ -1494,6 +1494,9 @@ ARCHER
ATTRIBUTES
----------
* See src/libbu/TODO.binary_attributes for more info about
bson based binary attribute work.
* attr command option to output to a file
* attr command change to only output non-standard attributes
Vendored
-4
View File
@@ -190,10 +190,6 @@ do
shift;;
--disable-spr) options="$options -DBRLCAD_SPR=SYSTEM";
shift;;
--enable-bson) options="$options -DBRLCAD_BSON=BUNDLED";
shift;;
--disable-bson) options="$options -DBRLCAD_BSON=SYSTEM";
shift;;
--enable-scl) options="$options -DBRLCAD_SC=BUNDLED";
shift;;
--disable-scl) options="$options -DBRLCAD_SC=SYSTEM";
@@ -3,6 +3,8 @@ set(specifications_EN
)
ADD_DOCBOOK("HTML;PHP;PDF" specifications_EN specifications/en "")
CMAKEFILES(BRL_CAD_g_format_V6.xml)
# Local Variables:
# tab-width: 8
# mode: cmake
+3 -3
View File
@@ -44,8 +44,8 @@
/** @file bg.h */
/** @} */
#ifndef GM_H
#define GM_H
#ifndef BG_H
#define BG_H
#include "common.h"
@@ -56,7 +56,7 @@
#include "bg/tri_ray.h"
#include "bg/tri_tri.h"
#endif /* GM_H */
#endif /* BG_H */
/*
* Local Variables:
+3 -3
View File
@@ -18,8 +18,8 @@
* information.
*/
#ifndef DVEC_H
#define DVEC_H
#ifndef BN_DVEC_H
#define BN_DVEC_H
#include "common.h"
@@ -207,7 +207,7 @@ extern "C++" {
/** @} */
#endif /* DVEC_H */
#endif /* BN_DVEC_H */
/*
* Local Variables:
+3 -3
View File
@@ -30,8 +30,8 @@
/** @{ */
/** @file plot3.h */
#ifndef PLOT3_H
#define PLOT3_H
#ifndef BN_PLOT3_H
#define BN_PLOT3_H
#include "common.h"
@@ -484,7 +484,7 @@ BN_EXPORT extern void BU_FORTRAN(f3vect, F3VECT)(FILE **fp,
__END_DECLS
#endif /* PLOT3_H */
#endif /* BN_PLOT3_H */
/** @} */
/*
+3 -3
View File
@@ -26,8 +26,8 @@
/** @{ */
/** @file spm.h */
#ifndef SPM_H
#define SPM_H
#ifndef BN_SPM_H
#define BN_SPM_H
#include "common.h"
#include "bn/defines.h"
@@ -135,7 +135,7 @@ BN_EXPORT extern void bn_spm_dump(bn_spm_map_t *mp, int verbose);
__END_DECLS
#endif /* SPM_H */
#endif /* BN_SPM_H */
/** @} */
/*
+4 -4
View File
@@ -25,14 +25,14 @@
#include <stddef.h> /* for size_t */
#if defined(USE_BINARY_ATTRIBUTES)
# include "bson.h"
#endif
#include "bu/defines.h"
#include "bu/magic.h"
#include "bu/vls.h"
#if defined(USE_BINARY_ATTRIBUTES)
#include "bson.h"
#endif
__BEGIN_DECLS
/*----------------------------------------------------------------------*/
+3 -3
View File
@@ -29,8 +29,8 @@
* example).
*
*/
#ifndef BVIEW_H
#define BVIEW_H
#ifndef DM_BVIEW_H
#define DM_BVIEW_H
#include "common.h"
#include "bu/list.h"
@@ -312,7 +312,7 @@ struct view_obj {
};
#define VIEW_OBJ_NULL ((struct view_obj *)0)
#endif /* BVIEW_H */
#endif /* DM_BVIEW_H */
/** @} */
/*
+4 -1
View File
@@ -25,6 +25,9 @@
*
*/
#ifndef DM_DM_DESIGN_H
#define DM_DM_DESIGN_H
/* Display Manager Types */
#define DM_TYPE_BAD -1
#define DM_TYPE_NULL 0
@@ -201,7 +204,7 @@ DM_EXPORT extern int dm_set_type(dm_s *dmp, int dm_t);
DM_EXPORT extern int dm_get_image(dm_s *dmp, icv_image_t *image);
DM_EXPORT extern int dm_get_obj_image(dm_s *dmp, const char *handle, icv_image_t *image);
#endif /* DM_H */
#endif /* DM_DM_DESIGN_H */
/** @} */
/*
+3 -3
View File
@@ -22,8 +22,8 @@
/** @file dm_xvars.h
*
*/
#ifndef DM_XVARS_H
#define DM_XVARS_H
#ifndef DM_DM_XVARS_H
#define DM_DM_XVARS_H
#include "common.h"
@@ -83,7 +83,7 @@ struct dm_xvars {
int devbuttonrelease;
};
#endif /* DM_XVARS_H */
#endif /* DM_DM_XVARS_H */
/** @} */
/*
* Local Variables:
+50 -57
View File
@@ -33,15 +33,16 @@
#ifndef NMG_H
#define NMG_H
#include "common.h"
/* interface headers */
#include "bu/list.h"
#include "bu/log.h"
#include "bu/magic.h"
#include "bu/ptbl.h"
#include "vmath.h"
#define DEBUG_PL_ANIM 0x00000001 /**< @brief 1 mged: animated evaluation */
#define DEBUG_PL_SLOW 0x00000002 /**< @brief 2 mged: add delays to animation */
#define DEBUG_GRAPHCL 0x00000004 /**< @brief 3 mged: graphic classification */
@@ -513,18 +514,6 @@ struct vertexuse_a_cnurb {
long index; /**< @brief struct # in this model */
};
/**
* storage allocation support
* OBSOLETE
*/
#define NMG_GETSTRUCT(p, str) BU_GET(p, struct str)
/**
* storage de-allocation support
* OBSOLETE
*/
#define NMG_FREESTRUCT(ptr, str) BU_PUT(ptr, struct str)
/*
* Macros to create and destroy storage for the NMG data structures.
@@ -537,52 +526,52 @@ struct vertexuse_a_cnurb {
NMG_CK_MODEL(_m); (_p)->index = ((_m)->maxindex)++
#define GET_MODEL(p, m) {NMG_GETSTRUCT(p, model); NMG_INCR_INDEX(p, m);}
#define GET_REGION(p, m) {NMG_GETSTRUCT(p, nmgregion); NMG_INCR_INDEX(p, m);}
#define GET_REGION_A(p, m) {NMG_GETSTRUCT(p, nmgregion_a); NMG_INCR_INDEX(p, m);}
#define GET_SHELL(p, m) {NMG_GETSTRUCT(p, shell); NMG_INCR_INDEX(p, m);}
#define GET_SHELL_A(p, m) {NMG_GETSTRUCT(p, shell_a); NMG_INCR_INDEX(p, m);}
#define GET_FACE(p, m) {NMG_GETSTRUCT(p, face); NMG_INCR_INDEX(p, m);}
#define GET_FACE_G_PLANE(p, m) {NMG_GETSTRUCT(p, face_g_plane); NMG_INCR_INDEX(p, m);}
#define GET_FACE_G_SNURB(p, m) {NMG_GETSTRUCT(p, face_g_snurb); NMG_INCR_INDEX(p, m);}
#define GET_FACEUSE(p, m) {NMG_GETSTRUCT(p, faceuse); NMG_INCR_INDEX(p, m);}
#define GET_LOOP(p, m) {NMG_GETSTRUCT(p, loop); NMG_INCR_INDEX(p, m);}
#define GET_LOOP_G(p, m) {NMG_GETSTRUCT(p, loop_g); NMG_INCR_INDEX(p, m);}
#define GET_LOOPUSE(p, m) {NMG_GETSTRUCT(p, loopuse); NMG_INCR_INDEX(p, m);}
#define GET_LOOPUSE_A(p, m) {NMG_GETSTRUCT(p, loopuse_a); NMG_INCR_INDEX(p, m);}
#define GET_EDGE(p, m) {NMG_GETSTRUCT(p, edge); NMG_INCR_INDEX(p, m);}
#define GET_EDGE_G_LSEG(p, m) {NMG_GETSTRUCT(p, edge_g_lseg); NMG_INCR_INDEX(p, m);}
#define GET_EDGE_G_CNURB(p, m) {NMG_GETSTRUCT(p, edge_g_cnurb); NMG_INCR_INDEX(p, m);}
#define GET_EDGEUSE(p, m) {NMG_GETSTRUCT(p, edgeuse); NMG_INCR_INDEX(p, m);}
#define GET_VERTEX(p, m) {NMG_GETSTRUCT(p, vertex); NMG_INCR_INDEX(p, m);}
#define GET_VERTEX_G(p, m) {NMG_GETSTRUCT(p, vertex_g); NMG_INCR_INDEX(p, m);}
#define GET_VERTEXUSE(p, m) {NMG_GETSTRUCT(p, vertexuse); NMG_INCR_INDEX(p, m);}
#define GET_VERTEXUSE_A_PLANE(p, m) {NMG_GETSTRUCT(p, vertexuse_a_plane); NMG_INCR_INDEX(p, m);}
#define GET_VERTEXUSE_A_CNURB(p, m) {NMG_GETSTRUCT(p, vertexuse_a_cnurb); NMG_INCR_INDEX(p, m);}
#define GET_MODEL(p, m) {BU_GET(p, struct model); NMG_INCR_INDEX(p, m);}
#define GET_REGION(p, m) {BU_GET(p, struct nmgregion); NMG_INCR_INDEX(p, m);}
#define GET_REGION_A(p, m) {BU_GET(p, struct nmgregion_a); NMG_INCR_INDEX(p, m);}
#define GET_SHELL(p, m) {BU_GET(p, struct shell); NMG_INCR_INDEX(p, m);}
#define GET_SHELL_A(p, m) {BU_GET(p, struct shell_a); NMG_INCR_INDEX(p, m);}
#define GET_FACE(p, m) {BU_GET(p, struct face); NMG_INCR_INDEX(p, m);}
#define GET_FACE_G_PLANE(p, m) {BU_GET(p, struct face_g_plane); NMG_INCR_INDEX(p, m);}
#define GET_FACE_G_SNURB(p, m) {BU_GET(p, struct face_g_snurb); NMG_INCR_INDEX(p, m);}
#define GET_FACEUSE(p, m) {BU_GET(p, struct faceuse); NMG_INCR_INDEX(p, m);}
#define GET_LOOP(p, m) {BU_GET(p, struct loop); NMG_INCR_INDEX(p, m);}
#define GET_LOOP_G(p, m) {BU_GET(p, struct loop_g); NMG_INCR_INDEX(p, m);}
#define GET_LOOPUSE(p, m) {BU_GET(p, struct loopuse); NMG_INCR_INDEX(p, m);}
#define GET_LOOPUSE_A(p, m) {BU_GET(p, struct loopuse_a); NMG_INCR_INDEX(p, m);}
#define GET_EDGE(p, m) {BU_GET(p, struct edge); NMG_INCR_INDEX(p, m);}
#define GET_EDGE_G_LSEG(p, m) {BU_GET(p, struct edge_g_lseg); NMG_INCR_INDEX(p, m);}
#define GET_EDGE_G_CNURB(p, m) {BU_GET(p, struct edge_g_cnurb); NMG_INCR_INDEX(p, m);}
#define GET_EDGEUSE(p, m) {BU_GET(p, struct edgeuse); NMG_INCR_INDEX(p, m);}
#define GET_VERTEX(p, m) {BU_GET(p, struct vertex); NMG_INCR_INDEX(p, m);}
#define GET_VERTEX_G(p, m) {BU_GET(p, struct vertex_g); NMG_INCR_INDEX(p, m);}
#define GET_VERTEXUSE(p, m) {BU_GET(p, struct vertexuse); NMG_INCR_INDEX(p, m);}
#define GET_VERTEXUSE_A_PLANE(p, m) {BU_GET(p, struct vertexuse_a_plane); NMG_INCR_INDEX(p, m);}
#define GET_VERTEXUSE_A_CNURB(p, m) {BU_GET(p, struct vertexuse_a_cnurb); NMG_INCR_INDEX(p, m);}
#define FREE_MODEL(p) NMG_FREESTRUCT(p, model)
#define FREE_REGION(p) NMG_FREESTRUCT(p, nmgregion)
#define FREE_REGION_A(p) NMG_FREESTRUCT(p, nmgregion_a)
#define FREE_SHELL(p) NMG_FREESTRUCT(p, shell)
#define FREE_SHELL_A(p) NMG_FREESTRUCT(p, shell_a)
#define FREE_FACE(p) NMG_FREESTRUCT(p, face)
#define FREE_FACE_G_PLANE(p) NMG_FREESTRUCT(p, face_g_plane)
#define FREE_FACE_G_SNURB(p) NMG_FREESTRUCT(p, face_g_snurb)
#define FREE_FACEUSE(p) NMG_FREESTRUCT(p, faceuse)
#define FREE_LOOP(p) NMG_FREESTRUCT(p, loop)
#define FREE_LOOP_G(p) NMG_FREESTRUCT(p, loop_g)
#define FREE_LOOPUSE(p) NMG_FREESTRUCT(p, loopuse)
#define FREE_LOOPUSE_A(p) NMG_FREESTRUCT(p, loopuse_a)
#define FREE_EDGE(p) NMG_FREESTRUCT(p, edge)
#define FREE_EDGE_G_LSEG(p) NMG_FREESTRUCT(p, edge_g_lseg)
#define FREE_EDGE_G_CNURB(p) NMG_FREESTRUCT(p, edge_g_cnurb)
#define FREE_EDGEUSE(p) NMG_FREESTRUCT(p, edgeuse)
#define FREE_VERTEX(p) NMG_FREESTRUCT(p, vertex)
#define FREE_VERTEX_G(p) NMG_FREESTRUCT(p, vertex_g)
#define FREE_VERTEXUSE(p) NMG_FREESTRUCT(p, vertexuse)
#define FREE_VERTEXUSE_A_PLANE(p) NMG_FREESTRUCT(p, vertexuse_a_plane)
#define FREE_VERTEXUSE_A_CNURB(p) NMG_FREESTRUCT(p, vertexuse_a_cnurb)
#define FREE_MODEL(p) BU_PUT(p, struct model)
#define FREE_REGION(p) BU_PUT(p, struct nmgregion)
#define FREE_REGION_A(p) BU_PUT(p, struct nmgregion_a)
#define FREE_SHELL(p) BU_PUT(p, struct shell)
#define FREE_SHELL_A(p) BU_PUT(p, struct shell_a)
#define FREE_FACE(p) BU_PUT(p, struct face)
#define FREE_FACE_G_PLANE(p) BU_PUT(p, struct face_g_plane)
#define FREE_FACE_G_SNURB(p) BU_PUT(p, struct face_g_snurb)
#define FREE_FACEUSE(p) BU_PUT(p, struct faceuse)
#define FREE_LOOP(p) BU_PUT(p, struct loop)
#define FREE_LOOP_G(p) BU_PUT(p, struct loop_g)
#define FREE_LOOPUSE(p) BU_PUT(p, struct loopuse)
#define FREE_LOOPUSE_A(p) BU_PUT(p, struct loopuse_a)
#define FREE_EDGE(p) BU_PUT(p, struct edge)
#define FREE_EDGE_G_LSEG(p) BU_PUT(p, struct edge_g_lseg)
#define FREE_EDGE_G_CNURB(p) BU_PUT(p, struct edge_g_cnurb)
#define FREE_EDGEUSE(p) BU_PUT(p, struct edgeuse)
#define FREE_VERTEX(p) BU_PUT(p, struct vertex)
#define FREE_VERTEX_G(p) BU_PUT(p, struct vertex_g)
#define FREE_VERTEXUSE(p) BU_PUT(p, struct vertexuse)
#define FREE_VERTEXUSE_A_PLANE(p) BU_PUT(p, struct vertexuse_a_plane)
#define FREE_VERTEXUSE_A_CNURB(p) BU_PUT(p, struct vertexuse_a_cnurb)
/**
@@ -779,6 +768,10 @@ struct nmg_visit_handlers {
void (*vis_vertex_g)(uint32_t *, void *, int);
};
extern int nmg_debug;
#endif /* NMG_H */
/** @} */
+1523
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -26,8 +26,8 @@
*
*/
#ifndef LIGHT_H
#define LIGHT_H
#ifndef OPTICAL_LIGHT_H
#define OPTICAL_LIGHT_H
#include "common.h"
@@ -90,7 +90,7 @@ OPTICAL_EXPORT extern void light_obs(struct application *ap, struct shadework *s
__END_DECLS
#endif /* LIGHT_H */
#endif /* OPTICAL_LIGHT_H */
/** @} */
/*
+3 -3
View File
@@ -22,8 +22,8 @@
/** @file plastic.h
*
*/
#ifndef PLASTIC_H
#define PLASTIC_H
#ifndef OPTICAL_PLASTIC_H
#define OPTICAL_PLASTIC_H
#define PL_NULL ((struct phong_specific *)0)
#define PL_O(m) offsetof(struct phong_specific, m)
@@ -43,7 +43,7 @@ struct phong_specific {
};
extern struct bu_structparse phong_parse[];
#endif
#endif /* OPTICAL_PLASTIC_H */
/** @} */
/*
* Local Variables:
+3 -3
View File
@@ -23,8 +23,8 @@
*
*/
#ifndef SHADEFUNCS_H
#define SHADEFUNCS_H
#ifndef OPTICAL_SHADEFUNCS_H
#define OPTICAL_SHADEFUNCS_H
#include "common.h"
@@ -96,7 +96,7 @@ OPTICAL_EXPORT extern struct mfuncs *load_dynamic_shader(const char *material);
__END_DECLS
#endif /* SHADEFUNCS_H */
#endif /* OPTICAL_SHADEFUNCS_H */
/** @} */
+3 -3
View File
@@ -23,8 +23,8 @@
*
*/
#ifndef SHADEWORK_H
#define SHADEWORK_H
#ifndef OPTICAL_SHADEWORK_H
#define OPTICAL_SHADEWORK_H
#include "common.h"
#include "bn/tabdata.h"
@@ -76,7 +76,7 @@ extern void pr_shadework(const char *str, const struct shadework *swp);
__END_DECLS
#endif /* SHADEWORK_H */
#endif /* OPTICAL_SHADEWORK_H */
/** @} */
/*
+3 -3
View File
@@ -26,8 +26,8 @@
*
*/
#ifndef ARB_EDIT_H
#define ARB_EDIT_H
#ifndef RT_ARB_EDIT_H
#define RT_ARB_EDIT_H
#include "common.h"
#include "bn.h"
@@ -441,7 +441,7 @@ arb_edit(struct rt_arb_internal *arb, fastf_t peqn[7][4], int edge, int newedge,
__END_DECLS
#endif /* ARB_EDIT_H */
#endif /* RT_ARB_EDIT_H */
/** @} */
/*
+3 -3
View File
@@ -61,8 +61,8 @@
*
*/
#ifndef DB_H
#define DB_H
#ifndef RT_DB4_H
#define RT_DB4_H
#include "common.h"
@@ -489,7 +489,7 @@ DEPRECATED void rt_dbmat_mat(dbfloat_t *dbp, const fastf_t *ff);
__END_DECLS
#endif /* DB_H */
#endif /* RT_DB4_H */
/** @} */
/*
+3 -3
View File
@@ -26,8 +26,8 @@
*
*/
#ifndef DB5_H
#define DB5_H
#ifndef RT_DB5_H
#define RT_DB5_H
#include "common.h"
@@ -231,7 +231,7 @@ RT_EXPORT extern const unsigned char *db5_get_raw_internal_ptr(struct db5_raw_in
__END_DECLS
#endif /* DB5_H */
#endif /* RT_DB5_H */
/** @} */
/*
+3 -3
View File
@@ -27,8 +27,8 @@
* this message goes away.
*
*/
#ifndef RTFUNC_H
#define RTFUNC_H
#ifndef RT_FUNC_H
#define RT_FUNC_H
#include "common.h"
@@ -179,7 +179,7 @@ RT_EXPORT extern int rt_obj_mirror(struct rt_db_internal *ip, const plane_t *pla
__END_DECLS
#endif /* RTFUNC_H */
#endif /* RT_FUNC_H */
/** @} */
+3 -3
View File
@@ -28,8 +28,8 @@
*
*/
#ifndef NURB_H
#define NURB_H
#ifndef RT_NURB_H
#define RT_NURB_H
#include "common.h"
@@ -284,7 +284,7 @@ RT_EXPORT extern void rt_nurb_map_oslo(struct oslo_mat *oslo,
__END_DECLS
#endif /* NURB_H */
#endif /* RT_NURB_H */
/** @} */
/*
+3 -3
View File
@@ -22,8 +22,8 @@
*
*/
#ifndef TIE_H
#define TIE_H
#ifndef RT_TIE_H
#define RT_TIE_H
#include "common.h"
@@ -154,7 +154,7 @@ RT_EXPORT extern void TIE_VAL(tie_push)(struct tie_s *tie, TIE_3 **tlist, unsign
__END_DECLS
#endif /* TIE_H */
#endif /* RT_TIE_H */
/*
* Local Variables:
+94
View File
@@ -0,0 +1,94 @@
# From https://github.com/mongodb/mongo-c-driver/blob/master/build/cmake/FindBSON.cmake
# License: Apache License Version 2.0, January 2004
# Read-Only variables:
# BSON_FOUND - system has the BSON library
# BSON_INCLUDE_DIR - the BSON include directory
# BSON_LIBRARIES - The libraries needed to use BSON
# BSON_VERSION - This is set to $major.$minor.$revision$path (eg. 0.4.1)
if (UNIX)
find_package(PkgConfig QUIET)
pkg_check_modules(_BSON QUIET libbson-1.0)
endif ()
find_path(BSON_INCLUDE_DIR
NAMES
libbson-1.0/bson.h
HINTS
${BSON_ROOT_DIR}
${_BSON_INCLUDEDIR}
PATH_SUFFIXES
include
)
set(BSON_INCLUDE_DIR "${BSON_INCLUDE_DIR}/libbson-1.0")
if(WIN32 AND NOT CYGWIN)
if(MSVC)
find_library(BSON
NAMES
"bson-1.0"
HINTS
${BSON_ROOT_DIR}
PATH_SUFFIXES
bin
lib
)
mark_as_advanced(BSON)
set(BSON_LIBRARIES ${BSON} ws2_32)
else()
# bother supporting this?
endif()
else()
find_library(BSON_LIBRARY
NAMES
bson-1.0
HINTS
${_BSON_LIBDIR}
PATH_SUFFIXES
lib
)
mark_as_advanced(BSON_LIBRARY)
find_package (Threads REQUIRED)
set(BSON_LIBRARIES ${BSON_LIBRARY} ${CMAKE_THREAD_LIBS_INIT})
endif()
if (BSON_INCLUDE_DIR)
if (_BSON_VERSION)
set(BSON_VERSION "${_BSON_VERSION}")
elseif(BSON_INCLUDE_DIR AND EXISTS "${BSON_INCLUDE_DIR}/bson-version.h")
file(STRINGS "${BSON_INCLUDE_DIR}/bson-version.h" bson_version_str
REGEX "^#define[\t ]+BSON_VERSION[\t ]+\([0-9.]+\)[\t ]+$")
string(REGEX REPLACE "^.*BSON_VERSION[\t ]+\([0-9.]+\)[\t ]+$"
"\\1" BSON_VERSION "${bson_version_str}")
endif ()
endif ()
include(FindPackageHandleStandardArgs)
if (BSON_VERSION)
find_package_handle_standard_args(BSON
REQUIRED_VARS
BSON_LIBRARIES
BSON_INCLUDE_DIR
VERSION_VAR
BSON_VERSION
FAIL_MESSAGE
"Could NOT find BSON version"
)
else ()
find_package_handle_standard_args(BSON "Could NOT find BSON"
BSON_LIBRARIES
BSON_INCLUDE_DIR
)
endif ()
mark_as_advanced(BSON_INCLUDE_DIR BSON_LIBRARIES)
+100
View File
@@ -0,0 +1,100 @@
# F I N D G E C O D E . C M A K E
# BRL-CAD
#
# Copyright (c) 2011-2014 United States Government as represented by
# the U.S. Army Research Laboratory.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. 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.
#
# 3. The name of the author may not be used to endorse or promote
# products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
#
###
# - Find Gecode constraint programming libraries
#
# The following variables are set:
#
# GECODE_INCLUDE_DIR
# GECODE_LIBRARIES
find_path(GECODE_INCLUDE_DIR gecode/search.hh)
find_library(GECODE_SUPPORT_LIB NAMES gecodesupport)
find_library(GECODE_KERNEL_LIB NAMES gecodekernel)
find_library(GECODE_SEARCH_LIB NAMES gecodesearch)
find_library(GECODE_INT_LIB NAMES gecodeint)
find_library(GECODE_SET_LIB NAMES gecodeset)
find_library(GECODE_FLOAT_LIB NAMES gecodefloat)
find_library(GECODE_MINIMODEL_LIB NAMES gecodeminimodel)
find_library(GECODE_DRIVER_LIB NAMES gecodedriver)
find_library(GECODE_FLATZINC_LIB NAMES gecodeflatzinc)
set(GECODE_LIBRARIES
${GECODE_SUPPORT_LIB}
${GECODE_KERNEL_LIB}
${GECODE_SEARCH_LIB}
${GECODE_INT_LIB}
${GECODE_SET_LIB}
${GECODE_FLOAT_LIB}
${GECODE_MINIMODEL_LIB}
${GECODE_DRIVER_LIB}
${GECODE_FLATZINC_LIB}
)
set(GECODE_LIBRARIES "${GECODE_LIBRARIES}" CACHE STRING "Gecode libraries")
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GECODE DEFAULT_MSG
GECODE_SUPPORT_LIB
GECODE_KERNEL_LIB
GECODE_SEARCH_LIB
GECODE_INT_LIB
GECODE_SET_LIB
GECODE_FLOAT_LIB
GECODE_MINIMODEL_LIB
GECODE_DRIVER_LIB
GECODE_FLATZINC_LIB
)
mark_as_advanced(
GECODE_SUPPORT_LIB
GECODE_KERNEL_LIB
GECODE_SEARCH_LIB
GECODE_INT_LIB
GECODE_SET_LIB
GECODE_FLOAT_LIB
GECODE_MINIMODEL_LIB
GECODE_DRIVER_LIB
GECODE_FLATZINC_LIB
)
# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+6 -3
View File
@@ -49,6 +49,7 @@ include(CMakeParseArguments)
# [RESET_VARS var1 var2 ...]
# [ALIASES alias1 alias2 ...]
# [FLAGS flag1 flag2 ...]
# [UNDOCUMENTED]
# )
#-----------------------------------------------------------------------------
@@ -72,7 +73,7 @@ macro(THIRD_PARTY dir varname_root build_target description)
if(${ARGC} GREATER 3)
# Parse extra arguments
CMAKE_PARSE_ARGUMENTS(${varname_root} "" "FIND_NAME;FIND_VERSION" "FIND_COMPONENTS;REQUIRED_VARS;RESET_VARS;ALIASES;FLAGS" ${ARGN})
CMAKE_PARSE_ARGUMENTS(${varname_root} "UNDOCUMENTED" "FIND_NAME;FIND_VERSION" "FIND_COMPONENTS;REQUIRED_VARS;RESET_VARS;ALIASES;FLAGS" ${ARGN})
endif(${ARGC} GREATER 3)
if(NOT ${varname_root}_FIND_NAME)
set(${varname_root}_FIND_NAME ${varname_root})
@@ -262,8 +263,10 @@ macro(THIRD_PARTY dir varname_root build_target description)
CMAKEFILES(${dir})
endif(${CMAKE_PROJECT_NAME}_${varname_root}_BUILD)
OPTION_ALIASES("${CMAKE_PROJECT_NAME}_${varname_root}" "${varname_root}_ALIASES" "ABS")
OPTION_DESCRIPTION("${CMAKE_PROJECT_NAME}_${varname_root}" "${varname_root}_ALIASES" "${description}")
if(NOT ${varname_root}_UNDOCUMENTED)
OPTION_ALIASES("${CMAKE_PROJECT_NAME}_${varname_root}" "${varname_root}_ALIASES" "ABS")
OPTION_DESCRIPTION("${CMAKE_PROJECT_NAME}_${varname_root}" "${varname_root}_ALIASES" "${description}")
endif(NOT ${varname_root}_UNDOCUMENTED)
# For drop-down menus in CMake gui - set STRINGS property
set_property(CACHE ${CMAKE_PROJECT_NAME}_${varname_root} PROPERTY STRINGS AUTO BUNDLED SYSTEM)
+146 -65
View File
@@ -29,24 +29,32 @@
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
cmake_policy(SET CMP0064 OLD)
# The purpose of this logic is to scan a set of C/C++ source files to identify
# all of the variables the CMake configure process may need to set.
# The global property C_DEFINE_VARS will hold the list of defined variables
# found.
# TODO - Use https://sourceforge.net/p/predef/wiki/Home/ to create more
# comprehensive and less ad-hoc lists of flags for OS, arch, etc.
# A user can suppress consideration of definitions that match one or a set of
# patterns by appending those patterns to the C_DEFINE_SKIPVARS global
# property. There are some "standard" patterns that are automatically skipped
# patterns. There are some "standard" patterns that are automatically skipped
# - tests matching the "header guard" pattern are skipped, as are defines
# matching the "EXPORT" and "IMPORT" substrings, operating system and compiler
# identifiers, and various other flags that do not typically need user-defined
# configure stage testing.
set_property(GLOBAL APPEND PROPERTY C_DEFINE_SKIPVARS ".*EXPORT.*")
set_property(GLOBAL APPEND PROPERTY C_DEFINE_SKIPVARS ".*IMPORT.*")
set_property(GLOBAL APPEND PROPERTY C_DEFINE_SKIPPATTERNS ".*EXPORT.*")
set_property(GLOBAL APPEND PROPERTY C_DEFINE_SKIPPATTERNS ".*IMPORT.*")
function(autoheader_ignore_define def)
set_property(GLOBAL APPEND PROPERTY C_DEFINE_SKIPVARS ".*[ (\t]+${def}[ )\t$]*.*")
if("${def}" MATCHES ".*[*].*")
set_property(GLOBAL APPEND PROPERTY C_DEFINE_SKIPPATTERNS "${def}")
else("${def}" MATCHES ".*[*].*")
set_property(GLOBAL APPEND PROPERTY C_DEFINE_SKIPVARS "${def}")
endif("${def}" MATCHES ".*[*].*")
endfunction(autoheader_ignore_define)
function(autoheader_ignore_defines deflist)
@@ -55,15 +63,22 @@ function(autoheader_ignore_defines deflist)
endforeach(def ${${deflist}})
endfunction(autoheader_ignore_defines)
function(autoheader_skip_files def)
set_property(GLOBAL APPEND PROPERTY FILE_SKIPPATTERNS "${def}")
endfunction(autoheader_skip_files)
# OS flags. For performance, put most common
# comparisons first (that'll typicall be
# Windows related tests)
set(OS_FLAGS
WIN32
WIN32_LEAN_AND_MEAN
_WIN32
_WIN64
WIN32_LEAN_AND_MEAN
_WINDOWS
__WIN32__
__WIN64
__WINDOWS__
__APPLE__
BSD
CRAY1
@@ -72,32 +87,82 @@ set(OS_FLAGS
MSDOS
SUNOS
SYSV
_AIX
_BEOS
_BEOS_
_IBMR2
_SCO_SV
_SGI
_ULTRIX
_WINSOCKAPI_
_XENIX
__AIX
__AIX__
__ANDROID__
__BEOS__
__BeOS
__CRAYXC
__CRAYXE
__CYGWIN__
__DARWIN__
__DOS__
__FreeBSD__
__GNU__
__HAIKU__
__LINUX__
__MSDOS__
__NT__
__NetBSD
__NetBSD__
__OPENBSD
__OS2__
__OS400__
__OpenBSD__
__QNX__
__SCO_VERSION__
__TRU64__
__aix
__aix__
__alpha
__alpha__
__apollo
__bsdos__
__convex__NATIVE
__hppa
__hpua
__hpux
__i386
__i386__
__ia64__
__linux
__linux__
__minux
__osf
__osf__
__ppc64__
__ppc__
__riscos
__riscos__
__sgi
__sinix
__sinix__
__sp3__ # what is this? context indicates it is a platform...
__sparc64__
__sun
__tru64
__ultrix
__ultrix__
__x86_64__
_sgi
_sun
_tru64
convex_NATIVE
eta10
hpux
ibm
linux
mips
sco_sv
sgi
sun
vax
@@ -158,95 +223,111 @@ macro(header_guard rdir fname ovar)
string(REPLACE "${rdir}/" "" stage1 ${fname})
string(REPLACE "/" "_" stage2 ${stage1})
string(REPLACE "." "_" stage3 ${stage2})
string(TOUPPER "${stage3}" stage4)
set(${ovar} ${stage4})
string(REPLACE "-" "_" stage4 ${stage3})
string(TOUPPER "${stage4}" stage5)
set(${ovar} ${stage5})
endmacro(header_guard)
# Given an atom from a line (i.e. one conditional if the original line had
# and/or branches, or the original line if there were no and/or branches),
# extract the compile flag
macro(compile_def_flag atom ovar)
string(REGEX REPLACE "^[ \t]*#*.*[!]*(ifdef|defined|elseif defined)[ \t]*[(]*" "" stage1 "${atom}")
string(REGEX REPLACE "[/][*].*[*][/]" "" stage2 "${stage1}")
string(REGEX REPLACE "[)][ \t]*" "" stage3 "${stage2}")
string(REGEX REPLACE "[ \t]+$" "" stage4 "${stage3}")
string(REGEX REPLACE "^[ \t]+" "" stage5 "${stage4}")
set(${ovar} ${stage5})
endmacro(compile_def_flag)
function(autoheader_scan seed_dir)
function(autoheader_scan_internal seed_dir recurse)
set(scan_files)
set(extensions c h cxx cpp hxx hpp)
get_property(C_DEFINE_SKIPVARS GLOBAL PROPERTY C_DEFINE_SKIPVARS)
get_property(C_DEFINE_SKIPPATTERNS GLOBAL PROPERTY C_DEFINE_SKIPPATTERNS)
get_property(FILE_SKIPPATTERNS GLOBAL PROPERTY FILE_SKIPPATTERNS)
foreach(exten ${extensions})
set(sfiles)
file(GLOB_RECURSE sfiles "${seed_dir}/*.${exten}")
if(recurse)
file(GLOB_RECURSE sfiles "${seed_dir}/*.${exten}")
else(recurse)
file(GLOB sfiles "${seed_dir}/*.${exten}")
endif(recurse)
set(scan_files ${scan_files} ${sfiles})
endforeach(exten ${extensions})
#message("found files: ${scan_files}")
foreach(ptn ${FILE_SKIPPATTERNS})
list(FILTER scan_files EXCLUDE REGEX "${ptn}")
endforeach(ptn ${FILE_SKIPPATTERNS})
#message("processing files: ${scan_files}")
set(unique_keys)
foreach(sf ${scan_files})
header_guard("${seed_dir}" "${sf}" hg)
set(SKIP_LIST ".*[ \t]+${hg}[ \t]*" ${C_DEFINE_SKIPVARS})
file(STRINGS ${sf} SRC_LINES REGEX "^[ \t]*#.*(ifdef|defined[(]).+")
set(def_list)
foreach(line ${SRC_LINES})
#message("line: ${line}")
set(lset ${line})
string(REPLACE "&&" ";" lset "${lset}")
string(REPLACE "||" ";" lset "${lset}")
foreach(l ${lset})
#message(" atom: ${l}")
set(skip_line 0)
foreach(sk ${SKIP_LIST})
if(NOT skip_line)
#message("testing ${l} vs ${sk}")
if("${l}" MATCHES "${sk}")
#message("matched ${l} vs ${sk} - skipping")
set(skip_line 1)
endif("${l}" MATCHES "${sk}")
endif(NOT skip_line)
endforeach(sk ${SKIP_LIST})
if(NOT skip_line)
set(def_list ${def_list} ${l})
endif(NOT skip_line)
endforeach(l ${lset})
endforeach(line ${SRC_LINES})
set(SKIP_LIST "${hg}" ${C_DEFINE_SKIPVARS})
# Use unifdef to get the list of conditional symbols
# See http://dotat.at/prog/unifdef/ and https://github.com/fanf2/unifdef
execute_process(COMMAND unifdef -s ${sf} OUTPUT_VARIABLE def_list)
string(REPLACE "\n" ";" def_list "${def_list}")
if(def_list)
#message("file ${sf} def lines:")
foreach(l ${def_list})
set(dflag)
compile_def_flag(${l} dflag)
#message(" line: ${l}")
#message(" extracted: ${dflag}")
set(unique_keys ${unique_keys} ${dflag})
endforeach(l ${def_list})
foreach(dflag ${def_list})
set(skip_flag 0)
foreach(sk ${SKIP_LIST})
if(NOT skip_flag)
if("${dflag}" STREQUAL "${sk}")
set(skip_flag 1)
endif("${dflag}" STREQUAL "${sk}")
endif(NOT skip_flag)
endforeach(sk ${SKIP_LIST})
foreach(sp ${C_DEFINE_SKIPPATTERNS})
if(NOT skip_flag)
if("${dflag}" MATCHES ${sp})
set(skip_flag 1)
endif("${dflag}" MATCHES ${sp})
endif(NOT skip_flag)
endforeach(sp ${C_DEFINE_SKIPPATTERNS})
if(NOT skip_flag)
#message(" ${dflag}")
set(unique_keys ${unique_keys} ${dflag})
endif(NOT skip_flag)
endforeach(dflag ${def_list})
endif(def_list)
endforeach(sf ${scan_files})
list(REMOVE_DUPLICATES unique_keys)
foreach(k ${unique_keys})
set_property(GLOBAL APPEND PROPERTY C_DEFINE_VARS "${k}")
endforeach(k ${unique_keys})
list(LENGTH unique_keys UKLEN)
if(UKLEN)
list(REMOVE_DUPLICATES unique_keys)
foreach(k ${unique_keys})
set_property(GLOBAL APPEND PROPERTY C_DEFINE_VARS "${k}")
endforeach(k ${unique_keys})
endif(UKLEN)
# If we've run autoheader_scan mulitple times, we need to
# ensure uniqueness globally...
get_property(C_DEFINE_VARS GLOBAL PROPERTY C_DEFINE_VARS)
list(REMOVE_DUPLICATES C_DEFINE_VARS)
list(SORT C_DEFINE_VARS)
list(LENGTH C_DEFINE_VARS DLEN)
if(DLEN)
list(REMOVE_DUPLICATES C_DEFINE_VARS)
list(SORT C_DEFINE_VARS)
endif(DLEN)
set_property(GLOBAL PROPERTY C_DEFINE_VARS "${C_DEFINE_VARS}")
endfunction(autoheader_scan_internal)
function(autoheader_scan seed_dir)
autoheader_scan_internal("${seed_dir}" 0)
endfunction(autoheader_scan)
function(autoheader_recursive_scan seed_dir)
autoheader_scan_internal("${seed_dir}" 1)
endfunction(autoheader_recursive_scan)
# For testing convenience, the following will exercise the
# logic in cmake -P script mode. Should be removed if/when
# this goes "live" in the real build.
set(LOCAL_SKIP DIRENT_ BRLCADBUILD BRLCAD_ DM_ FB_ NO_BOMBING_MACROS USE_BINARY_ATTRIBUTES
set(LOCAL_SKIP DIRENT_ BRLCADBUILD ^BRLCAD_* ^DM_* ^FB_* NO_BOMBING_MACROS USE_BINARY_ATTRIBUTES
IF_WGL IF_X IF_QT IF_OGL NO_DEBUG_CHECKING USE_OPENCL)
autoheader_ignore_defines(LOCAL_SKIP)
set_property(GLOBAL APPEND PROPERTY C_DEFINE_SKIPVARS ".*IMPORT.*")
autoheader_scan(${CMAKE_CURRENT_SOURCE_DIR}/include)
autoheader_scan(${CMAKE_CURRENT_SOURCE_DIR}/src/libbu)
autoheader_skip_files(".*src/other/.*")
autoheader_recursive_scan(${CMAKE_CURRENT_SOURCE_DIR}/include)
autoheader_recursive_scan(${CMAKE_CURRENT_SOURCE_DIR}/src)
autoheader_scan(${CMAKE_CURRENT_SOURCE_DIR}/misc/tools/perplex)
get_property(C_DEFINE_VARS GLOBAL PROPERTY C_DEFINE_VARS)
message("keys:")
+1
View File
@@ -80,6 +80,7 @@ set(misc_ignore_files
mime.types
mime_cad.types
nsis
osl_shaders
wix
svn2git
uncpowerplant2g.sh
-7
View File
@@ -1,5 +1,4 @@
SET(re2c_ignore_files
CHANGELOG
CMake
README.in
basics.h
@@ -9,23 +8,17 @@ config.h.in
config_w32.h.in
configure.in
dfa.h
doc
examples
globals.h
htdocs
ins.h
lessons
mbo_getopt.h
re2c_parser.h
parser.yy
re.h
re2c.1.in
re2c.spec.in
run_tests.sh.in
scanner.h
scanner.re
stream_lc.h
substr.h
test
token.h
)
-255
View File
@@ -1,255 +0,0 @@
Version 0.13.6 (2008-??-??)
---------------------------
Version 0.13.5 (2008-05-25)
---------------------------
- Fixed #1952896 Segfault in re2c::Scanner::scan.
- Fixed #1952842 Regression.
Version 0.13.4 (2008-04-05)
---------------------------
- Added transparent handling of #line directives in input files.
- Added re2c:yyfill:check inplace configuration.
- Added re2c:define:YYSETSTATE:naked inplace configuration.
- Added re2c:flags:w and re2c:flags:u inplace configurations.
- Added the ability to add rules in 'use:re2c' blocks.
- Changed -r flag to accept only 'rules:re2c' and 'use:re2c' blocks.
Version 0.13.3 (2008-03-14)
---------------------------
- Added -r flag to allow reuse of scanner definitions.
- Added -F flag to support flex syntax in rules.
- Fixed SEGV in scanner that occurs with very large blocks.
- Fixed issue with unused yybm.
- Partial support for flex syntax.
- Changed to allow /* comments with -c switch.
- Added flag -D/--emit-dot.
Version 0.13.2 (2008-02-14)
---------------------------
- Added flag --case-inverted.
- Added flag --case-insensitive.
- Added support for '<!...>' to enable rule setup.
- Added support for '=>' style rules.
- Added support for ':=' style rules.
- Added support for ':=>' style rules.
- Added re2c:cond:divider and re2c:con:goto inplace configuration.
- Fixed code generation to emit space after 'if'.
Version 0.13.1 (2007-08-24)
---------------------------
- Added custom build rules for Visual Studio 2005 (re2c.rules). (William Swanson)
- Fixed issue with some compilers.
- Fixed #1776177 Build on AIX.
- Fixed #1743180 fwrite with 0 length crashes on OS X.
Version 0.13.0 (2007-06-24)
---------------------------
- Added -c and -t to generate scanners with (f)lex-like condition support.
- Fixed issue with short form of switches and parameter if not first switch.
- Fixed #1708378 segfault in actions.cc.
Version 0.12.3 (2007-08-24)
---------------------------
- Fixed issue with some compilers.
- Fixed #1776177 Build on AIX.
- Fixed #1743180 fwrite with 0 length crashes on OS X.
Version 0.12.2 (2007-06-26)
---------------------------
- Fixed #1743180 fwrite with 0 length crashes on OS X.
Version 0.12.1 (2007-05-23)
---------------------------
- Fixed #1711240 problem with '"' and 7F on EBCDIC platforms.
Version 0.12.0 (2007-05-01)
---------------------------
- Re-release of 0.11.3 as new stable branch.
- Fixed issue with short form of switches and parameter if not first switch.
- Fixed #1708378 segfault in actions.cc.
Version 0.11.3 (2007-04-01)
---------------------------
- Added support for underscores in named definitions.
- Added new option --no-generation-date.
- Fixed issue with long form of switches.
Version 0.11.2 (2007-03-01)
---------------------------
- Added inplace configuration 're2c:yyfill:parameter'.
- Added inplace configuration 're2c:yych:conversion'.
- Fixed -u switch code generation.
- Added ability to avoid defines and overwrite variable and label names.
Version 0.11.1 (2007-02-20)
---------------------------
- Applied #1647875 add const to yybm vector.
Version 0.11.0 (2007-01-01)
---------------------------
- Added -u switch to support unicode.
Version 0.10.8 (2007-04-01)
---------------------------
- Fixed issue with long form of switches.
Version 0.10.7 (2007-02-20)
---------------------------
- Applied #1647875 add const to yybm vector.
Version 0.10.6 (2006-08-05)
---------------------------
- Fixed #1529351 Segv bug on unterminated code blocks.
- Fixed #1528269 Invalid code generation.
Version 0.10.5 (2006-06-11)
---------------------------
- Fixed long form of -1 switch to --single-pass as noted in man page and help.
- Added MSVC 2003 project files and renamed old 2002 ones.
Version 0.10.4 (2006-06-01)
---------------------------
- Fix whitespace in generated code.
Version 0.10.3 (2006-05-14)
---------------------------
- Fixed issue with -wb and -ws.
- Added -g switch to support gcc's computed goto's.
- Changed to use nested if's instead of "switch(yyaccept)" in -s mode.
Version 0.10.2 (2006-05-01)
---------------------------
- Changed to generate YYMARKER only when needed or in single pass mode.
- Added -1 switch to force single pass generation and make two pass the default.
- Fixed -i switch.
- Added configuration 'yyfill:enable' to allow suppression of YYFILL() blocks.
- Added tutorial like lessons to re2c.
- Added /*!ignore:re2c */ to support documenting of re2c source.
- Fixed issue with multiline re2c comments (/*!max:re2c ... */ and alike).
- Fixed generation of YYDEBUG() when using -d switch.
- Added /*!getstate:re2c */ which triggers generation of the YYGETSTATE() block.
- Added configuration 'state:abort'.
- Changed to not generate yyNext unless configuration 'state:nextlabel' is used.
- Changed to not generate yyaccept code unless needed.
- Changed to use if- instead of switch-expression when yyaccpt has only one case.
- Added docu, examples and tests to .src.zip package (0.10.1 zip was repackaged).
- Fixed #1479044 incorrect code generated when using -b.
- Fixed #1472770 re2c creates an infinite loop.
- Fixed #1454253 Piece of code saving a backtracking point not generated.
- Fixed #1463639 Missing forward declaration.
- Implemented #1187127 savable state support for multiple re2c blocks.
Version 0.10.1 (2006-02-28)
---------------------------
- Added support for Solaris and native SUN compiler.
- Applied #1438160 expose YYCTXMARKER.
Version 0.10.0 (2006-02-18)
---------------------------
- Added make target zip to create windows source packages as zip files.
- Added re2c:startlabel configuration.
- Fixed code generation to not generate unreachable code for initial state.
- Added support for c/c++ compatible \u and \U unicode notation.
- Added ability to control indentation.
- Made scanner error out in case an ambiguous /* is found.
- Fixed indentation of generated code.
- Added support for DOS line endings.
- Added experimental unicode support.
- Added config_w32.h to build out of the box on windows (using msvc 2002+).
- Added Microsoft Visual C .NET 2005 build files.
- Applied #1411087 variable length trailing context.
- Applied #1408326 do not generate goto next state.
- Applied #1408282 CharSet initialization fix.
- Applied #1408278 readsome with MSVC.
- Applied #1307467 Unicode patch for 0.9.7.
Version 0.9.12 (2005-12-28)
---------------------------
- Fixed bug #1390174 re2c cannot accept {0,}.
Version 0.9.11 (2005-12-18)
---------------------------
- Fixed #1313083 -e (EBCDIC cross compile) broken.
- Fixed #1297658 underestimation of n in YYFILL(n).
- Applied #1339483 Avoid rebuilds of re2c when running subtargets.
- Implemented #1335305 symbol table reimplementation, just slightly modified.
Version 0.9.10 (2005-09-04)
---------------------------
- Added -i switch to avoid generating #line information.
- Fixed bug #1251653 re2c generate some invalid #line on WIN32.
Version 0.9.9 (2005-07-21)
--------------------------
- Implemented #1232777 negated char classes '[^...]' and the dot operator '.'.
- Added hexadecimal character definitions.
- Added consistency check for octal character definitions.
Version 0.9.8 (2005-06-26)
--------------------------
- Fixed code generation for -b switch.
- Added Microsoft Visual C .NET build files.
Version 0.9.7 (2005-04-30)
--------------------------
- Applied #1181535 storable state patch.
- Added -d flag which outputs a debuggable parser.
- Fixed generation of '#line' directives (according to ISO-C99).
- Fixed bug #1187785 Re2c fails to generate valid code.
- Fixed bug #1187452 unused variable `yyaccept'.
Version 0.9.6 (2005-04-14)
--------------------------
- Fixed build with gcc >= 3.4.
Version 0.9.5 (2005-04-08)
--------------------------
- Added /*!max:re2c */ which emits a '#define YYMAXFILL <max>\n' line
This allows to define buffers of the minimum required length. Occurrence
must follow '/*re2c */ and cannot precede it.
- Changed re2c to two pass generation to output warning free code.
- Fixed bug #1163046 re2c hangs when processing valid re-file.
- Fixed bug #1022799 re2c scanner has buffering bug.
Version 0.9.4 (2005-03-12)
--------------------------
- Added --vernum support.
- Fixed bug #1054496 incorrect code generated with -b option.
- Fixed bug #1012748 re2c does not emit last line if '\n' missing.
- Fixed bug #999104 --output=output option does not work as documented.
- Fixed bug #999103 Invalid options prefixed with two dashes cause program crash.
Version 0.9.3 (2004-05-26)
--------------------------
- Fixes one small possible bug in the generated output. ych instead of yych is
output in certain circumstances
Version 0.9.2 (2004-05-26)
--------------------------
- Added -o option to specify the output file which also will set the #line
directives to something useful.
- Print version to cout instead cerr.
- Added -h and -- style options.
- Moved development to http://sourceforge.net/projects/re2c .
- Fixed bug #960144 minor cosmetic problem.
- Fixed bug #953181 cannot compile with.
- Fixed bug #939277 Windows support.
- Fixed bug #914462 automake build patch
- Fixed bug #891940 braced quantifiers: {\d+(,|,\d+)?} style.
- Fixed bug #869298 Add case insensitive string literals.
- Fixed bug #869297 Input buffer overrun.
Version 0.9.1 (2003-12-13)
--------------------------
- Removed rcs comments in source files.
Version 0.9
-----------
- Redistribution based on version 0.5.
- Added parentheses to assignment expressions in 'if' statements.
- Rearranged class members to match initialization order.
- Substr fix.
- Use array delete [] when necessary.
- Other minor fixes for subduing compiler warnings.
-1
View File
@@ -134,7 +134,6 @@ if(NOT RE2C_SKIP_INSTALL)
endif(NOT RE2C_SKIP_INSTALL)
configure_file(README.in ${CMAKE_CURRENT_BINARY_DIR}/README)
configure_file(run_tests.sh.in ${CMAKE_CURRENT_BINARY_DIR}/run_tests.sh @ONLY)
# Local Variables:
# tab-width: 8
File diff suppressed because it is too large Load Diff
-48
View File
@@ -1,48 +0,0 @@
@Article{Bumbulis94,
author = {Peter Bumbulis and Donald D. Cowan},
title = {RE2C -- A More Versatile Scanner Generator},
journal = "ACM Letters on Programming Languages and Systems",
volume = 2,
number = "1--4",
year = 1994,
abstract = {
It is usually claimed that lexical analysis routines are still coded by
hand, despite the widespread availability of scanner generators, for
efficiency reasons. While efficiency is a consideration, there exist
freely available scanner generators such as GLA \cite{Gray88} that can
generate scanners that are faster than most hand-coded ones. However,
most generated scanners are tailored for a particular environment, and
retargetting these scanners to other environments, if possible, is
usually complex enough to make a hand-coded scanner more appealing. In
this paper we describe RE2C, a scanner generator that not only generates
scanners which are faster (and usually smaller) than those produced by
any other scanner generator known to the authors, including GLA, but
also adapt easily to any environment.
}
}
@Article{Gray88,
author = {Robert W. Gray},
title = {{$\gamma$-GLA} - {A} Generator for Lexical Analyzers That
Programmers Can Use},
journal = {USENIX Conference Proceedings},
year = {1988},
month = {June},
pages = {147-160},
abstract = {Writing an efficient lexical analyzer for even a simple
language is not a trivial task, and should not be done by hand. We
describe GLA, a tool that generates very efficient scanners. These
scanners do not use the conventional transition matrix, but instead
use a few 128 element vectors. Scanning time is only slightly
greater than the absolute minimum --- the time it takes to look at
each character in a file. The GLA language allows simple, concise
specification of scanners. Augmenting regular expressions with
auxiliary scanners easily handles nasty problems such as C comments
and C literal constants. We formalize the connection between token
scanning and token processing by associating a processor with
appropriate patterns. A library of canned descriptions simplifies the
specification of commonly used language pieces --- such as,
C\_IDENTIFIERS, C\_STRINGS, PASCAL\_COMMENTS, etc. Finally, carefully
tuned lexical analysis support modules are provided for error
handling, input buffering, storing identifiers in hash tables and
manipulating denotations.}
}
-26
View File
@@ -1,26 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <string.h>
#ifndef MAP_NORESERVE
#define MAP_NORESERVE 0
#endif
volatile char ch;
main(){
struct stat statbuf;
uchar *buf;
fstat(0, &statbuf);
buf = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED|MAP_NORESERVE,
0, 0);
if(buf != (uchar*)(-1)){
uchar *cur, *lim = &buf[statbuf.st_size];
for(cur = buf; buf != lim; ++cur){
ch = *cur;
}
munmap(buf, statbuf.st_size);
}
}
-272
View File
@@ -1,272 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define ADDEQ 257
#define ANDAND 258
#define ANDEQ 259
#define ARRAY 260
#define ASM 261
#define AUTO 262
#define BREAK 263
#define CASE 264
#define CHAR 265
#define CONST 266
#define CONTINUE 267
#define DECR 268
#define DEFAULT 269
#define DEREF 270
#define DIVEQ 271
#define DO 272
#define DOUBLE 273
#define ELLIPSIS 274
#define ELSE 275
#define ENUM 276
#define EQL 277
#define EXTERN 278
#define FCON 279
#define FLOAT 280
#define FOR 281
#define FUNCTION 282
#define GEQ 283
#define GOTO 284
#define ICON 285
#define ID 286
#define IF 287
#define INCR 288
#define INT 289
#define LEQ 290
#define LONG 291
#define LSHIFT 292
#define LSHIFTEQ 293
#define MODEQ 294
#define MULEQ 295
#define NEQ 296
#define OREQ 297
#define OROR 298
#define POINTER 299
#define REGISTER 300
#define RETURN 301
#define RSHIFT 302
#define RSHIFTEQ 303
#define SCON 304
#define SHORT 305
#define SIGNED 306
#define SIZEOF 307
#define STATIC 308
#define STRUCT 309
#define SUBEQ 310
#define SWITCH 311
#define TYPEDEF 312
#define UNION 313
#define UNSIGNED 314
#define VOID 315
#define VOLATILE 316
#define WHILE 317
#define XOREQ 318
#define EOI 319
typedef unsigned int uint;
typedef unsigned char uchar;
#define BSIZE 8192
#define YYCTYPE uchar
#define YYCURSOR cursor
#define YYLIMIT s->lim
#define YYMARKER s->ptr
#define YYFILL(n) {cursor = fill(s, cursor);}
#define RET(i) {s->cur = cursor; return i;}
typedef struct Scanner {
int fd;
uchar *bot, *tok, *ptr, *cur, *pos, *lim, *top, *eof;
uint line;
} Scanner;
uchar *fill(Scanner *s, uchar *cursor){
if(!s->eof) {
uint cnt = s->tok - s->bot;
if(cnt){
memcpy(s->bot, s->tok, s->lim - s->tok);
s->tok = s->bot;
s->ptr -= cnt;
cursor -= cnt;
s->pos -= cnt;
s->lim -= cnt;
}
if((s->top - s->lim) < BSIZE){
uchar *buf = (uchar*) malloc(((s->lim - s->bot) + BSIZE)*sizeof(uchar));
memcpy(buf, s->tok, s->lim - s->tok);
s->tok = buf;
s->ptr = &buf[s->ptr - s->bot];
cursor = &buf[cursor - s->bot];
s->pos = &buf[s->pos - s->bot];
s->lim = &buf[s->lim - s->bot];
s->top = &s->lim[BSIZE];
free(s->bot);
s->bot = buf;
}
if((cnt = read(s->fd, (char*) s->lim, BSIZE)) != BSIZE){
s->eof = &s->lim[cnt]; *(s->eof)++ = '\n';
}
s->lim += cnt;
}
return cursor;
}
int scan(Scanner *s){
uchar *cursor = s->cur;
std:
s->tok = cursor;
/*!re2c
any = [\000-\377];
O = [0-7];
D = [0-9];
L = [a-zA-Z_];
H = [a-fA-F0-9];
E = [Ee] [+-]? D+;
FS = [fFlL];
IS = [uUlL]*;
ESC = [\\] ([abfnrtv?'"\\] | "x" H+ | O+);
*/
/*!re2c
"/*" { goto comment; }
"auto" { RET(AUTO); }
"break" { RET(BREAK); }
"case" { RET(CASE); }
"char" { RET(CHAR); }
"const" { RET(CONST); }
"continue" { RET(CONTINUE); }
"default" { RET(DEFAULT); }
"do" { RET(DO); }
"double" { RET(DOUBLE); }
"else" { RET(ELSE); }
"enum" { RET(ENUM); }
"extern" { RET(EXTERN); }
"float" { RET(FLOAT); }
"for" { RET(FOR); }
"goto" { RET(GOTO); }
"if" { RET(IF); }
"int" { RET(INT); }
"long" { RET(LONG); }
"register" { RET(REGISTER); }
"return" { RET(RETURN); }
"short" { RET(SHORT); }
"signed" { RET(SIGNED); }
"sizeof" { RET(SIZEOF); }
"static" { RET(STATIC); }
"struct" { RET(STRUCT); }
"switch" { RET(SWITCH); }
"typedef" { RET(TYPEDEF); }
"union" { RET(UNION); }
"unsigned" { RET(UNSIGNED); }
"void" { RET(VOID); }
"volatile" { RET(VOLATILE); }
"while" { RET(WHILE); }
L (L|D)* { RET(ID); }
("0" [xX] H+ IS?) | ("0" D+ IS?) | (D+ IS?) |
(['] (ESC|any\[\n\\'])* ['])
{ RET(ICON); }
(D+ E FS?) | (D* "." D+ E? FS?) | (D+ "." D* E? FS?)
{ RET(FCON); }
(["] (ESC|any\[\n\\"])* ["])
{ RET(SCON); }
"..." { RET(ELLIPSIS); }
">>=" { RET(RSHIFTEQ); }
"<<=" { RET(LSHIFTEQ); }
"+=" { RET(ADDEQ); }
"-=" { RET(SUBEQ); }
"*=" { RET(MULEQ); }
"/=" { RET(DIVEQ); }
"%=" { RET(MODEQ); }
"&=" { RET(ANDEQ); }
"^=" { RET(XOREQ); }
"|=" { RET(OREQ); }
">>" { RET(RSHIFT); }
"<<" { RET(LSHIFT); }
"++" { RET(INCR); }
"--" { RET(DECR); }
"->" { RET(DEREF); }
"&&" { RET(ANDAND); }
"||" { RET(OROR); }
"<=" { RET(LEQ); }
">=" { RET(GEQ); }
"==" { RET(EQL); }
"!=" { RET(NEQ); }
";" { RET(';'); }
"{" { RET('{'); }
"}" { RET('}'); }
"," { RET(','); }
":" { RET(':'); }
"=" { RET('='); }
"(" { RET('('); }
")" { RET(')'); }
"[" { RET('['); }
"]" { RET(']'); }
"." { RET('.'); }
"&" { RET('&'); }
"!" { RET('!'); }
"~" { RET('~'); }
"-" { RET('-'); }
"+" { RET('+'); }
"*" { RET('*'); }
"/" { RET('/'); }
"%" { RET('%'); }
"<" { RET('<'); }
">" { RET('>'); }
"^" { RET('^'); }
"|" { RET('|'); }
"?" { RET('?'); }
[ \t\v\f]+ { goto std; }
"\n"
{
if(cursor == s->eof) RET(EOI);
s->pos = cursor; s->line++;
goto std;
}
any
{
printf("unexpected character: %c\n", *s->tok);
goto std;
}
*/
comment:
/*!re2c
"*/" { goto std; }
"\n"
{
if(cursor == s->eof) RET(EOI);
s->tok = s->pos = cursor; s->line++;
goto comment;
}
any { goto comment; }
*/
}
main(){
Scanner in;
int t;
memset((char*) &in, 0, sizeof(in));
in.fd = 0;
while((t = scan(&in)) != EOI){
/*
printf("%d\t%.*s\n", t, in.cur - in.tok, in.tok);
printf("%d\n", t);
*/
}
close(in.fd);
}
-267
View File
@@ -1,267 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <string.h>
#define ADDEQ 257
#define ANDAND 258
#define ANDEQ 259
#define ARRAY 260
#define ASM 261
#define AUTO 262
#define BREAK 263
#define CASE 264
#define CHAR 265
#define CONST 266
#define CONTINUE 267
#define DECR 268
#define DEFAULT 269
#define DEREF 270
#define DIVEQ 271
#define DO 272
#define DOUBLE 273
#define ELLIPSIS 274
#define ELSE 275
#define ENUM 276
#define EQL 277
#define EXTERN 278
#define FCON 279
#define FLOAT 280
#define FOR 281
#define FUNCTION 282
#define GEQ 283
#define GOTO 284
#define ICON 285
#define ID 286
#define IF 287
#define INCR 288
#define INT 289
#define LEQ 290
#define LONG 291
#define LSHIFT 292
#define LSHIFTEQ 293
#define MODEQ 294
#define MULEQ 295
#define NEQ 296
#define OREQ 297
#define OROR 298
#define POINTER 299
#define REGISTER 300
#define RETURN 301
#define RSHIFT 302
#define RSHIFTEQ 303
#define SCON 304
#define SHORT 305
#define SIGNED 306
#define SIZEOF 307
#define STATIC 308
#define STRUCT 309
#define SUBEQ 310
#define SWITCH 311
#define TYPEDEF 312
#define UNION 313
#define UNSIGNED 314
#define VOID 315
#define VOLATILE 316
#define WHILE 317
#define XOREQ 318
#define EOI 319
typedef unsigned int unint;
typedef unsigned char uchar;
#define YYCTYPE uchar
#define YYCURSOR cursor
#define YYLIMIT s->lim
#define YYMARKER s->ptr
#define YYFILL(n) {cursor = fill(s, cursor);}
#define RET(i) {s->cur = cursor; return i;}
typedef struct Scanner {
uchar *tok, *ptr, *cur, *pos, *lim, *eof;
unint line;
} Scanner;
uchar *fill(Scanner *s, uchar *cursor){
if(!s->eof){
unint cnt = s->lim - s->tok;
uchar *buf = malloc((cnt + 1)*sizeof(uchar));
memcpy(buf, s->tok, cnt);
cursor = &buf[cursor - s->tok];
s->pos = &buf[s->pos - s->tok];
s->ptr = &buf[s->ptr - s->tok];
s->lim = &buf[cnt];
s->eof = s->lim; *(s->eof)++ = '\n';
s->tok = buf;
}
return cursor;
}
int scan(Scanner *s){
uchar *cursor = s->cur;
std:
s->tok = cursor;
/*!re2c
any = [\000-\377];
O = [0-7];
D = [0-9];
L = [a-zA-Z_];
H = [a-fA-F0-9];
E = [Ee] [+-]? D+;
FS = [fFlL];
IS = [uUlL]*;
ESC = [\\] ([abfnrtv?'"\\] | "x" H+ | O+);
*/
/*!re2c
"/*" { goto comment; }
"auto" { RET(AUTO); }
"break" { RET(BREAK); }
"case" { RET(CASE); }
"char" { RET(CHAR); }
"const" { RET(CONST); }
"continue" { RET(CONTINUE); }
"default" { RET(DEFAULT); }
"do" { RET(DO); }
"double" { RET(DOUBLE); }
"else" { RET(ELSE); }
"enum" { RET(ENUM); }
"extern" { RET(EXTERN); }
"float" { RET(FLOAT); }
"for" { RET(FOR); }
"goto" { RET(GOTO); }
"if" { RET(IF); }
"int" { RET(INT); }
"long" { RET(LONG); }
"register" { RET(REGISTER); }
"return" { RET(RETURN); }
"short" { RET(SHORT); }
"signed" { RET(SIGNED); }
"sizeof" { RET(SIZEOF); }
"static" { RET(STATIC); }
"struct" { RET(STRUCT); }
"switch" { RET(SWITCH); }
"typedef" { RET(TYPEDEF); }
"union" { RET(UNION); }
"unsigned" { RET(UNSIGNED); }
"void" { RET(VOID); }
"volatile" { RET(VOLATILE); }
"while" { RET(WHILE); }
L (L|D)* { RET(ID); }
("0" [xX] H+ IS?) | ("0" D+ IS?) | (D+ IS?) |
(['] (ESC|any\[\n\\'])* ['])
{ RET(ICON); }
(D+ E FS?) | (D* "." D+ E? FS?) | (D+ "." D* E? FS?)
{ RET(FCON); }
(["] (ESC|any\[\n\\"])* ["])
{ RET(SCON); }
"..." { RET(ELLIPSIS); }
">>=" { RET(RSHIFTEQ); }
"<<=" { RET(LSHIFTEQ); }
"+=" { RET(ADDEQ); }
"-=" { RET(SUBEQ); }
"*=" { RET(MULEQ); }
"/=" { RET(DIVEQ); }
"%=" { RET(MODEQ); }
"&=" { RET(ANDEQ); }
"^=" { RET(XOREQ); }
"|=" { RET(OREQ); }
">>" { RET(RSHIFT); }
"<<" { RET(LSHIFT); }
"++" { RET(INCR); }
"--" { RET(DECR); }
"->" { RET(DEREF); }
"&&" { RET(ANDAND); }
"||" { RET(OROR); }
"<=" { RET(LEQ); }
">=" { RET(GEQ); }
"==" { RET(EQL); }
"!=" { RET(NEQ); }
";" { RET(';'); }
"{" { RET('{'); }
"}" { RET('}'); }
"," { RET(','); }
":" { RET(':'); }
"=" { RET('='); }
"(" { RET('('); }
")" { RET(')'); }
"[" { RET('['); }
"]" { RET(']'); }
"." { RET('.'); }
"&" { RET('&'); }
"!" { RET('!'); }
"~" { RET('~'); }
"-" { RET('-'); }
"+" { RET('+'); }
"*" { RET('*'); }
"/" { RET('/'); }
"%" { RET('%'); }
"<" { RET('<'); }
">" { RET('>'); }
"^" { RET('^'); }
"|" { RET('|'); }
"?" { RET('?'); }
[ \t\v\f]+ { goto std; }
"\n"
{
if(cursor == s->eof) RET(EOI);
s->pos = cursor; s->line++;
goto std;
}
any
{
printf("unexpected character: %c\n", *s->tok);
goto std;
}
*/
comment:
/*!re2c
"*/" { goto std; }
"\n"
{
if(cursor == s->eof) RET(EOI);
s->tok = s->pos = cursor; s->line++;
goto comment;
}
any { goto comment; }
*/
}
#ifndef MAP_NORESERVE
#define MAP_NORESERVE 0
#endif
main(){
Scanner in;
struct stat statbuf;
uchar *buf;
fstat(0, &statbuf);
buf = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED|MAP_NORESERVE,
0, 0);
if(buf != (uchar*)(-1)){
int t;
in.lim = &(in.cur = buf)[statbuf.st_size];
in.pos = NULL;
in.eof = NULL;
while((t = scan(&in)) != EOI){
/*
printf("%d\t%.*s\n", t, in.cur - in.tok, in.tok);
printf("%d\n", t);
*/
}
munmap(buf, statbuf.st_size);
}
}
-239
View File
@@ -1,239 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define ADDEQ 257
#define ANDAND 258
#define ANDEQ 259
#define ARRAY 260
#define ASM 261
#define AUTO 262
#define BREAK 263
#define CASE 264
#define CHAR 265
#define CONST 266
#define CONTINUE 267
#define DECR 268
#define DEFAULT 269
#define DEREF 270
#define DIVEQ 271
#define DO 272
#define DOUBLE 273
#define ELLIPSIS 274
#define ELSE 275
#define ENUM 276
#define EQL 277
#define EXTERN 278
#define FCON 279
#define FLOAT 280
#define FOR 281
#define FUNCTION 282
#define GEQ 283
#define GOTO 284
#define ICON 285
#define ID 286
#define IF 287
#define INCR 288
#define INT 289
#define LEQ 290
#define LONG 291
#define LSHIFT 292
#define LSHIFTEQ 293
#define MODEQ 294
#define MULEQ 295
#define NEQ 296
#define OREQ 297
#define OROR 298
#define POINTER 299
#define REGISTER 300
#define RETURN 301
#define RSHIFT 302
#define RSHIFTEQ 303
#define SCON 304
#define SHORT 305
#define SIGNED 306
#define SIZEOF 307
#define STATIC 308
#define STRUCT 309
#define SUBEQ 310
#define SWITCH 311
#define TYPEDEF 312
#define UNION 313
#define UNSIGNED 314
#define VOID 315
#define VOLATILE 316
#define WHILE 317
#define XOREQ 318
#define EOI 319
typedef unsigned int uint;
typedef unsigned char uchar;
#define BSIZE 8192
#define YYCTYPE uchar
#define YYCURSOR cursor
#define YYLIMIT s->lim
#define YYMARKER s->ptr
#define YYFILL(n) {cursor = fill(s, cursor);}
#define RET(i) {s->cur = cursor; return i;}
typedef struct Scanner {
int fd;
uchar *bot, *tok, *ptr, *cur, *pos, *lim, *top, *eof;
uint line;
} Scanner;
uchar *fill(Scanner *s, uchar *cursor){
if(!s->eof){
uint cnt = s->tok - s->bot;
if(cnt){
memcpy(s->bot, s->tok, s->lim - s->tok);
s->tok = s->bot;
s->ptr -= cnt;
cursor -= cnt;
s->pos -= cnt;
s->lim -= cnt;
}
if((s->top - s->lim) < BSIZE){
uchar *buf = (uchar*) malloc(((s->lim - s->bot) + BSIZE)*sizeof(uchar));
memcpy(buf, s->tok, s->lim - s->tok);
s->tok = buf;
s->ptr = &buf[s->ptr - s->bot];
cursor = &buf[cursor - s->bot];
s->pos = &buf[s->pos - s->bot];
s->lim = &buf[s->lim - s->bot];
s->top = &s->lim[BSIZE];
free(s->bot);
s->bot = buf;
}
if((cnt = read(s->fd, (char*) s->lim, BSIZE)) != BSIZE){
s->eof = &s->lim[cnt]; *(s->eof)++ = '\n';
}
s->lim += cnt;
}
return cursor;
}
int scan(Scanner *s){
uchar *cursor = s->cur;
std:
s->tok = cursor;
/*!re2c
any = [\000-\377];
O = [0-7];
D = [0-9];
L = [a-zA-Z_];
H = [a-fA-F0-9];
E = [Ee] [+-]? D+;
FS = [fFlL];
IS = [uUlL]*;
ESC = [\\] ([abfnrtv?'"\\] | "x" H+ | O+);
*/
/*!re2c
"/*" { goto comment; }
L (L|D)* { RET(ID); }
("0" [xX] H+ IS?) | ("0" D+ IS?) | (D+ IS?) |
(['] (ESC|any\[\n\\'])* ['])
{ RET(ICON); }
(D+ E FS?) | (D* "." D+ E? FS?) | (D+ "." D* E? FS?)
{ RET(FCON); }
(["] (ESC|any\[\n\\"])* ["])
{ RET(SCON); }
"..." { RET(ELLIPSIS); }
">>=" { RET(RSHIFTEQ); }
"<<=" { RET(LSHIFTEQ); }
"+=" { RET(ADDEQ); }
"-=" { RET(SUBEQ); }
"*=" { RET(MULEQ); }
"/=" { RET(DIVEQ); }
"%=" { RET(MODEQ); }
"&=" { RET(ANDEQ); }
"^=" { RET(XOREQ); }
"|=" { RET(OREQ); }
">>" { RET(RSHIFT); }
"<<" { RET(LSHIFT); }
"++" { RET(INCR); }
"--" { RET(DECR); }
"->" { RET(DEREF); }
"&&" { RET(ANDAND); }
"||" { RET(OROR); }
"<=" { RET(LEQ); }
">=" { RET(GEQ); }
"==" { RET(EQL); }
"!=" { RET(NEQ); }
";" { RET(';'); }
"{" { RET('{'); }
"}" { RET('}'); }
"," { RET(','); }
":" { RET(':'); }
"=" { RET('='); }
"(" { RET('('); }
")" { RET(')'); }
"[" { RET('['); }
"]" { RET(']'); }
"." { RET('.'); }
"&" { RET('&'); }
"!" { RET('!'); }
"~" { RET('~'); }
"-" { RET('-'); }
"+" { RET('+'); }
"*" { RET('*'); }
"/" { RET('/'); }
"%" { RET('%'); }
"<" { RET('<'); }
">" { RET('>'); }
"^" { RET('^'); }
"|" { RET('|'); }
"?" { RET('?'); }
[ \t\v\f]+ { goto std; }
"\n"
{
if(cursor == s->eof) RET(EOI);
s->pos = cursor; s->line++;
goto std;
}
any
{
printf("unexpected character: %c\n", *s->tok);
goto std;
}
*/
comment:
/*!re2c
"*/" { goto std; }
"\n"
{
if(cursor == s->eof) RET(EOI);
s->tok = s->pos = cursor; s->line++;
goto comment;
}
any { goto comment; }
*/
}
main(){
Scanner in;
int t;
memset((char*) &in, 0, sizeof(in));
in.fd = 0;
while((t = scan(&in)) != EOI){
/*
printf("%d\t%.*s\n", t, in.cur - in.tok, in.tok);
printf("%d\n", t);
*/
}
close(in.fd);
}
-258
View File
@@ -1,258 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define ADDEQ 257
#define ANDAND 258
#define ANDEQ 259
#define ARRAY 260
#define ASM 261
#define AUTO 262
#define BREAK 263
#define CASE 264
#define CHAR 265
#define CONST 266
#define CONTINUE 267
#define DECR 268
#define DEFAULT 269
#define DEREF 270
#define DIVEQ 271
#define DO 272
#define DOUBLE 273
#define ELLIPSIS 274
#define ELSE 275
#define ENUM 276
#define EQL 277
#define EXTERN 278
#define FCON 279
#define FLOAT 280
#define FOR 281
#define FUNCTION 282
#define GEQ 283
#define GOTO 284
#define ICON 285
#define ID 286
#define IF 287
#define INCR 288
#define INT 289
#define LEQ 290
#define LONG 291
#define LSHIFT 292
#define LSHIFTEQ 293
#define MODEQ 294
#define MULEQ 295
#define NEQ 296
#define OREQ 297
#define OROR 298
#define POINTER 299
#define REGISTER 300
#define RETURN 301
#define RSHIFT 302
#define RSHIFTEQ 303
#define SCON 304
#define SHORT 305
#define SIGNED 306
#define SIZEOF 307
#define STATIC 308
#define STRUCT 309
#define SUBEQ 310
#define SWITCH 311
#define TYPEDEF 312
#define UNION 313
#define UNSIGNED 314
#define VOID 315
#define VOLATILE 316
#define WHILE 317
#define XOREQ 318
#define EOI 319
typedef unsigned int uint;
typedef unsigned char uchar;
#define BSIZE 8192
#define YYCTYPE uchar
#define YYCURSOR cursor
#define YYLIMIT s->lim
#define YYMARKER s->ptr
#define YYFILL(n) {cursor = fill(s, cursor);}
#define RET(i) {s->cur = cursor; return i;}
typedef struct Scanner {
int fd;
uchar *bot, *tok, *ptr, *cur, *pos, *lim, *top, *eof;
uint line;
} Scanner;
uchar *fill(Scanner *s, uchar *cursor){
if(!s->eof){
uint cnt = s->tok - s->bot;
if(cnt){
memcpy(s->bot, s->tok, s->lim - s->tok);
s->tok = s->bot;
s->ptr -= cnt;
cursor -= cnt;
s->pos -= cnt;
s->lim -= cnt;
}
if((s->top - s->lim) < BSIZE){
uchar *buf = (uchar*) malloc(((s->lim - s->bot) + BSIZE)*sizeof(uchar));
memcpy(buf, s->tok, s->lim - s->tok);
s->tok = buf;
s->ptr = &buf[s->ptr - s->bot];
cursor = &buf[cursor - s->bot];
s->pos = &buf[s->pos - s->bot];
s->lim = &buf[s->lim - s->bot];
s->top = &s->lim[BSIZE];
free(s->bot);
s->bot = buf;
}
if((cnt = read(s->fd, (char*) s->lim, BSIZE)) != BSIZE){
s->eof = &s->lim[cnt]; *(s->eof)++ = '\n';
}
s->lim += cnt;
}
return cursor;
}
int scan(Scanner *s){
uchar *cursor = s->cur;
std:
s->tok = cursor;
/*!re2c
any = [\000-\377];
O = [0-7];
D = [0-9];
L = [a-zA-Z_];
I = L|D;
H = [a-fA-F0-9];
E = [Ee] [+-]? D+;
FS = [fFlL];
IS = [uUlL]*;
ESC = [\\] ([abfnrtv?'"\\] | "x" H+ | O+);
X = any\[*/];
*/
/*!re2c
"/*" { goto comment; }
L { RET(ID); }
L I { RET(ID); }
L I I { RET(ID); }
L I I I { RET(ID); }
L I I I I { RET(ID); }
L I I I I I { RET(ID); }
L I I I I I I { RET(ID); }
L I I I I I I I { RET(ID); }
L I* { RET(ID); }
("0" [xX] H+ IS?) | ("0" D+ IS?) | (D+ IS?) |
(['] (ESC|any\[\n\\'])* ['])
{ RET(ICON); }
(D+ E FS?) | (D* "." D+ E? FS?) | (D+ "." D* E? FS?)
{ RET(FCON); }
(["] (ESC|any\[\n\\"])* ["])
{ RET(SCON); }
"..." { RET(ELLIPSIS); }
">>=" { RET(RSHIFTEQ); }
"<<=" { RET(LSHIFTEQ); }
"+=" { RET(ADDEQ); }
"-=" { RET(SUBEQ); }
"*=" { RET(MULEQ); }
"/=" { RET(DIVEQ); }
"%=" { RET(MODEQ); }
"&=" { RET(ANDEQ); }
"^=" { RET(XOREQ); }
"|=" { RET(OREQ); }
">>" { RET(RSHIFT); }
"<<" { RET(LSHIFT); }
"++" { RET(INCR); }
"--" { RET(DECR); }
"->" { RET(DEREF); }
"&&" { RET(ANDAND); }
"||" { RET(OROR); }
"<=" { RET(LEQ); }
">=" { RET(GEQ); }
"==" { RET(EQL); }
"!=" { RET(NEQ); }
";" { RET(';'); }
"{" { RET('{'); }
"}" { RET('}'); }
"," { RET(','); }
":" { RET(':'); }
"=" { RET('='); }
"(" { RET('('); }
")" { RET(')'); }
"[" { RET('['); }
"]" { RET(']'); }
"." { RET('.'); }
"&" { RET('&'); }
"!" { RET('!'); }
"~" { RET('~'); }
"-" { RET('-'); }
"+" { RET('+'); }
"*" { RET('*'); }
"/" { RET('/'); }
"%" { RET('%'); }
"<" { RET('<'); }
">" { RET('>'); }
"^" { RET('^'); }
"|" { RET('|'); }
"?" { RET('?'); }
[ \t\v\f]+ { goto std; }
"\n"
{
if(cursor == s->eof) RET(EOI);
s->pos = cursor; s->line++;
goto std;
}
any
{
printf("unexpected character: %c\n", *s->tok);
goto std;
}
*/
comment:
/*!re2c
"*/" { goto std; }
"\n"
{
if(cursor == s->eof) RET(EOI);
s->tok = s->pos = cursor; s->line++;
goto comment;
}
X { goto comment; }
X X { goto comment; }
X X X { goto comment; }
X X X X { goto comment; }
X X X X X { goto comment; }
X X X X X X { goto comment; }
X X X X X X X { goto comment; }
X X X X X X X X { goto comment; }
any { goto comment; }
*/
}
main(){
Scanner in;
int t;
memset((char*) &in, 0, sizeof(in));
in.fd = 0;
while((t = scan(&in)) != EOI){
/*
printf("%d\t%.*s\n", t, in.cur - in.tok, in.tok);
printf("%d\n", t);
*/
}
close(in.fd);
}
-202
View File
@@ -1,202 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef unsigned int uint;
typedef unsigned char uchar;
#define BSIZE 8192
#define YYCTYPE uchar
#define YYCURSOR cursor
#define YYLIMIT s->lim
#define YYMARKER s->ptr
#define YYFILL {cursor = fill(s, cursor);}
#define RETURN(i) {s->cur = cursor; return i;}
typedef struct Scanner {
int fd;
uchar *bot, *tok, *ptr, *cur, *pos, *lim, *top, *eof;
uint line;
} Scanner;
uchar *fill(Scanner *s, uchar *cursor){
if(!s->eof){
uint cnt = s->tok - s->bot;
if(cnt){
memcpy(s->bot, s->tok, s->lim - s->tok);
s->tok = s->bot;
s->ptr -= cnt;
cursor -= cnt;
s->pos -= cnt;
s->lim -= cnt;
}
if((s->top - s->lim) < BSIZE){
uchar *buf = (uchar*) malloc(((s->lim - s->bot) + BSIZE)*sizeof(uchar));
memcpy(buf, s->tok, s->lim - s->tok);
s->tok = buf;
s->ptr = &buf[s->ptr - s->bot];
cursor = &buf[cursor - s->bot];
s->pos = &buf[s->pos - s->bot];
s->lim = &buf[s->lim - s->bot];
s->top = &s->lim[BSIZE];
free(s->bot);
s->bot = buf;
}
if((cnt = read(s->fd, (char*) s->lim, BSIZE)) != BSIZE){
s->eof = &s->lim[cnt]; *(s->eof)++ = '\n';
}
s->lim += cnt;
}
return cursor;
}
int scan(Scanner *s){
uchar *cursor = s->cur;
uint depth;
std:
s->tok = cursor;
/*!re2c
any = [\000-\377];
digit = [0-9];
letter = [a-zA-Z];
*/
/*!re2c
"(*" { depth = 1; goto comment; }
digit + {RETURN(1);}
digit + / ".." {RETURN(1);}
[0-7] + "B" {RETURN(2);}
[0-7] + "C" {RETURN(3);}
digit [0-9A-F] * "H" {RETURN(4);}
digit + "." digit * ("E" ([+-]) ? digit +) ? {RETURN(5);}
['] (any\[\n']) * ['] | ["] (any\[\n"]) * ["] {RETURN(6);}
"#" {RETURN(7);}
"&" {RETURN(8);}
"(" {RETURN(9);}
")" {RETURN(10);}
"*" {RETURN(11);}
"+" {RETURN(12);}
"," {RETURN(13);}
"-" {RETURN(14);}
"." {RETURN(15);}
".." {RETURN(16);}
"/" {RETURN(17);}
":" {RETURN(18);}
":=" {RETURN(19);}
";" {RETURN(20);}
"<" {RETURN(21);}
"<=" {RETURN(22);}
"<>" {RETURN(23);}
"=" {RETURN(24);}
">" {RETURN(25);}
">=" {RETURN(26);}
"[" {RETURN(27);}
"]" {RETURN(28);}
"^" {RETURN(29);}
"{" {RETURN(30);}
"|" {RETURN(31);}
"}" {RETURN(32);}
"~" {RETURN(33);}
"AND" {RETURN(34);}
"ARRAY" {RETURN(35);}
"BEGIN" {RETURN(36);}
"BY" {RETURN(37);}
"CASE" {RETURN(38);}
"CONST" {RETURN(39);}
"DEFINITION" {RETURN(40);}
"DIV" {RETURN(41);}
"DO" {RETURN(42);}
"ELSE" {RETURN(43);}
"ELSIF" {RETURN(44);}
"END" {RETURN(45);}
"EXIT" {RETURN(46);}
"EXPORT" {RETURN(47);}
"FOR" {RETURN(48);}
"FROM" {RETURN(49);}
"IF" {RETURN(50);}
"IMPLEMENTATION" {RETURN(51);}
"IMPORT" {RETURN(52);}
"IN" {RETURN(53);}
"LOOP" {RETURN(54);}
"MOD" {RETURN(55);}
"MODULE" {RETURN(56);}
"NOT" {RETURN(57);}
"OF" {RETURN(58);}
"OR" {RETURN(59);}
"POINTER" {RETURN(60);}
"PROCEDURE" {RETURN(61);}
"QUALIFIED" {RETURN(62);}
"RECORD" {RETURN(63);}
"REPEAT" {RETURN(64);}
"RETURN" {RETURN(65);}
"SET" {RETURN(66);}
"THEN" {RETURN(67);}
"TO" {RETURN(68);}
"TYPE" {RETURN(69);}
"UNTIL" {RETURN(70);}
"VAR" {RETURN(71);}
"WHILE" {RETURN(72);}
"WITH" {RETURN(73);}
letter (letter | digit) * {RETURN(74);}
[ \t]+ { goto std; }
"\n"
{
if(cursor == s->eof) RETURN(0);
s->pos = cursor; s->line++;
goto std;
}
any
{
printf("unexpected character: %c\n", *s->tok);
goto std;
}
*/
comment:
/*!re2c
"*)"
{
if(--depth == 0)
goto std;
else
goto comment;
}
"(*" { ++depth; goto comment; }
"\n"
{
if(cursor == s->eof) RETURN(0);
s->tok = s->pos = cursor; s->line++;
goto comment;
}
any { goto comment; }
*/
}
/*
void putStr(FILE *o, char *s, uint l){
while(l-- > 0)
putc(*s++, o);
}
*/
main(){
Scanner in;
memset((char*) &in, 0, sizeof(in));
in.fd = 0;
while(scan(&in)){
/*
putc('<', stdout);
putStr(stdout, (char*) in.tok, in.cur - in.tok);
putc('>', stdout);
putc('\n', stdout);
*/
}
}
-295
View File
@@ -1,295 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define ADDEQ 257
#define ANDAND 258
#define ANDEQ 259
#define ARRAY 260
#define ASM 261
#define AUTO 262
#define BREAK 263
#define CASE 264
#define CHAR 265
#define CONST 266
#define CONTINUE 267
#define DECR 268
#define DEFAULT 269
#define DEREF 270
#define DIVEQ 271
#define DO 272
#define DOUBLE 273
#define ELLIPSIS 274
#define ELSE 275
#define ENUM 276
#define EQL 277
#define EXTERN 278
#define FCON 279
#define FLOAT 280
#define FOR 281
#define FUNCTION 282
#define GEQ 283
#define GOTO 284
#define ICON 285
#define ID 286
#define IF 287
#define INCR 288
#define INT 289
#define LEQ 290
#define LONG 291
#define LSHIFT 292
#define LSHIFTEQ 293
#define MODEQ 294
#define MULEQ 295
#define NEQ 296
#define OREQ 297
#define OROR 298
#define POINTER 299
#define REGISTER 300
#define RETURN 301
#define RSHIFT 302
#define RSHIFTEQ 303
#define SCON 304
#define SHORT 305
#define SIGNED 306
#define SIZEOF 307
#define STATIC 308
#define STRUCT 309
#define SUBEQ 310
#define SWITCH 311
#define TYPEDEF 312
#define UNION 313
#define UNSIGNED 314
#define VOID 315
#define VOLATILE 316
#define WHILE 317
#define XOREQ 318
#define EOI 319
#define PP_INCLUDE 500
#define PP_LINE 501
#define PP_DEFINE 502
#define PP_UNDEF 503
#define PP_IF 504
#define PP_IFDEF 505
#define PP_IFNDEF 506
#define PP_ELSE 507
#define PP_ELIF 508
#define PP_ENDIF 509
#define PP_ERROR 510
typedef unsigned int uint;
typedef unsigned char uchar;
#define BSIZE 12
//8192
#define YYCTYPE uchar
#define YYCURSOR cursor
#define YYLIMIT s->lim
#define YYMARKER s->ptr
#define YYFILL(n) {cursor = fill(s, cursor);}
#define RET(i) {s->cur = cursor; return i;}
typedef struct Scanner {
int fd;
uchar *bot, *tok, *ptr, *cur, *pos, *lim, *top, *eof;
uint line;
} Scanner;
uchar *fill(Scanner *s, uchar *cursor){
if(!s->eof) {
uint cnt = s->tok - s->bot;
if(cnt){
memcpy(s->bot, s->tok, s->lim - s->tok);
s->tok = s->bot;
s->ptr -= cnt;
cursor -= cnt;
s->pos -= cnt;
s->lim -= cnt;
}
if((s->top - s->lim) < BSIZE){
uchar *buf = (uchar*) malloc(((s->lim - s->bot) + BSIZE)*sizeof(uchar));
memcpy(buf, s->tok, s->lim - s->tok);
s->tok = buf;
s->ptr = &buf[s->ptr - s->bot];
cursor = &buf[cursor - s->bot];
s->pos = &buf[s->pos - s->bot];
s->lim = &buf[s->lim - s->bot];
s->top = &s->lim[BSIZE];
free(s->bot);
s->bot = buf;
}
if((cnt = read(s->fd, (char*) s->lim, BSIZE)) != BSIZE){
s->eof = &s->lim[cnt]; *(s->eof)++ = '\n';
}
s->lim += cnt;
}
return cursor;
}
int scan(Scanner *s){
uchar *cursor = s->cur;
std:
s->tok = cursor;
/*!re2c
any = [\000-\377];
O = [0-7];
D = [0-9];
L = [a-zA-Z_];
H = [a-fA-F0-9];
E = [Ee] [+-]? D+;
FS = [fFlL];
IS = [uUlL]*;
ESC = [\\] ([abfnrtv?'"\\] | "x" H+ | O+);
PP = "#" [ \t]*;
*/
/*!re2c
"/*" { goto comment; }
"auto" { RET(AUTO); }
"break" { RET(BREAK); }
"case" { RET(CASE); }
"char" { RET(CHAR); }
"const" { RET(CONST); }
"continue" { RET(CONTINUE); }
"default" { RET(DEFAULT); }
"do" { RET(DO); }
"double" { RET(DOUBLE); }
"else" { RET(ELSE); }
"enum" { RET(ENUM); }
"extern" { RET(EXTERN); }
"float" { RET(FLOAT); }
"for" { RET(FOR); }
"goto" { RET(GOTO); }
"if" { RET(IF); }
"int" { RET(INT); }
"long" { RET(LONG); }
"register" { RET(REGISTER); }
"return" { RET(RETURN); }
"short" { RET(SHORT); }
"signed" { RET(SIGNED); }
"sizeof" { RET(SIZEOF); }
"static" { RET(STATIC); }
"struct" { RET(STRUCT); }
"switch" { RET(SWITCH); }
"typedef" { RET(TYPEDEF); }
"union" { RET(UNION); }
"unsigned" { RET(UNSIGNED); }
"void" { RET(VOID); }
"volatile" { RET(VOLATILE); }
"while" { RET(WHILE); }
L (L|D)* { RET(ID); }
("0" [xX] H+ IS?) | ("0" D+ IS?) | (D+ IS?) |
(['] (ESC|any\[\n\\'])* ['])
{ RET(ICON); }
(D+ E FS?) | (D* "." D+ E? FS?) | (D+ "." D* E? FS?)
{ RET(FCON); }
(["] (ESC|any\[\n\\"])* ["])
{ RET(SCON); }
"..." { RET(ELLIPSIS); }
">>=" { RET(RSHIFTEQ); }
"<<=" { RET(LSHIFTEQ); }
"+=" { RET(ADDEQ); }
"-=" { RET(SUBEQ); }
"*=" { RET(MULEQ); }
"/=" { RET(DIVEQ); }
"%=" { RET(MODEQ); }
"&=" { RET(ANDEQ); }
"^=" { RET(XOREQ); }
"|=" { RET(OREQ); }
">>" { RET(RSHIFT); }
"<<" { RET(LSHIFT); }
"++" { RET(INCR); }
"--" { RET(DECR); }
"->" { RET(DEREF); }
"&&" { RET(ANDAND); }
"||" { RET(OROR); }
"<=" { RET(LEQ); }
">=" { RET(GEQ); }
"==" { RET(EQL); }
"!=" { RET(NEQ); }
";" { RET(';'); }
"{" { RET('{'); }
"}" { RET('}'); }
"," { RET(','); }
":" { RET(':'); }
"=" { RET('='); }
"(" { RET('('); }
")" { RET(')'); }
"[" { RET('['); }
"]" { RET(']'); }
"." { RET('.'); }
"&" { RET('&'); }
"!" { RET('!'); }
"~" { RET('~'); }
"-" { RET('-'); }
"+" { RET('+'); }
"*" { RET('*'); }
"/" { RET('/'); }
"%" { RET('%'); }
"<" { RET('<'); }
">" { RET('>'); }
"^" { RET('^'); }
"|" { RET('|'); }
"?" { RET('?'); }
PP "include" { RET(PP_INCLUDE); }
PP "line" { RET(PP_LINE); }
PP "define" { RET(PP_DEFINE); }
PP "undef" { RET(PP_UNDEF); }
PP "if" { RET(PP_IF); }
PP "ifdef" { RET(PP_IFDEF); }
PP "ifndef" { RET(PP_IFNDEF); }
PP "else" { RET(PP_ELSE); }
PP "elif" { RET(PP_ELIF); }
PP "endif" { RET(PP_ENDIF); }
PP "error" { RET(PP_ERROR); }
[ \t\v\f]+ { goto std; }
"\n"
{
if(cursor == s->eof) RET(EOI);
s->pos = cursor; s->line++;
goto std;
}
any
{
printf("unexpected character: %c\n", *s->tok);
goto std;
}
*/
comment:
/*!re2c
"*/" { goto std; }
"\n"
{
if(cursor == s->eof) RET(EOI);
s->tok = s->pos = cursor; s->line++;
goto comment;
}
any { goto comment; }
*/
}
main(){
Scanner in;
int t;
memset((char*) &in, 0, sizeof(in));
in.fd = 0;
while((t = scan(&in)) != EOI){
printf("%d\t%.*s\n", t, in.cur - in.tok, in.tok);
}
close(in.fd);
}
-340
View File
@@ -1,340 +0,0 @@
/*
* A push-model scanner example for re2c -f
* Written Mon Apr 11 2005 by mgix@mgix.com
* This file is in the public domain.
*
*/
// ----------------------------------------------------------------------
#include <fcntl.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#if defined(WIN32)
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#else
#include <stdint.h>
#include <unistd.h>
#ifndef O_BINARY
#define O_BINARY 0
#endif
#endif
// ----------------------------------------------------------------------
#define TOKENS \
\
TOK(kEOF) \
TOK(kEOL) \
TOK(kUnknown) \
TOK(kIdentifier) \
TOK(kDecimalConstant) \
\
TOK(kEqual) \
TOK(kLeftParen) \
TOK(kRightParen) \
TOK(kMinus) \
TOK(kPlus) \
TOK(kStar) \
TOK(kSlash) \
\
TOK(kIf) \
TOK(kFor) \
TOK(kElse) \
TOK(kGoto) \
TOK(kBreak) \
TOK(kWhile) \
TOK(kReturn) \
// ----------------------------------------------------------------------
static const char *tokenNames[] =
{
#define TOK(x) #x,
TOKENS
#undef TOK
};
// ----------------------------------------------------------------------
class PushScanner
{
public:
enum Token
{
#define TOK(x) x,
TOKENS
#undef TOK
};
private:
bool eof;
int32_t state;
uint8_t *limit;
uint8_t *start;
uint8_t *cursor;
uint8_t *marker;
uint8_t *buffer;
uint8_t *bufferEnd;
uint8_t yych;
uint32_t yyaccept;
public:
// ----------------------------------------------------------------------
PushScanner()
{
limit = 0;
start = 0;
state = -1;
cursor = 0;
marker = 0;
buffer = 0;
eof = false;
bufferEnd = 0;
}
// ----------------------------------------------------------------------
~PushScanner()
{
}
// ----------------------------------------------------------------------
void send(
Token token
)
{
size_t tokenSize = cursor-start;
const char *tokenName = tokenNames[token];
printf(
"scanner is pushing out a token of type %d (%s)",
token,
tokenName
);
if(token==kEOF) putchar('\n');
else
{
size_t tokenNameSize = strlen(tokenNames[token]);
size_t padSize = 20-(20<tokenNameSize ? 20 : tokenNameSize);
for(size_t i=0; i<padSize; ++i) putchar(' ');
printf(" : ---->");
fwrite(
start,
tokenSize,
1,
stdout
);
printf("<----\n");
}
}
// ----------------------------------------------------------------------
uint32_t push(
const void *input,
ssize_t inputSize
)
{
printf(
"scanner is receiving a new data batch of length %d\n"
"scanner continues with saved state = %d\n",
inputSize,
state
);
/*
* Data source is signaling end of file when batch size
* is less than maxFill. This is slightly annoying because
* maxFill is a value that can only be known after re2c does
* its thing. Practically though, maxFill is never bigger than
* the longest keyword, so given our grammar, 32 is a safe bet.
*/
uint8_t null[64];
const ssize_t maxFill = 32;
if(inputSize<maxFill)
{
eof = true;
input = null;
inputSize = sizeof(null);
memset(null, 0, sizeof(null));
}
/*
* When we get here, we have a partially
* consumed buffer which is in the following state:
* last valid char last valid buffer spot
* v v
* +-------------------+-------------+---------------+-------------+----------------------+
* ^ ^ ^ ^ ^ ^
* buffer start marker cursor limit bufferEnd
*
* We need to stretch the buffer and concatenate the new chunk of input to it
*
*/
size_t used = limit-buffer;
size_t needed = used+inputSize;
size_t allocated = bufferEnd-buffer;
if(allocated<needed)
{
size_t limitOffset = limit-buffer;
size_t startOffset = start-buffer;
size_t markerOffset = marker-buffer;
size_t cursorOffset = cursor-buffer;
buffer = (uint8_t*)realloc(buffer, needed);
bufferEnd = needed+buffer;
marker = markerOffset + buffer;
cursor = cursorOffset + buffer;
start = buffer + startOffset;
limit = limitOffset + buffer;
}
memcpy(limit, input, inputSize);
limit += inputSize;
// The scanner starts here
#define YYLIMIT limit
#define YYCURSOR cursor
#define YYMARKER marker
#define YYCTYPE uint8_t
#define SKIP(x) { start = cursor; goto yy0; }
#define SEND(x) { send(x); SKIP(); }
#define YYFILL(n) { goto fill; }
#define YYGETSTATE() state
#define YYSETSTATE(x) { state = (x); }
start:
/*!re2c
eol = "\n";
eof = "\000";
digit = [0-9];
integer = digit+;
alpha = [A-Za-z_];
any = [\000-\0377];
space = [ \h\t\v\f\r];
"if" { SEND(kIf); }
"for" { SEND(kFor); }
"else" { SEND(kElse); }
"goto" { SEND(kGoto); }
"break" { SEND(kBreak); }
"while" { SEND(kWhile); }
"return" { SEND(kReturn); }
alpha (alpha|digit)* { SEND(kIdentifier); }
integer { SEND(kDecimalConstant);}
"=" { SEND(kEqual); }
"(" { SEND(kLeftParen); }
")" { SEND(kRightParen); }
"-" { SEND(kMinus); }
"+" { SEND(kPlus); }
"*" { SEND(kStar); }
"/" { SEND(kSlash); }
eol { SKIP(); }
space { SKIP(); }
eof { send(kEOF); return 1; }
any { SEND(kUnknown); }
*/
fill:
ssize_t unfinishedSize = cursor-start;
printf(
"scanner needs a refill. Exiting for now with:\n"
" saved fill state = %d\n"
" unfinished token size = %d\n",
state,
unfinishedSize
);
if(0<unfinishedSize && start<limit)
{
printf(" unfinished token is :");
fwrite(start, 1, cursor-start, stdout);
putchar('\n');
}
putchar('\n');
/*
* Once we get here, we can get rid of
* everything before start and after limit.
*/
if(eof==true) goto start;
if(buffer<start)
{
size_t startOffset = start-buffer;
memmove(buffer, start, limit-start);
marker -= startOffset;
cursor -= startOffset;
limit -= startOffset;
start -= startOffset;
}
return 0;
}
};
// ----------------------------------------------------------------------
int main(
int argc,
char **argv
)
{
// Parse cmd line
int input = 0;
if(1<argc)
{
input = open(argv[1], O_RDONLY | O_BINARY);
if(input<0)
{
fprintf(
stderr,
"could not open file %s\n",
argv[1]
);
exit(1);
}
}
/*
* Tokenize input file by pushing batches
* of data one by one into the scanner.
*/
const size_t batchSize = 256;
uint8_t buffer[batchSize];
PushScanner scanner;
while(1)
{
ssize_t n = read(input, buffer, batchSize);
scanner.push(buffer, n);
if(n<batchSize) break;
}
scanner.push(0, -1);
close(input);
// Done
return 0;
}
-44
View File
@@ -1,44 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define RET(n) printf("%d\n", n); return n
int scan(char *s, int l){
char *p = s;
char *q;
#define YYCTYPE char
#define YYCURSOR p
#define YYLIMIT (s+l)
#define YYMARKER q
#define YYFILL(n)
/*!re2c
'a'{1}"\n" {RET(1);}
'a'{2,3}"\n" {RET(2);}
'a'{6}"\n" {RET(4);}
'a'{4,}"\n" {RET(3);}
[^aq]|"\n" {RET(0);}
*/
}
#define do_scan(str) scan(str, strlen(str))
main()
{
do_scan("a\n");
do_scan("aa\n");
do_scan("aaa\n");
do_scan("aaaa\n");
do_scan("q");
do_scan("a");
do_scan("A\n");
do_scan("AA\n");
do_scan("aAa\n");
do_scan("AaaA\n");
do_scan("Q");
do_scan("AaaAa\n");
do_scan("AaaAaA\n");
do_scan("A");
do_scan("\n");
do_scan("0");
}
-1
View File
@@ -1 +0,0 @@
Replacement modules for an existing REXX interpreter. Not standalone.
-319
View File
@@ -1,319 +0,0 @@
#include "scanio.h"
#include "scanner.h"
#define CURSOR ch
#define LOADCURSOR ch = *cursor;
#define ADVANCE cursor++;
#define BACK(n) cursor -= (n);
#define CHECK(n) if((ScanCB.lim - cursor) < (n)){cursor = ScanFill(cursor);}
#define MARK(n) ScanCB.ptr = cursor; sel = (n);
#define REVERT cursor = ScanCB.ptr;
#define MARKER sel
#define RETURN(i) {ScanCB.cur = cursor; return i;}
int ScanToken(){
uchar *cursor = ScanCB.cur;
unsigned sel;
uchar ch;
ScanCB.tok = cursor;
ScanCB.eot = NULL;
/*!re2c
all = [\000-\377];
eof = [\000];
any = all\eof;
letter = [a-z]|[A-Z];
digit = [0-9];
symchr = letter|digit|[.!?_];
const = (digit|[.])symchr*([eE][+-]?digit+)?;
simple = (symchr\(digit|[.]))(symchr\[.])*;
stem = simple [.];
symbol = symchr*;
sqstr = ['] ((any\['\n])|(['][']))* ['];
dqstr = ["] ((any\["\n])|(["]["]))* ["];
str = sqstr|dqstr;
ob = [ \t]*;
not = [\\~];
A = [aA];
B = [bB];
C = [cC];
D = [dD];
E = [eE];
F = [fF];
G = [gG];
H = [hH];
I = [iI];
J = [jJ];
K = [kK];
L = [lL];
M = [mM];
N = [nN];
O = [oO];
P = [pP];
Q = [qQ];
R = [rR];
S = [sS];
T = [tT];
U = [uU];
V = [vV];
W = [wW];
X = [xX];
Y = [yY];
Z = [zZ];
*/
scan:
/*!re2c
"\n"
{
++(ScanCB.lineNum);
ScanCB.linePos = ScanCB.pos + (cursor - ScanCB.mrk);
RETURN(SU_EOL);
}
"|" ob "|"
{ RETURN(OP_CONCAT); }
"+"
{ RETURN(OP_PLUS); }
"-"
{ RETURN(OP_MINUS); }
"*"
{ RETURN(OP_MULT); }
"/"
{ RETURN(OP_DIV); }
"%"
{ RETURN(OP_IDIV); }
"/" ob "/"
{ RETURN(OP_REMAIN); }
"*" ob "*"
{ RETURN(OP_POWER); }
"="
{ RETURN(OP_EQUAL); }
not ob "=" | "<" ob ">" | ">" ob "<"
{ RETURN(OP_EQUAL_N); }
">"
{ RETURN(OP_GT); }
"<"
{ RETURN(OP_LT); }
">" ob "=" | not ob "<"
{ RETURN(OP_GE); }
"<" ob "=" | not ob ">"
{ RETURN(OP_LE); }
"=" ob "="
{ RETURN(OP_EQUAL_EQ); }
not ob "=" ob "="
{ RETURN(OP_EQUAL_EQ_N); }
">" ob ">"
{ RETURN(OP_GT_STRICT); }
"<" ob "<"
{ RETURN(OP_LT_STRICT); }
">" ob ">" ob "=" | not ob "<" ob "<"
{ RETURN(OP_GE_STRICT); }
"<" ob "<" ob "=" | not ob ">" ob ">"
{ RETURN(OP_LE_STRICT); }
"&"
{ RETURN(OP_AND); }
"|"
{ RETURN(OP_OR); }
"&" ob "&"
{ RETURN(OP_XOR); }
not
{ RETURN(OP_NOT); }
":"
{ RETURN(SU_COLON); }
","
{ RETURN(SU_COMMA); }
"("
{ RETURN(SU_POPEN); }
")"
{ RETURN(SU_PCLOSE); }
";"
{ RETURN(SU_EOC); }
A D D R E S S
{ RETURN(RX_ADDRESS); }
A R G
{ RETURN(RX_ARG); }
C A L L
{ RETURN(RX_CALL); }
D O
{ RETURN(RX_DO); }
D R O P
{ RETURN(RX_DROP); }
E L S E
{ RETURN(RX_ELSE); }
E N D
{ RETURN(RX_END); }
E X I T
{ RETURN(RX_EXIT); }
I F
{ RETURN(RX_IF); }
I N T E R P R E T
{ RETURN(RX_INTERPRET); }
I T E R A T E
{ RETURN(RX_ITERATE); }
L E A V E
{ RETURN(RX_LEAVE); }
N O P
{ RETURN(RX_NOP); }
N U M E R I C
{ RETURN(RX_NUMERIC); }
O P T I O N S
{ RETURN(RX_OPTIONS); }
O T H E R W I S E
{ RETURN(RX_OTHERWISE); }
P A R S E
{ RETURN(RX_PARSE); }
P R O C E D U R E
{ RETURN(RX_PROCEDURE); }
P U L L
{ RETURN(RX_PULL); }
P U S H
{ RETURN(RX_PUSH); }
Q U E U E
{ RETURN(RX_QUEUE); }
R E T U R N
{ RETURN(RX_RETURN); }
S A Y
{ RETURN(RX_SAY); }
S E L E C T
{ RETURN(RX_SELECT); }
S I G N A L
{ RETURN(RX_SIGNAL); }
T H E N
{ RETURN(RX_THEN); }
T R A C E
{ RETURN(RX_TRACE); }
W H E N
{ RETURN(RX_WHEN); }
O F F
{ RETURN(RXS_OFF); }
O N
{ RETURN(RXS_ON); }
B Y
{ RETURN(RXS_BY); }
D I G I T S
{ RETURN(RXS_DIGITS); }
E N G I N E E R I N G
{ RETURN(RXS_ENGINEERING); }
E R R O R
{ RETURN(RXS_ERROR); }
E X P O S E
{ RETURN(RXS_EXPOSE); }
F A I L U R E
{ RETURN(RXS_FAILURE); }
F O R
{ RETURN(RXS_FOR); }
F O R E V E R
{ RETURN(RXS_FOREVER); }
F O R M
{ RETURN(RXS_FORM); }
F U Z Z
{ RETURN(RXS_FUZZ); }
H A L T
{ RETURN(RXS_HALT); }
L I N E I N
{ RETURN(RXS_LINEIN); }
N A M E
{ RETURN(RXS_NAME); }
N O T R E A D Y
{ RETURN(RXS_NOTREADY); }
N O V A L U E
{ RETURN(RXS_NOVALUE); }
S C I E N T I F I C
{ RETURN(RXS_SCIENTIFIC); }
S O U R C E
{ RETURN(RXS_SOURCE); }
S Y N T A X
{ RETURN(RXS_SYNTAX); }
T O
{ RETURN(RXS_TO); }
U N T I L
{ RETURN(RXS_UNTIL); }
U P P E R
{ RETURN(RXS_UPPER); }
V A L U E
{ RETURN(RXS_VALUE); }
V A R
{ RETURN(RXS_VAR); }
V E R S I O N
{ RETURN(RXS_VERSION); }
W H I L E
{ RETURN(RXS_WHILE); }
W I T H
{ RETURN(RXS_WITH); }
const
{ RETURN(SU_CONST); }
simple
{ RETURN(SU_SYMBOL); }
stem
{ RETURN(SU_SYMBOL_STEM); }
symbol
{ RETURN(SU_SYMBOL_COMPOUND); }
str
{ RETURN(SU_LITERAL); }
str [bB] / (all\symchr)
{ RETURN(SU_LITERAL_BIN); }
str [xX] / (all\symchr)
{ RETURN(SU_LITERAL_HEX); }
eof
{ RETURN(SU_EOF); }
any
{ RETURN(SU_ERROR); }
*/
}
bool StripToken(){
uchar *cursor = ScanCB.cur;
unsigned depth;
uchar ch;
bool blanks = FALSE;
ScanCB.eot = cursor;
strip:
/*!re2c
"/*"
{
depth = 1;
goto comment;
}
"\r"
{ goto strip; }
[ \t]
{
blanks = TRUE;
goto strip;
}
[] / all
{ RETURN(blanks); }
*/
comment:
/*!re2c
"*/"
{
if(--depth == 0)
goto strip;
else
goto comment;
}
"\n"
{
++(ScanCB.lineNum);
ScanCB.linePos = ScanCB.pos + (cursor - ScanCB.mrk);
goto comment;
}
"/*"
{
++depth;
goto comment;
}
eof
{ RETURN(blanks); }
any
{
goto comment;
}
*/
}
-41
View File
@@ -1,41 +0,0 @@
uchar *ScanFill(uchar *cursor){
unsigned cnt = s->tok - s->bot;
s->pos += cursor - s->mrk;
if(cnt){
if(s->eot){
unsigned len = s->eot - s->tok;
memcpy(s->bot, s->tok, len);
s->eot = &s->bot[len];
if((len = s->lim - cursor) != 0)
memcpy(s->eot, cursor, len);
cursor = s->eot;
s->lim = &cursor[len];
} else {
memcpy(s->bot, s->tok, s->lim - s->tok);
cursor -= cnt;
s->lim -= cnt;
}
s->tok = s->bot;
s->ptr -= cnt;
}
if((s->top - s->lim) < 512){
uchar *buf = (uchar*) malloc(((s->lim - s->bot) + 512)*sizeof(uchar));
memcpy(buf, s->bot, s->lim - s->bot);
s->tok = buf;
s->ptr = &buf[s->ptr - s->bot];
if(s->eot)
s->eot = &buf[s->eot - s->bot];
cursor = &buf[cursor - s->bot];
s->lim = &buf[s->lim - s->bot];
s->top = &s->lim[512];
free(s->bot);
s->bot = buf;
}
s->mrk = cursor;
if(ScanCBIO.file){
if((cnt = read(ScanCBIO.u.f.fd, (char*) s->lim, 512)) != 512)
memset(&s->lim[cnt], 0, 512 - cnt);
s->lim += 512;
}
return cursor;
}
-7
View File
@@ -1,7 +0,0 @@
/*!re2c
"print" {return PRINT;}
[a-z]+ {return ID;}
[0-9]+ {return DEC;}
"0x" [0-9a-f]+ {return HEX;}
[\000-\377] {return ERR;}
*/
-13
View File
@@ -1,13 +0,0 @@
#define NULL ((char*) 0)
char *scan(char *p){
char *q;
#define YYCTYPE char
#define YYCURSOR p
#define YYLIMIT p
#define YYMARKER q
#define YYFILL(n)
/*!re2c
[0-9]+ {return YYCURSOR;}
[\000-\377] {return NULL;}
*/
}
-706
View File
@@ -1,706 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Manpage of RE2C</title>
</head>
<body>
<h1>RE2C</h1>
Section: User Commands (1)<br />
Updated: @PACKAGE_DATE@<br />
<a href="#index">Index</a>
<hr />
<a name="lbAB" id="lbAB">&nbsp;</a>
<h2>NAME</h2>
<p>re2c - convert regular expressions to C/C++</p>
<a name="lbAC" id="lbAC">&nbsp;</a>
<h2>SYNOPSIS</h2>
<p><b>re2c</b> [<b>-bdefFghisuvVw1</b>] [<b>-o output</b>] [<b>-c</b> [<b>-t header</b>]] file</p>
<a name="lbAD" id="lbAD">&nbsp;</a>
<h2>DESCRIPTION</h2>
<p><b>re2c</b> is a preprocessor that generates C-based recognizers from
regular expressions. The input to <b>re2c</b> consists of C/C++ source
interleaved with comments of the form /*!re2c ... */ which contain scanner
specifications. In the output these comments are replaced with code that, when
executed, will find the next input token and then execute some user-supplied
token-specific code.</p>
<p>For example, given the following code</p>
<pre>
char *scan(char *p)
{
/*!re2c
re2c:define:YYCTYPE = "unsigned char";
re2c:define:YYCURSOR = p;
re2c:yyfill:enable = 0;
re2c:yych:conversion = 1;
re2c:indent:top = 1;
[0-9]+ {return p;}
[^] {return (char*)0;}
*/
}
</pre>
<br />
<br />
<p><b>re2c -is</b> will generate</p>
<pre>
/* Generated by re2c on Sat Apr 16 11:40:58 1994 */
char *scan(char *p)
{
{
unsigned char yych;
yych = (unsigned char)*p;
if(yych &lt;= '/') goto yy4;
if(yych &gt;= ':') goto yy4;
++p;
yych = (unsigned char)*p;
goto yy7;
yy3:
{return p;}
yy4:
++p;
yych = (unsigned char)*p;
{return char*)0;}
yy6:
++p;
yych = (unsigned char)*p;
yy7:
if(yych &lt;= '/') goto yy3;
if(yych &lt;= '9') goto yy6;
goto yy3;
}
}
</pre>
<br />
<br />
<p>You can place one /*!max:re2c */ comment that will output a "#define YYMAXFILL
&lt;n&gt;" line that holds the maximum number of characters
required to parse the input. That is the maximum value YYFILL(n)
will receive. If -1 is in effect then YYMAXFILL can be triggered once
after the last /*!re2c */.</p>
<p>You can also use /*!ignore:re2c */ blocks that allows to document the
scanner code and will not be part of the output.</p>
<a name="lbAE" id="lbAE">&nbsp;</a>
<h2>OPTIONS</h2>
<p><b>re2c</b> provides the following options:</p>
<dl compact="compact">
<dt><b>-?</b></dt>
<dd><b>-h</b> Invoke a short help.<br /><br /></dd>
<dt><b>-b</b></dt>
<dd>Implies <b>-s</b>. Use bit vectors as well in the attempt to coax better
code out of the compiler. Most useful for specifications with more than a few
keywords (e.g. for most programming languages).<br /><br /></dd>
<dt><b>-c</b></dt>
<dd>Used to support (f)lex-like condition support.<br /><br /></dd>
<dt><b>-d</b></dt>
<dd>Creates a parser that dumps information about the current position and in
which state the parser is while parsing the input. This is useful to debug
parser issues and states. If you use this switch you need to define a macro
<i>YYDEBUG</i> that is called like a function with two parameters: <i>void
YYDEBUG(int state, char current)</i>. The first parameter receives the state or
-1 and the second parameter receives the input at the current cursor.<br /><br /></dd>
<dt><b>-D</b></dt>
<dd>Emit Graphviz dot data. It can then be processed with e.g.
"dot -Tpng input.dot > output.png". Please note that scanners with many states
may crash dot.<br /><br /></dd>
<dt><b>-e</b></dt>
<dd>Cross-compile from an ASCII platform to an EBCDIC one.<br /><br /></dd>
<dt><b>-f</b></dt>
<dd>Generate a scanner with support for storable state. For details see below
at <b>SCANNER WITH STORABLE STATES</b>.<br /><br /></dd>
<dt><b>-F</b><dt>
<dd>Partial support for flex syntax. When this flag is active then named
definitions must be surrounded by curly braces and can be defined without an
equal sign and the terminating semi colon. Instead names are treated as direct
double quoted strings.<br /><br /></dd>
<dt><b>-g</b></dt>
<dd>Generate a scanner that utilizes GCC's computed goto feature. That is re2c
generates jump tables whenever a decision is of a certain complexity (e.g. a
lot of if conditions are otherwise necessary). This is only useable with GCC
and produces output that cannot be compiled with any other compiler. Note that
this implies -b and that the complexity threshold can be configured using the
inplace configuration "cgoto:threshold".</dd>
<dt><b>-i</b></dt>
<dd>Do not output #line information. This is useful when you want use a CMS
tool with the re2c output which you might want if you do not require your users
to have re2c themselves when building from your source. <b>-o output</b>
Specify the output file.<br /><br /></dd>
<dt><b>-r</b></dt>
<dd>Allows reuse of scanner definitions with '<b>/*!use:re2c</b>' after
'<b>/*!rules:re2c</b>'. In this mode no '<b>/*!re2c</b>' block and exactly one
'<b>/*!use:re2c</b>' must be present. The rules are being saved and used by
every '<b>/*!repeat:re2c</b>' block that follows. These blocks can contain
inplace configurations, especially '<b>re2c:flags:w</b>' and '<b>re2c:flags:u</b>'.
That way it is possible to create the same scanner multiple times for different
character types, different input mechanisms or different output mechanisms.
The '<b>/*!use:re2c</b>' blocks can also contain additional rules that will be
appended to the set of rules in '<b>/*!rules:re2c</b>'.
<br /><br /></dd>
<dt><b>-s</b></dt>
<dd>Generate nested ifs for some switches. Many compilers need this assist to
generate better code.<br /><br /></dd>
<dt><b>-t</b></dt>
<dd>Create a header file that contains types for the (f)lex-like condition support.
This can only be activated when <b>-c</b> is in use.<br /><br /></dd>
<dt><b>-u</b></dt>
<dd>Generate a parser that supports Unicode chars (UTF-32). This means the
generated code can deal with any valid Unicode character up to 0x10FFFF. When
UTF-8 or UTF-16 needs to be supported you need to convert the incoming stream
to UTF-32 upon input yourself.<br /><br /></dd>
<dt><b>-v</b></dt>
<dd>Show version information.<br /><br /></dd>
<dt><b>-V</b></dt>
<dd>Show the version as a number XXYYZZ.<br /><br /></dd>
<dt><b>-w</b></dt>
<dd>Create a parser that supports wide chars (UCS-2). This implies <b>-s</b>
and cannot be used together with <b>-e</b> switch.<br /><br /></dd>
<dt><b>-1</b></dt>
<dd>Force single pass generation, this cannot be combined with -f and disables
YYMAXFILL generation prior to last re2c block.<br /><br /></dd>
<dt><b>--no-generation-date</b></dt>
<dd>Suppress date output in the generated output so that it only shows the re2c
version.<br /><br /></dd>
<dt><b>--case-insensitive</b></dt>
<dd>All strings are case insensitive, so all "-expressions are treated
in the same way '-expressions are.<br /><br /></dd>
<dt><b>--case-inverted</b></dt>
<dd>Invert the meaning of single and double quoted strings.
With this switch single quotes are case sensitive and
double quotes are case insensitive.<br /><br /></dd>
</dl>
<br />
<br />
<a name="lbAF" id="lbAF">&nbsp;</a>
<h2>INTERFACE CODE</h2>
<p>Unlike other scanner generators, <b>re2c</b> does not generate complete
scanners: the user must supply some interface code. In particular, the user
must define the following macros or use the
corresponding inplace configurations:</p>
<dl compact="compact">
<dt>YYCONDTYPE</dt>
<dd>In <b>-c</b> mode you can use <b>-t</b> to generate a file that contains the
enumeration used as conditions. Each of the values refers to a condition of
a rule set.</dd>
<dt>YYCTXMARKER</dt>
<dd><i>l</i>-expression of type *YYCTYPE. The generated code saves context
backtracking information in YYCTXMARKER. The user only needs to define this
macro if a scanner specification uses trailing context in one or more of its
regular expressions.<br /><br /></dd>
<dt>YYCTYPE</dt>
<dd>Type used to hold an input symbol. Usually char or unsigned char.<br /><br /></dd>
<dt>YYCURSOR</dt>
<dd><i>l</i>-expression of type *YYCTYPE that points to the current input
symbol. The generated code advances YYCURSOR as symbols are matched. On entry,
YYCURSOR is assumed to point to the first character of the current token. On
exit, YYCURSOR will point to the first character of the following token.<br /><br /></dd>
<dt>YYDEBUG(<i>state</i>,<i>current</i>)</dt>
<dd>This is only needed if the <b>-d</b> flag was specified. It allows to
easily debug the generated parser by calling a user defined function for every
state. The function should have the following signature: <i>void YYDEBUG(int
state, char current)</i>. The first parameter receives the state or -1 and the
second parameter receives the input at the current cursor.<br /><br /></dd>
<dt>YYFILL(<i>n</i>)</dt>
<dd>The generated code "calls" YYFILL(n) when the buffer needs (re)filling: at
least <i>n</i> additional characters should be provided. YYFILL(n) should adjust
YYCURSOR, YYLIMIT, YYMARKER and YYCTXMARKER as needed. Note that for typical
programming languages <i>n</i> will be the length of the longest keyword plus
one. The user can place a comment of the form /*!max:re2c */ once to insert
a YYMAXFILL definition that is set to the maximum length value. If -1
switch is used then YYMAXFILL can be triggered only once after the
last /*!re2c */ block.<br /><br /></dd>
<dt>YYGETCONDITION()</dt>
<dd>This define is used to get the condition prior to entering the scanner code
when using <b>-c</b> switch. The value must be initialized with a value from
the enumeration YYCONDTYPE type.</dd>
<dt>YYGETSTATE()</dt>
<dd>The user only needs to define this macro if the <b>-f</b> flag was
specified. In that case, the generated code "calls" YYGETSTATE() at the very
beginning of the scanner in order to obtain the saved state. YYGETSTATE() must
return a signed integer. The value must be either -1, indicating that the
scanner is entered for the first time, or a value previously saved by
YYSETSTATE(s). In the second case, the scanner will resume operations right after
where the last YYFILL(n) was called.<br /><br /></dd>
<dt>YYLIMIT</dt>
<dd>Expression of type *YYCTYPE that marks the end of the buffer (YYLIMIT[-1] is
the last character in the buffer). The generated code repeatedly compares
YYCURSOR to YYLIMIT to determine when the buffer needs (re)filling.<br /><br /></dd>
<dt>YYMARKER</dt>
<dd><i>l</i>-expression of type *YYCTYPE. The generated code saves backtracking
information in YYMARKER. Some easy scanners might not use this.<br /><br /></dd>
<dt>YYMAXFILL</dt>
<dd>This will be automatically defined by /*!max:re2c */ blocks as explained
above.<br /><br /></dd>
<dt>YYSETCONDITION(<i>c</i>)</dt>
<dd>This define is used to set the condition in transition rules. This is only
being used when <b>-c</b> is active and transition rules are being used.<br /><br /></dd>
<dt>YYSETSTATE(<i>s</i>)</dt>
<dd>The user only needs to define this macro if the <b>-f</b> flag was
specified. In that case, the generated code "calls" YYSETSTATE just before
calling YYFILL(n). The parameter to YYSETSTATE(s) is a signed integer that uniquely
identifies the specific instance of YYFILL(n) that is about to be called. Should
the user wish to save the state of the scanner and have YYFILL(n) return to the
caller, all he has to do is store that unique identifier in a variable. Later,
when the scanner is called again, it will call YYGETSTATE() and resume
execution right where it left off. The generated code will contain
both YYSETSTATE(s) and YYGETSTATE() even if YYFILL(n) is being
disabled.<br /><br /></dd>
</dl>
<br />
<br />
<a name="lbAG" id="lbAG">&nbsp;</a>
<h2>SCANNER WITH STORABLE STATES</h2>
<p>When the <b>-f</b> flag is specified, re2c generates a scanner that can
store its current state, return to the caller, and later resume operations
exactly where it left off.</p>
<p>The default operation of re2c is a "pull" model, where the scanner asks for
extra input whenever it needs it. However, this mode of operation assumes that
the scanner is the "owner" the parsing loop, and that may not always be
convenient.</p>
<p>Typically, if there is a preprocessor ahead of the scanner in the stream, or
for that matter any other procedural source of data, the scanner cannot "ask"
for more data unless both scanner and source live in a separate threads.</p>
<p>The <b>-f</b> flag is useful for just this situation : it lets users design
scanners that work in a "push" model, i.e. where data is fed to the scanner
chunk by chunk. When the scanner runs out of data to consume, it just stores
its state, and return to the caller. When more input data is fed to the
scanner, it resumes operations exactly where it left off.</p>
<p>When using the -f option re2c does not accept stdin because it has to do the
full generation process twice which means it has to read the input twice. That
means re2c would fail in case it cannot open the input twice or reading the
input for the first time influences the second read attempt.</p>
<p>Changes needed compared to the "pull" model.</p>
<p>1. User has to supply macros YYSETSTATE() and YYGETSTATE(state)</p>
<p>2. The <b>-f</b> option inhibits declaration of <i>yych</i> and
<i>yyaccept</i>. So the user has to declare these. Also the user has to save
and restore these. In the example <i>examples/push.re</i> these are declared as
fields of the (C++) class of which the scanner is a method, so they do not need
to be saved/restored explicitly. For C they could e.g. be made macros that
select fields from a structure passed in as parameter. Alternatively, they
could be declared as local variables, saved with YYFILL(n) when it decides
to return and restored at entry to the function. Also, it could be more
efficient to save the state from YYFILL(n) because
YYSETSTATE(state) is called unconditionally. YYFILL(n) however does not
get <i>state</i> as parameter, so we would have to store state in a local
variable by YYSETSTATE(state).</p>
<p>3. Modify YYFILL(n) to return (from
the function calling it) if more input is needed.</p>
<p>4. Modify caller to recognise "more input is needed" and respond
appropriately.</p>
<p>5.The generated code will contain a switch block that is used to restores
the last state by jumping behind the corresponding YYFILL(n) call. This code is
automatically generated in the epilog of the first "/*!re2c */" block.
It is possible to trigger generation of the YYGETSTATE() block earlier by
placing a "/*!getstate:re2c */" comment. This is especially useful when
the scanner code should be wrapped inside a loop.</p>
<p>Please see examples/push.re for push-model scanner. The generated code can be
tweaked using inplace configurations "state:abort" and "state:nextlabel".</p>
<a name="lbAH" id="lbAH">&nbsp;</a>
<h2>SCANNER WITH CONDITION SUPPORT</h2>
<p>
You can precede regular-expressions with a list of condition names when using the <b>-c</b>
switch. In this case <b>re2c</b> generates scanner blocks for each condition. Where each of the
generated scanners has its own precondition. The precondition is given by the
interface define <b>YYGETCONDITION</b> and must be of type <b>YYCONDTYPE</b>.
</p><p>
There are two special rule types. First, the rules of the condition '*' are
merged to all conditions. And second the empty condition list allows to
provide a code block that does not have a scanner part. Meaning it does not
allow any regular expression. The condition value referring to this special
block is always the one with the enumeration value 0. This way the code of this
special rule can be used to initialize a scanner. It is in no way necessary to
have these rules: but sometimes it is helpful to have a dedicated uninitialized
condition state.
</p><p>
Non empty rules allow to specify the new condition, which makes them
transition rules. Besides generating calls for the define <b>YYSETCONDITION</b>
no other special code is generated.
</p>
<p>
There is another kind of special rules that allow to prepend code to any code
block of all rules of a certain set of conditions or to all code blocks to all
rules. This can be helpful when some operation is common among rules. For
instance this can be used to store the length of the scanned string. These
special setup rules start with an exclamation mark followed by either a list
of conditions <b>&lt;! condition, ... &gt;</b> or a star <b>&lt;!*&gt;</b>.
When <b>re2c</b> generates the code for a rule whose state does not have a
setup rule and a star'd setup rule is present, than that code will be used
as setup code.
</p>
<a name="lbAI" id="lbAI">&nbsp;</a>
<h2>SCANNER SPECIFICATIONS</h2>
<p>Each scanner specification consists of a set of <i>rules</i>, <i>named
definitions</i> and <i>configurations</i>.</p>
<p><i>Rules</i> consist of a regular expression along with a block of C/C++
code that is to be executed when the associated <i>regular expression</i> is
matched. You can either
start the code with an opening curly brace or the sequence '<b>:=</b>'. When
the code with a curly brace then <b>re2c</b> counts the brace depth and stops looking
for code automatically. Otherwise curly braces are not allowed and <b>re2c</b> stops
looking for code at the first line that does not begin with whitespace.</p>
<dl compact="compact">
<dd><i>regular-expression</i> { <i>C/C++ code</i> }</dd>
<dd><i>regular-expression</i> := <i>C/C++ code</i></dd>
</dl>
<p>
If <b>-c</b> is active then each regular expression is preceded by a list of
comma separated condition names. Besides normal naming rules there are two
special cases. A rule may contain the single condition name '*' and no condition
name at all. In the latter case the rule cannot have a regular expression. Non
empty rules may further more specify the new condition. In that case re2c will
generated the necessary code to change the condition automatically. Just as above
code can be started with a curly brace of the sequence '<b>:=</b>'. Further more
rules can use ':=>' as a shortcut to automatically generate code that not only
sets the new condition state but also continues execution with the new state. A
shortcut rule should not be used in a loop where there is code between the start
of the loop and the <b>re2c</b> block unless <i>re2c:cond:goto</i> is changed
to '<i>continue;</i>'. If code is necessary before all rule (though not simple
jumps) you can do so by using &lt;! pseudo-rules.
</p>
<dl compact="compact">
<dd>&lt;<i>condition-list</i>&gt; <i>regular-expression</i> { <i>C/C++ code</i> }</dd>
<dd>&lt;<i>condition-list</i>&gt; <i>regular-expression</i> := <i>C/C++ code</i></dd>
<dd>&lt;<i>condition-list</i>&gt; <i>regular-expression</i> =&gt; <i>condition</i> { <i>C/C++ code</i> }</dd>
<dd>&lt;<i>condition-list</i>&gt; <i>regular-expression</i> =&gt; <i>condition</i> := <i>C/C++ code</i></dd>
<dd>&lt;<i>condition-list</i>&gt; <i>regular-expression</i> :=&gt; <i>condition</i></dd>
<dd>&lt;<i>*</i>&gt; <i>regular-expression</i> { <i>C/C++ code</i> }</dd>
<dd>&lt;<i>*</i>&gt; <i>regular-expression</i> := <i>C/C++ code</i></dd>
<dd>&lt;<i>*</i>&gt; <i>regular-expression</i> =&gt; <i>condition</i> { <i>C/C++ code</i> }</dd>
<dd>&lt;<i>*</i>&gt; <i>regular-expression</i> =&gt; <i>condition</i> := <i>C/C++ code</i></dd>
<dd>&lt;<i>*</i>&gt; <i>regular-expression</i> :=&gt; <i>condition</i></dd>
<dd>&lt;&gt; { <i>C/C++ code</i> }</dd>
<dd>&lt;&gt; := <i>C/C++ code</i></dd>
<dd>&lt;&gt; =&gt; <i>condition</i> { <i>C/C++ code</i> }</dd>
<dd>&lt;&gt; =&gt; <i>condition</i> := <i>C/C++ code</i></dd>
<dd>&lt;&gt; :=&gt; <i>condition</i></dd>
<dd>&lt;!<i>condition-list</i>&gt; { <i>C/C++ code</i> }</dd>
<dd>&lt;!<i>condition-list</i>&gt; := <i>C/C++ code</i></dd>
<dd>&lt;!*&gt; { <i>C/C++ code</i> }</dd>
<dd>&lt;!*&gt; := <i>C/C++ code</i></dd>
</dl>
<p>Named definitions are of the form:</p>
<dl compact="compact">
<dd><i>name</i> = <i>regular expression</i>;</dd>
</dl>
<p>When <b>-F</b> is active, then named definitions are also of the form:</p>
<dl compact="compact">
<dd><i>name</i> <i>regular expression</i></dd>
</dl>
<p>Configurations look like named definitions whose names start with
"<b>re2c:</b>":</p>
<dl compact="compact">
<dd>re2c:<i>name</i> = <i>value</i>;</dd>
<dd>re2c:<i>name</i> = <b>"</b><i>value</i><b>"</b>;</dd>
</dl>
<a name="lbAJ" id="lbAJ">&nbsp;</a>
<h2>SUMMARY OF RE2C REGULAR EXPRESSIONS</h2>
<dl compact="compact">
<dt>"foo"</dt>
<dd>the literal string foo. ANSI-C escape sequences can be used.</dd>
<dt>'foo'</dt>
<dd>the literal string foo (characters [a-zA-Z] treated case-insensitive).
ANSI-C escape sequences can be used.</dd>
<dt>[xyz]</dt>
<dd>a "character class"; in this case, the regular expression matches either an
'x', a 'y', or a 'z'.</dd>
<dt>[abj-oZ]</dt>
<dd>a "character class" with a range in it; matches an 'a', a 'b', any letter
from 'j' through 'o', or a 'Z'.</dd>
<dt>[^<i>class</i>]</dt>
<dd>an inverted "character class".</dd>
<dt><i>r</i>\<i>s</i></dt>
<dd>match any <i>r</i> which isn't an <i>s</i>. <i>r</i> and <i>s</i> must be
regular expressions which can be expressed as character classes.</dd>
<dt><i>r</i>*</dt>
<dd>zero or more <i>r</i>'s, where <i>r</i> is any regular expression</dd>
<dt><i>r</i>+</dt>
<dd>one or more <i>r</i>'s</dd>
<dt><i>r</i>?</dt>
<dd>zero or one <i>r</i>'s (that is, "an optional <i>r</i>")</dd>
<dt>name</dt>
<dd>the expansion of the "named definition" (see above)</dd>
<dt>(<i>r</i>)</dt>
<dd>an <i>r</i>; parentheses are used to override precedence (see below)</dd>
<dt><i>rs</i></dt>
<dd>an <i>r</i> followed by an <i>s</i> ("concatenation")</dd>
<dt><i>r</i>|<i>s</i></dt>
<dd>either an <i>r</i> or an <i>s</i></dd>
<dt><i>r</i>/<i>s</i></dt>
<dd>an <i>r</i> but only if it is followed by an <i>s</i>. The <i>s</i> is not part of
the matched text. This type of regular expression is called "trailing context". A trailing
context can only be the end of a rule and not part of a named definition.</dd>
<dt><i>r</i>{<i>n</i>}</dt>
<dd>matches <i>r</i> exactly <i>n</i> times.</dd>
<dt><i>r</i>{<i>n</i>,}</dt>
<dd>matches <i>r</i> at least <i>n</i> times.</dd>
<dt><i>r</i>{<i>n</i>,<i>m</i>}</dt>
<dd>matches <i>r</i> at least <i>n</i> but not more than <i>m</i> times.</dd>
<dt>.</dt>
<dd>match any character except newline (\n).</dd>
<dt><i>def</i></dt>
<dd>matches named definition as specified by <i>def</i> only if <b>-F</b> is
off. If the switch <b>-F</b> is active then this behaves like it was enclosed
in double quotes and matches the string <i>def</i>.</dd>
</dl>
<br />
<br />
<p>Character classes and string literals may contain octal or hexadecimal
character definitions and the following set of escape sequences
(<b>\n</b>,<br />
<b>\t</b>, <b>\v</b>, <b>\b</b>, <b>\r</b>, <b>\f</b>, <b>\a</b>, <b>\\</b>).
An octal character is defined by a backslash followed by its three octal digits
and a hexadecimal character is defined by backslash, a lower cased '<b>x</b>'
and its two hexadecimal digits or a backslash, an upper cased <b>X</b> and its
four hexadecimal digits.</p>
<p>re2c further more supports the c/c++ unicode notation. That is a backslash
followed by either a lowercased <b>u</b> and its four hexadecimal digits or an
uppercased <b>U</b> and its eight hexadecimal digits. However only in \fB-u\fP
mode the generated code can deal with any valid Unicode character up to
0x10FFFF.</p>
<p>Since characters greater <b>\X00FF</b> are not allowed in non unicode mode,
the only portable "<b>any</b>" rules are <b>(.|"\n")</b> and <b>[^]</b>.</p>
<p>The regular expressions listed above are grouped according to precedence,
from highest precedence at the top to lowest at the bottom. Those grouped
together have equal precedence.</p>
<a name="lbAK" id="lbAK">&nbsp;</a>
<h2>INPLACE CONFIGURATION</h2>
<p>It is possible to configure code generation inside re2c blocks. The
following lists the available configurations:</p>
<dl compact="compact">
<dt><i>re2c:cond:divider</i> <b>=</b> "/* *********************************** */" <b>;</b></dt>
<dd>Allows customizing of the divider for condition blocks. You can use '@@' to
put the name of the condition or customize the placeholder
using <i>re2c:cond:divider@cond</i>.</dd>
<dt><i>re2c:cond:divider@cond</i> <b>=</b> @@ <b>;</b></dt>
<dd>Specify the placeholder that will be replaced with the condition name
in <i>re2c:cond:divider\fP</i>.</dd>
<dt><i>re2c:cond:goto</i> <b>=</b> "goto @@;" <b>;</b></dt>
<dd>Allows customizing of the conditional goto statements used with ':=>' style rules.
You can use '@@' to put the name of the condition or customize the placeholder
using <i>re2c:cond:goto@cond</i>. You can also change this to 'continue;',
which would allow you to continue with the next loop cycle including any code
between loop start and re2c block.</dd>
<dt><i>re2c:cond:goto@cond</i> <b>=</b> @@ <b>;</b></dt>
<dd>Specifies the placeholder that will be replaced with the condition label
in <i>re2c:cond:goto</i>.</dd>
<dt><i>re2c:indent:top</i> <b>=</b> 0 <b>;</b></dt>
<dd>Specifies the minimum number of indentation to use. Requires a numeric
value greater than or equal zero.</dd>
<dt><i>re2c:condprefix</i> <b>=</b> yyc_ <b>;</b></dt>
<dd>Allows to specify the prefix used for condition labels. That is this text is
prepended to any condition label in the generated output file.</dd>
<dt><i>re2c:condenumprefix</i> <b>=</b> yyc <b>;</b></dt>
<dd>Allows to specify the prefix used for condition values. That is this text is
prepended to any condition enum value in the generated output file.</dd>
<dt><i>re2c:indent:string</i> <b>=</b> "\t" <b>;</b></dt>
<dd>Specifies the string to use for indentation. Requires a string that should
contain only whitespace unless you need this for external tools. The easiest
way to specify spaces is to include them in single or double quotes. If you do
not want any indentation at all you can simply set this to <b>""</b>.</dd>
<dt><i>re2c:yych:conversion</i> <b>=</b> 0 <b>;</b></dt>
<dd>When this setting is non zero, then \*(re automatically generates conversion
code whenever yych gets read. In this case the type must be defined using
<b>re2c:define:YYCTYPE</b>.</dd>
<dt><i>re2c:yych:emit</i> <b>=</b> 1 <b>;</b></dt>
<dd>Generation of \fByych\fP can be suppressed by setting this to 0.</dd>
<dt><i>re2c:yybm:hex</i> <b>=</b> 0 <b>;</b></dt>
<dd>If set to zero then a decimal table is being used else a hexadecimal table
will be generated.</dd>
<dt><i>re2c:yyfill:enable</i> <b>=</b> 1 <b>;</b></dt>
<dd>Set this to zero to suppress generation of YYFILL(n). When using this be sure
to verify that the generated scanner does not read behind input. Allowing
this behavior might introduce sever security issues to you programs.</dd>
<dt><i>re2c:yyfill:check</i> <b>=</b> 1 </b>;</b></dt>
<dd>This can be set 0 to suppress output of the pre condition using YYCURSOR and
YYLIMIT which becomes useful when YYLIMIT + max(YYFILL) is always accessible.</dd>
<dt><i>re2c:yyfill:parameter</i> <b>=</b> 1 <b>;</b></dt>
<dd>Allows to suppress parameter passing to <b>YYFILL</b> calls. If set to zero
then no parameter is passed to <b>YYFILL</b>. However <b>define:YYFILL@LEN</b>
allows to specify a replacement string for the actual length value. If set to
a non zero value then <b>YYFILL</b> usage will be followed by the number of
requested characters in braces unless <b>re2c:define:YYFILL:naked</b> is set.
Also look at <b>re2c:define:YYFILL:naked</b> and <b>re2c:define:YYFILL@LEN</b>.</dd>
<dt><i>re2c:startlabel</i> <b>=</b> 0 <b>;</b></dt>
<dd>If set to a non zero integer then the start label of the next scanner
blocks will be generated even if not used by the scanner itself. Otherwise the
normal <b>yy0</b> like start label is only being generated if needed. If set to
a text value then a label with that text will be generated regardless of
whether the normal start label is being used or not. This setting is being
reset to <b>0</b> after a start label has been generated.</dd>
<dt><i>re2c:labelprefix</i> <b>=</b> yy <b>;</b></dt>
<dd>Allows to change the prefix of numbered labels. The default is \fByy\fP and
can be set any string that is a valid label.</dd>
<dt><i>re2c:state:abort</i> <b>=</b> 0 <b>;</b></dt>
<dd>When not zero and switch -f is active then the YYGETSTATE block will
contain a default case that aborts and a -1 case is used for initialization.</dd>
<dt><i>re2c:state:nextlabel</i> <b>=</b> 0 <b>;</b></dt>
<dd>Used when -f is active to control whether the YYGETSTATE block is
followed by a yyNext: label line. Instead of using yyNext you can
usually also use configuration <i>startlabel</i> to force a specific start label
or default to yy0 as start label. Instead of using a dedicated label it
is often better to separate the YYGETSTATE code from the actual scanner code by
placing a "/*!getstate:re2c */" comment.</dd>
<dt><i>re2c:cgoto:threshold</i> <b>=</b> 9 <b>;</b></dt>
<dd>When -g is active this value specifies the complexity threshold that triggers
generation of jump tables rather than using nested if's and decision bitfields.
The threshold is compared against a calculated estimation of if-s needed where
every used bitmap divides the threshold by 2.</dd>
<dt><i>re2c:yych:conversion</i> <b>=</b> 0 <b>;</b></dt>
<dd>When the input uses signed characters and <b>-s</b> or <b>-b</b> switches are
in effect re2c allows to automatically convert to the unsigned character type
that is then necessary for its internal single character. When this setting
is zero or an empty string the conversion is disabled. Using a non zero number
the conversion is taken from <b>YYCTYPE</b>. If that is given by an inplace
configuration that value is being used. Otherwise it will be <b>(YYCTYPE)</b>
and changes to that configuration are no longer possible. When this setting is
a string the braces must be specified. Now assuming your input is a <b>char*</b>
buffer and you are using above mentioned switches you can set <b>YYCTYPE</b> to
<b>unsigned char</b> and this setting to either <b>1</b> or <b>"(unsigned char)"</b>.</dd>
<dt><i>re2c:define:define:YYCONDTYPE</i> <b>=</b> YYCONDTYPE <b>;</b></dt>
<dd>Enumeration used for condition support with <b>-c</b> mode.</dd>
<dt><i>re2c:define:YYCTXMARKER</i> <b>=</b> YYCTXMARKER <b>;</b></dt>
<dd>Allows to overwrite the define YYCTXMARKER and thus avoiding it by setting the
value to the actual code needed.</dd>
<dt><i>re2c:define:YYCTYPE</i> <b>=</b> YYCTYPE <b>;</b></dt>
<dd>Allows to overwrite the define YYCTYPE and thus avoiding it by setting the
value to the actual code needed.</dd>
<dt><i>re2c:define:YYCURSOR</i> <b>=</b> YYCURSOR <b>;</b></dt>
<dd>Allows to overwrite the define YYCURSOR and thus avoiding it by setting the
value to the actual code needed.</dd>
<dt><i>re2c:define:YYDEBUG</i> <b>=</b> YYDEBUG <b>;</b></dt>
<dd>Allows to overwrite the define \fBYYDEBUG\fP and thus avoiding it by setting the
value to the actual code needed.</dd>
<dt><i>re2c:define:YYFILL</i> <b>=</b> YYFILL <b>;</b></dt>
<dd>Allows to overwrite the define \fBYYFILL\fP and thus avoiding it by setting the
value to the actual code needed.</dd>
<dt><i>re2c:define:YYFILL:naked</i> <b>=</b> 0 <b>;</b></dt>
<dd>When set to 1 neither braces, parameter nor semicolon gets emitted.</dd>
<dt><i>re2c:define:YYFILL@LEN</i> <b>=</b> @@ <b>;</b></dt>
<dd>When using <b>re2c:define:YYFILL</b> and <b>re2c:yyfill:parameter</b> is 0 then
any occurrence of this text inside <b>YYFILL</b> will be replaced with the actual
length value.</dd>
<dt><i>re2c:define:YYGETCONDITION</i> <b>=</b> YYGETCONDITION <b>;</b></dt>
<dd>Allows to overwrite the define <b>YYGETCONDITION</b>.</dd>
<dt><i>re2c:define:YYGETCONDITION:naked</i> <b>=</b> 0 <b>;</b></dt>
<dd>When set to 1 neither braces, parameter nor semicolon gets emitted.</dd>
<dt><i>re2c:define:YYGETSTATE</i> <b>=</b> YYGETSTATE <b>;</b></dt>
<dd>Allows to overwrite the define <b>YYGETSTATE</b> and thus avoiding it by setting the
value to the actual code needed.</dd>
<dt><i>re2c:define:YYGETSTATE:naked</i> <b>=</b> 0 <b>;</b></dt>
<dt>When set to 1 neither braces, parameter nor semicolon gets emitted.</dt>
<dt><i>re2c:define:YYLIMIT</i> <b>=</b> YYLIMIT <b>;</b></dt>
<dd>Allows to overwrite the define <b>YYLIMIT</b> and thus avoiding it by setting the
value to the actual code needed.</dd>
<dt><i>re2c:define:YYMARKER</i> <b>=</b> YYMARKER <b>;</b></dt>
<dd>Allows to overwrite the define <b>YYMARKER</b> and thus avoiding it by setting the
value to the actual code needed.</dd>
<dt><i>re2c:define:YYSETCONDITION</i> <b>=</b> YYSETCONDITION <b>;</b></dt>
<dd>Allows to overwrite the define <b>YYSETCONDITION</b>.</dd>
<dt><i>re2c:define:YYSETCONDITION@cond</i> <b>=</b> @@ <b>;</b></dt>
<dd>When using <b>re2c:define:YYSETCONDITION</b> then any occurrence of this text
inside <b>YYSETCONDITION</b> will be replaced with the actual new condition value.</dd>
<dt><i>re2c:define:YYSETSTATE</i> <b>=</b> YYSETSTATE <b>;</b></dt>
<dd>Allows to overwrite the define <b>YYSETSTATE</b> and thus avoiding it by setting the
value to the actual code needed.</dd>
<dt><i>re2c:define:YYSETSTATE:naked</i> <b>=</b> 0 <b>;</b></dt>
<dt>When set to 1 neither braces, parameter nor semicolon gets emitted.</dt>
<dt><i>re2c:define:YYSETSTATE@state</i> <b>=</b> @@ <b>;</b></dt>
<dd>When using <b>re2c:define:YYSETSTATE</b> then any occurrence of this text
inside <b>YYSETSTATE</b> will be replaced with the actual new state value.</dd>
<dt><i>re2c:label:yyFillLabel</i> <b>=</b> yyFillLabel <b>;</b></dt>
<dd>Allows to overwrite the name of the label yyFillLabel.</dd>
<dt><i>re2c:label:yyNext</i> <b>=</b> yyNext <b>;</b></dt>
<dd>Allows to overwrite the name of the label yyNext.</dd>
<dt><i>re2c:variable:yyaccept</i> <b>=</b> yyaccept <b>;</b></dt>
<dd>Allows to overwrite the name of the variable yyaccept.</dd>
<dt><i>re2c:variable:yybm</i> <b>=</b> yybm <b>;</b></dt>
<dd>Allows to overwrite the name of the variable yybm.</dd>
<dt><i>re2c:variable:yych</i> <b>=</b> yych <b>;</b></dt>
<dd>Allows to overwrite the name of the variable yych.</dd>
<dt><i>re2c:variable:yyctable</i> <b>=</b> yyctable <b>;</b></dt>
<dd>When both <b>-c</b> and <b>-g</b> are active then <b>re2c</b> uses this variable to
generate a static jump table for YYGETCONDITION.</dd>
<dt><i>re2c:variable:yystable</i> <b>=</b> yystable <b>;</b></dt>
<dd>When both <b>-f</b> and <b>-g</b> are active then <b>re2c</b> uses this variable to
generate a static jump table for YYGETSTATE.</dd>
<dt><i>re2c:variable:yytarget</i> <b>=</b> yytarget <b>;</b></dt>
<dd>Allows to overwrite the name of the variable yytarget.</dd>
</dl>
<a name="lbAL" id="lbAL">&nbsp;</a>
<h2>UNDERSTANDING RE2C</h2>
<p>The subdirectory lessons of the re2c distribution contains a few step by step
lessons to get you started with re2c. All examples in the lessons subdirectory
can be compiled and actually work.</p>
<a name="lbAM" id="lbAM">&nbsp;</a>
<h2>FEATURES</h2>
<p><b>re2c</b> does not provide a default action: the generated code assumes
that the input will consist of a sequence of tokens. Typically this can be
dealt with by adding a rule such as the one for unexpected characters in the
example above.</p>
<p>The user must arrange for a sentinel token to appear at the end of input
(and provide a rule for matching it): <b>re2c</b> does not provide an
&lt;&lt;EOF&gt;&gt; expression. If the source is from a null-byte terminated
string, a rule matching a null character will suffice. If the source is from a
file then you could pad the input with a newline (or some other character that
cannot appear within another token); upon recognizing such a character check
to see if it is the sentinel and act accordingly. And you can also use YYFILL(n)
to end the scanner in case not enough characters are available which is nothing
else then e detection of end of data/file.</p>
<a name="lbAN" id="lbAN">&nbsp;</a>
<h2>BUGS</h2>
<p>Difference only works for character sets.</p>
<p>The <b>re2c</b> internal algorithms need documentation.</p>
<a name="lbAO" id="lbAO">&nbsp;</a>
<h2>SEE ALSO</h2>
<p>flex(1), lex(1). More information on <b>re2c</b> can be found here:
<b><a href=
"http://re2c.org/">http://re2c.org/</a></b></p>
<a name="lbAP" id="lbAP">&nbsp;</a>
<h2>AUTHORS</h2>
<ul>
<li>Peter Bumbulis &lt;<a href=
"mailto:peter@csg.uwaterloo.ca">peter@csg.uwaterloo.ca</a>&gt;</li>
<li>Brian Young &lt;<a href=
"mailto:bayoung@acm.org">bayoung@acm.org</a>&gt;</li>
<li>Dan Nuffer &lt;<a href=
"mailto:nuffer@users.sourceforge.net">nuffer@users.sourceforge.net</a>&gt;</li>
<li>Marcus Boerger &lt;<a href=
"mailto:helly@users.sourceforge.net">helly@users.sourceforge.net</a>&gt;</li>
<li>Hartmut Kaiser &lt;<a href=
"mailto:hkaiser@users.sourceforge.net">hkaiser@users.sourceforge.net</a>&gt;</li>
<li>Emmanuel Mogenet &lt;<a href="mailto:mgix@mgix.com">mgix@mgix.com</a>&gt;
(added storable state)</li>
</ul>
<br />
<br />
<a name="lbAQ" id="lbAQ">&nbsp;</a>
<h2>VERSION INFORMATION</h2>
<p>This manpage describes <b>re2c</b>, version @PACKAGE_VERSION@.</p>
<hr />
<a name="index" id="index">&nbsp;</a>
<h2>Index</h2>
<dl>
<dt><a href="#lbAB">NAME</a><br /></dt>
<dt><a href="#lbAC">SYNOPSIS</a><br /></dt>
<dt><a href="#lbAD">DESCRIPTION</a><br /></dt>
<dt><a href="#lbAE">OPTIONS</a><br /></dt>
<dt><a href="#lbAF">INTERFACE CODE</a><br /></dt>
<dt><a href="#lbAG">SCANNER WITH STORABLE STATES</a><br /></dt>
<dt><a href="#lbAH">SCANNER WITH CONDITION SUPPORT</a><br /></dt>
<dt><a href="#lbAI">SCANNER SPECIFICATIONS</a><br /></dt>
<dt><a href="#lbAJ">SUMMARY OF RE2C REGULAR EXPRESSIONS</a><br /></dt>
<dt><a href="#lbAK">INPLACE CONFIGURATION</a><br /></dt>
<dt><a href="#lbAL">UNDERSTANDING RE2C</a><br /></dt>
<dt><a href="#lbAM">FEATURES</a><br /></dt>
<dt><a href="#lbAN">BUGS</a><br /></dt>
<dt><a href="#lbAO">SEE ALSO</a><br /></dt>
<dt><a href="#lbAP">AUTHORS</a><br /></dt>
<dt><a href="#lbAQ">VERSION INFORMATION</a><br /></dt>
</dl>
<br />
<br />
<hr />
<p>This document was created by man2html, using the manual pages.<br />
Date: @PACKAGE_DATE@</p>
</body>
</html>
@@ -1,148 +0,0 @@
/* Generated by re2c */
#line 1 "calc_001.re"
/* re2c lesson 001_upn_calculator, calc_001, (c) M. Boerger 2006 - 2007 */
#line 43 "calc_001.re"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int scan(char *s, int l)
{
char *p = s;
char *q = 0;
#define YYCTYPE char
#define YYCURSOR p
#define YYLIMIT (s+l)
#define YYMARKER q
#define YYFILL(n)
for(;;)
{
#line 24 "<stdout>"
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
switch (yych) {
case 0x00: goto yy10;
case '+': goto yy6;
case '-': goto yy8;
case '0': goto yy2;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy4;
default: goto yy12;
}
yy2:
++YYCURSOR;
switch ((yych = *YYCURSOR)) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy16;
default: goto yy3;
}
yy3:
#line 64 "calc_001.re"
{ printf("Num\n"); continue; }
#line 64 "<stdout>"
yy4:
++YYCURSOR;
yych = *YYCURSOR;
goto yy15;
yy5:
#line 63 "calc_001.re"
{ printf("Num\n"); continue; }
#line 72 "<stdout>"
yy6:
++YYCURSOR;
#line 65 "calc_001.re"
{ printf("+\n"); continue; }
#line 77 "<stdout>"
yy8:
++YYCURSOR;
#line 66 "calc_001.re"
{ printf("-\n"); continue; }
#line 82 "<stdout>"
yy10:
++YYCURSOR;
#line 67 "calc_001.re"
{ printf("EOF\n"); return 0; }
#line 87 "<stdout>"
yy12:
++YYCURSOR;
#line 68 "calc_001.re"
{ printf("ERR\n"); return 1; }
#line 92 "<stdout>"
yy14:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
yy15:
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy14;
default: goto yy5;
}
yy16:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy16;
default: goto yy18;
}
yy18:
#line 62 "calc_001.re"
{ printf("Oct\n"); continue; }
#line 131 "<stdout>"
}
#line 69 "calc_001.re"
}
}
int main(int argc, char **argv)
{
if (argc > 1)
{
return scan(argv[1], strlen(argv[1]));
}
else
{
fprintf(stderr, "%s <expr>\n", argv[0]);
return 1;
}
}
@@ -1,84 +0,0 @@
/* re2c lesson 001_upn_calculator, calc_001, (c) M. Boerger 2006 - 2007 */
/*!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. 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
'while(1)'-loop instead but some compilers generate a warning for it.
. To make the output more readable we use 're2c:indent:top' scanner
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
our 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.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int scan(char *s, int l)
{
char *p = s;
char *q = 0;
#define YYCTYPE char
#define YYCURSOR p
#define YYLIMIT (s+l)
#define YYMARKER q
#define YYFILL(n)
for(;;)
{
/*!re2c
re2c:indent:top = 2;
"0"[0-9]+ { printf("Oct\n"); continue; }
[1-9][0-9]* { printf("Num\n"); continue; }
"0" { printf("Num\n"); continue; }
"+" { printf("+\n"); continue; }
"-" { printf("-\n"); continue; }
"\000" { printf("EOF\n"); return 0; }
[^] { printf("ERR\n"); return 1; }
*/
}
}
int main(int argc, char **argv)
{
if (argc > 1)
{
return scan(argv[1], strlen(argv[1]));
}
else
{
fprintf(stderr, "%s <expr>\n", argv[0]);
return 1;
}
}
@@ -1,157 +0,0 @@
/* Generated by re2c */
#line 1 "calc_002.re"
/* re2c lesson 001_upn_calculator, calc_002, (c) M. Boerger 2006 - 2007 */
#line 19 "calc_002.re"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int fill(char *p, int n, char **l)
{
while (*++p && n--) ;
* l = p;
return n <= 0;
}
int scan(char *s)
{
char *p = s;
char *l = s;
char *q = 0;
#define YYCTYPE char
#define YYCURSOR p
#define YYLIMIT l
#define YYMARKER q
#define YYFILL(n) { if (!fill(p, n, &l)) break; }
for(;;)
{
#line 32 "<stdout>"
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
switch (yych) {
case 0x00: goto yy10;
case '+': goto yy6;
case '-': goto yy8;
case '0': goto yy2;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy4;
default: goto yy12;
}
yy2:
++YYCURSOR;
switch ((yych = *YYCURSOR)) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy16;
default: goto yy3;
}
yy3:
#line 48 "calc_002.re"
{ printf("Num\n"); continue; }
#line 72 "<stdout>"
yy4:
++YYCURSOR;
yych = *YYCURSOR;
goto yy15;
yy5:
#line 47 "calc_002.re"
{ printf("Num\n"); continue; }
#line 80 "<stdout>"
yy6:
++YYCURSOR;
#line 49 "calc_002.re"
{ printf("+\n"); continue; }
#line 85 "<stdout>"
yy8:
++YYCURSOR;
#line 50 "calc_002.re"
{ printf("+\n"); continue; }
#line 90 "<stdout>"
yy10:
++YYCURSOR;
#line 51 "calc_002.re"
{ printf("EOF\n"); return 0; }
#line 95 "<stdout>"
yy12:
++YYCURSOR;
#line 52 "calc_002.re"
{ printf("ERR\n"); return 1; }
#line 100 "<stdout>"
yy14:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
yy15:
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy14;
default: goto yy5;
}
yy16:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy16;
default: goto yy18;
}
yy18:
#line 46 "calc_002.re"
{ printf("Oct\n"); continue; }
#line 139 "<stdout>"
}
#line 53 "calc_002.re"
}
printf("OOD\n"); return 2;
}
int main(int argc, char **argv)
{
if (argc > 1)
{
return scan(argv[1]);
}
else
{
fprintf(stderr, "%s <expr>\n", argv[0]);
return 0;
}
}
@@ -1,69 +0,0 @@
/* re2c lesson 001_upn_calculator, calc_002, (c) M. Boerger 2006 - 2007 */
/*!ignore:re2c
- making use of YYFILL
. Here we modified the scanner to not require strlen() on the call. Instead
we compute limit on the fly. That is whenever more input is needed we
search for the terminating \0 in the next n chars the scanner needs.
. If there is not enough input we quit the scanner.
. Note that in lesson_001 YYLIMIT was a character pointer computed only once.
Here is of course also of type YYCTYPE but a variable that gets reevaluated
by YYFILL().
. To make the code smaller we take advantage of the fact that our loop has no
break so far. This allows us to use break here and have the code that is
used for YYFILL() not contain the printf in every occurrence. That way the
generated code gets smaller.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int fill(char *p, int n, char **l)
{
while (*++p && n--) ;
* l = p;
return n <= 0;
}
int scan(char *s)
{
char *p = s;
char *l = s;
char *q = 0;
#define YYCTYPE char
#define YYCURSOR p
#define YYLIMIT l
#define YYMARKER q
#define YYFILL(n) { if (!fill(p, n, &l)) break; }
for(;;)
{
/*!re2c
re2c:indent:top = 2;
"0"[0-9]+ { printf("Oct\n"); continue; }
[1-9][0-9]* { printf("Num\n"); continue; }
"0" { printf("Num\n"); continue; }
"+" { printf("+\n"); continue; }
"-" { printf("+\n"); continue; }
"\000" { printf("EOF\n"); return 0; }
[^] { printf("ERR\n"); return 1; }
*/
}
printf("OOD\n"); return 2;
}
int main(int argc, char **argv)
{
if (argc > 1)
{
return scan(argv[1]);
}
else
{
fprintf(stderr, "%s <expr>\n", argv[0]);
return 0;
}
}
@@ -1,149 +0,0 @@
/* Generated by re2c */
#line 1 "calc_003.re"
/* re2c lesson 001_upn_calculator, calc_003, (c) M. Boerger 2006 - 2007 */
#line 19 "calc_003.re"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int scan(char *s, int l)
{
char *p = s;
char *q = 0;
#define YYCTYPE char
#define YYCURSOR p
#define YYLIMIT (s+l+2)
#define YYMARKER q
#define YYFILL(n) { printf("OOD\n"); return 2; }
for(;;)
{
#line 24 "<stdout>"
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
switch (yych) {
case 0x00: goto yy10;
case '+': goto yy6;
case '-': goto yy8;
case '0': goto yy2;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy4;
default: goto yy12;
}
yy2:
++YYCURSOR;
switch ((yych = *YYCURSOR)) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy16;
default: goto yy3;
}
yy3:
#line 40 "calc_003.re"
{ printf("Num\n"); continue; }
#line 64 "<stdout>"
yy4:
++YYCURSOR;
yych = *YYCURSOR;
goto yy15;
yy5:
#line 39 "calc_003.re"
{ printf("Num\n"); continue; }
#line 72 "<stdout>"
yy6:
++YYCURSOR;
#line 41 "calc_003.re"
{ printf("+\n"); continue; }
#line 77 "<stdout>"
yy8:
++YYCURSOR;
#line 42 "calc_003.re"
{ printf("+\n"); continue; }
#line 82 "<stdout>"
yy10:
++YYCURSOR;
#line 43 "calc_003.re"
{ printf("EOF\n"); return 0; }
#line 87 "<stdout>"
yy12:
++YYCURSOR;
#line 44 "calc_003.re"
{ printf("ERR\n"); return 1; }
#line 92 "<stdout>"
yy14:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
yy15:
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy14;
default: goto yy5;
}
yy16:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy16;
default: goto yy18;
}
yy18:
#line 38 "calc_003.re"
{ printf("Oct\n"); continue; }
#line 131 "<stdout>"
}
#line 45 "calc_003.re"
}
return 0;
}
int main(int argc, char **argv)
{
if (argc > 1)
{
return scan(argv[1], strlen(argv[1]));
}
else
{
fprintf(stderr, "%s <expr>\n", argv[0]);
return 0;
}
}
@@ -1,61 +0,0 @@
/* re2c lesson 001_upn_calculator, calc_003, (c) M. Boerger 2006 - 2007 */
/*!ignore:re2c
- making use of YYFILL
. Again provide the length of the input to generate the limit only once. Now
we can use YYFILL() to detect the end and simply return since YYFILL() is
only being used if the next scanner run might use more chars then YYLIMIT
allows.
. Note that we now use (s+l+2) instead of (s+l) as we did in lesson_001. In
the first lesson we did not quit from YYFILL() and used a special rule to
detect the end of input. Here we use the fact that we know the exact end
of input and that this length does not include the terminating zero. Since
YYLIMIT points to the first character behind the used buffer we use "+ 2".
If we would use "+1" we could drop the "\000" rule but could no longer
distinguish between end of input and out of data.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int scan(char *s, int l)
{
char *p = s;
char *q = 0;
#define YYCTYPE char
#define YYCURSOR p
#define YYLIMIT (s+l+2)
#define YYMARKER q
#define YYFILL(n) { printf("OOD\n"); return 2; }
for(;;)
{
/*!re2c
re2c:indent:top = 2;
"0"[0-9]+ { printf("Oct\n"); continue; }
[1-9][0-9]* { printf("Num\n"); continue; }
"0" { printf("Num\n"); continue; }
"+" { printf("+\n"); continue; }
"-" { printf("+\n"); continue; }
"\000" { printf("EOF\n"); return 0; }
[^] { printf("ERR\n"); return 1; }
*/
}
return 0;
}
int main(int argc, char **argv)
{
if (argc > 1)
{
return scan(argv[1], strlen(argv[1]));
}
else
{
fprintf(stderr, "%s <expr>\n", argv[0]);
return 0;
}
}
@@ -1,156 +0,0 @@
/* Generated by re2c */
#line 1 "calc_004.re"
/* re2c lesson 001_upn_calculator, calc_004, (c) M. Boerger 2006 - 2007 */
#line 20 "calc_004.re"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char * tokendup(const char *t, const char *l)
{
size_t n = l -t + 1;
char *r = (char*)malloc(n);
memmove(r, t, n-1);
r[n] = '\0';
return r;
}
int scan(char *s, int l)
{
char *p = s;
char *q = 0;
char *t;
#define YYCTYPE char
#define YYCURSOR p
#define YYLIMIT (s+l+2)
#define YYMARKER q
#define YYFILL(n) { printf("OOD\n"); return 2; }
for(;;)
{
t = p;
#line 36 "<stdout>"
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
switch (yych) {
case 0x00: goto yy9;
case '+': goto yy5;
case '-': goto yy7;
case '0': goto yy2;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy4;
default: goto yy11;
}
yy2:
++YYCURSOR;
switch ((yych = *YYCURSOR)) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy15;
default: goto yy3;
}
yy3:
#line 57 "calc_004.re"
{ t = tokendup(t, p); printf("Num: %s\n", t); free(t); continue; }
#line 76 "<stdout>"
yy4:
yych = *++YYCURSOR;
goto yy14;
yy5:
++YYCURSOR;
#line 58 "calc_004.re"
{ printf("+\n"); continue; }
#line 84 "<stdout>"
yy7:
++YYCURSOR;
#line 59 "calc_004.re"
{ printf("+\n"); continue; }
#line 89 "<stdout>"
yy9:
++YYCURSOR;
#line 60 "calc_004.re"
{ printf("EOF\n"); return 0; }
#line 94 "<stdout>"
yy11:
++YYCURSOR;
#line 61 "calc_004.re"
{ printf("ERR\n"); return 1; }
#line 99 "<stdout>"
yy13:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
yy14:
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy13;
default: goto yy3;
}
yy15:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy15;
default: goto yy17;
}
yy17:
#line 56 "calc_004.re"
{ t = tokendup(t, p); printf("Oct: %s\n", t); free(t); continue; }
#line 138 "<stdout>"
}
#line 62 "calc_004.re"
}
return 0;
}
int main(int argc, char **argv)
{
if (argc > 1)
{
return scan(argv[1], strlen(argv[1]));
}
else
{
fprintf(stderr, "%s <expr>\n", argv[0]);
return 0;
}
}
@@ -1,78 +0,0 @@
/* re2c lesson 001_upn_calculator, calc_004, (c) M. Boerger 2006 - 2007 */
/*!ignore:re2c
- making use of definitions
. We provide complex rules as definitions. We can even have definitions made
up from other definitions. And we could also use definitions as part of
rules and not only as full rules as shown in this lesson.
- showing the tokens
. re2c does not store the beginning of a token on its own but we can easily
do this by providing variable, in our case t, that is set to YYCURSOR on
every loop. If we were not using a loop here the token, we could have used
s instead of a new variable instead.
. As we use the token for an output function that requires a terminating zero
we copy the token. Alternatively we could store the end of the token, then
replace it with a zero character and replace it after the token has been
used. However that approach is not always acceptable.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char * tokendup(const char *t, const char *l)
{
size_t n = l -t + 1;
char *r = (char*)malloc(n);
memmove(r, t, n-1);
r[n] = '\0';
return r;
}
int scan(char *s, int l)
{
char *p = s;
char *q = 0;
char *t;
#define YYCTYPE char
#define YYCURSOR p
#define YYLIMIT (s+l+2)
#define YYMARKER q
#define YYFILL(n) { printf("OOD\n"); return 2; }
for(;;)
{
t = p;
/*!re2c
re2c:indent:top = 2;
DIGIT = [0-9] ;
OCT = "0" DIGIT+ ;
INT = "0" | ( [1-9] DIGIT* ) ;
OCT { t = tokendup(t, p); printf("Oct: %s\n", t); free(t); continue; }
INT { t = tokendup(t, p); printf("Num: %s\n", t); free(t); continue; }
"+" { printf("+\n"); continue; }
"-" { printf("+\n"); continue; }
"\000" { printf("EOF\n"); return 0; }
[^] { printf("ERR\n"); return 1; }
*/
}
return 0;
}
int main(int argc, char **argv)
{
if (argc > 1)
{
return scan(argv[1], strlen(argv[1]));
}
else
{
fprintf(stderr, "%s <expr>\n", argv[0]);
return 0;
}
}
@@ -1,236 +0,0 @@
/* Generated by re2c */
#line 1 "calc_005.re"
/* re2c lesson 001_upn_calculator, calc_005, (c) M. Boerger 2006 - 2007 */
#line 19 "calc_005.re"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define DEBUG(stmt) stmt
int stack[4];
int depth = 0;
int push_num(const char *t, const char *l, int radix)
{
int num = 0;
if (depth >= sizeof(stack))
{
return 3;
}
--t;
while(++t < l)
{
num = num * radix + (*t - '0');
}
DEBUG(printf("Num: %d\n", num));
stack[depth++] = num;
return 0;
}
int stack_add()
{
if (depth < 2) return 4;
--depth;
stack[depth-1] = stack[depth-1] + stack[depth];
return 0;
}
int stack_sub()
{
if (depth < 2) return 4;
--depth;
stack[depth-1] = stack[depth-1] - stack[depth];
return 0;
}
int scan(char *s, int l)
{
char *p = s;
char *q = 0;
char *t;
int res = 0;
#define YYCTYPE char
#define YYCURSOR p
#define YYLIMIT (s+l+1)
#define YYMARKER q
#define YYFILL(n) { return depth == 1 ? 0 : 2; }
while(!res)
{
t = p;
#line 71 "<stdout>"
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
switch (yych) {
case '\t':
case ' ': goto yy2;
case '+': goto yy7;
case '-': goto yy9;
case '0': goto yy4;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy6;
default: goto yy11;
}
yy2:
++YYCURSOR;
yych = *YYCURSOR;
goto yy19;
yy3:
#line 91 "calc_005.re"
{ continue; }
#line 101 "<stdout>"
yy4:
++YYCURSOR;
switch ((yych = *YYCURSOR)) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy15;
default: goto yy5;
}
yy5:
#line 93 "calc_005.re"
{ res = push_num(t, p, 10); continue; }
#line 120 "<stdout>"
yy6:
yych = *++YYCURSOR;
goto yy14;
yy7:
++YYCURSOR;
#line 94 "calc_005.re"
{ res = stack_add(); continue; }
#line 128 "<stdout>"
yy9:
++YYCURSOR;
#line 95 "calc_005.re"
{ res = stack_sub(); continue; }
#line 133 "<stdout>"
yy11:
++YYCURSOR;
#line 96 "calc_005.re"
{ res = 1; continue; }
#line 138 "<stdout>"
yy13:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
yy14:
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy13;
default: goto yy5;
}
yy15:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
switch (yych) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': goto yy15;
default: goto yy17;
}
yy17:
#line 92 "calc_005.re"
{ res = push_num(t, p, 8); continue; }
#line 177 "<stdout>"
yy18:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
yy19:
switch (yych) {
case '\t':
case ' ': goto yy18;
default: goto yy3;
}
}
#line 97 "calc_005.re"
}
return res;
}
int main(int argc, char **argv)
{
if (argc > 1)
{
char *inp;
int res = 0, argp = 0, len;
while(!res && ++argp < argc)
{
inp = argv[argp];
len = strlen(inp);
if (inp[0] == '\"' && inp[len-1] == '\"')
{
++inp;
len -=2;
}
res = scan(inp, len);
}
switch(res)
{
case 0:
printf("Result: %d\n", stack[0]);
return 0;
case 1:
fprintf(stderr, "Illegal character in input.\n");
return 1;
case 2:
fprintf(stderr, "Premature end of input.\n");
return 2;
case 3:
fprintf(stderr, "Stack overflow.\n");
return 3;
case 4:
fprintf(stderr, "Stack underflow.\n");
return 4;
}
}
else
{
fprintf(stderr, "%s <expr>\n", argv[0]);
return 0;
}
}
@@ -1,144 +0,0 @@
/* re2c lesson 001_upn_calculator, calc_005, (c) M. Boerger 2006 - 2007 */
/*!ignore:re2c
- turning this lesson into an easy calculator
. We are going to write an UPN calculator so we need an additional rule to
ignore white space.
. Then we need to store the scanned input somewhere and do our math on it.
. Also we need to scan all arguments since the main c code gets the input
split up into chunks.
. In contrast to what we did before we now add a variable res that holds the
scanner state. We initialize that variable to 0 and quit the loop when it
is non zero. This will also be our return value so that we can use it in
function main to generate error information.
. To support operating systems where ' and " get passed in program arguments
we check for them being first and last input character. If so we correct
input pointer and input length. Since now our scanner might not see a
terminating zero we change YYLIMIT again and drop the special zero rule.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define DEBUG(stmt) stmt
int stack[4];
int depth = 0;
int push_num(const char *t, const char *l, int radix)
{
int num = 0;
if (depth >= sizeof(stack))
{
return 3;
}
--t;
while(++t < l)
{
num = num * radix + (*t - '0');
}
DEBUG(printf("Num: %d\n", num));
stack[depth++] = num;
return 0;
}
int stack_add()
{
if (depth < 2) return 4;
--depth;
stack[depth-1] = stack[depth-1] + stack[depth];
return 0;
}
int stack_sub()
{
if (depth < 2) return 4;
--depth;
stack[depth-1] = stack[depth-1] - stack[depth];
return 0;
}
int scan(char *s, int l)
{
char *p = s;
char *q = 0;
char *t;
int res = 0;
#define YYCTYPE char
#define YYCURSOR p
#define YYLIMIT (s+l+1)
#define YYMARKER q
#define YYFILL(n) { return depth == 1 ? 0 : 2; }
while(!res)
{
t = p;
/*!re2c
re2c:indent:top = 2;
DIGIT = [0-9] ;
OCT = "0" DIGIT+ ;
INT = "0" | ( [1-9] DIGIT* ) ;
WS = [ \t]+ ;
WS { continue; }
OCT { res = push_num(t, p, 8); continue; }
INT { res = push_num(t, p, 10); continue; }
"+" { res = stack_add(); continue; }
"-" { res = stack_sub(); continue; }
[^] { res = 1; continue; }
*/
}
return res;
}
int main(int argc, char **argv)
{
if (argc > 1)
{
char *inp;
int res = 0, argp = 0, len;
while(!res && ++argp < argc)
{
inp = argv[argp];
len = strlen(inp);
if (inp[0] == '\"' && inp[len-1] == '\"')
{
++inp;
len -=2;
}
res = scan(inp, len);
}
switch(res)
{
case 0:
printf("Result: %d\n", stack[0]);
return 0;
case 1:
fprintf(stderr, "Illegal character in input.\n");
return 1;
case 2:
fprintf(stderr, "Premature end of input.\n");
return 2;
case 3:
fprintf(stderr, "Stack overflow.\n");
return 3;
case 4:
fprintf(stderr, "Stack underflow.\n");
return 4;
}
}
else
{
fprintf(stderr, "%s <expr>\n", argv[0]);
return 0;
}
}
@@ -1,203 +0,0 @@
/* Generated by re2c */
#line 1 "calc_006.s.re"
/* re2c lesson 001_upn_calculator, calc_006, (c) M. Boerger 2006 - 2007 */
#line 36 "calc_006.s.re"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define DEBUG(stmt) stmt
int stack[4];
int depth = 0;
int push_num(const unsigned char *t, const unsigned char *l, int radix)
{
int num = 0;
if (depth >= sizeof(stack))
{
return 3;
}
--t;
while(++t < l)
{
num = num * radix + (*t - (unsigned char)'0');
}
DEBUG(printf("Num: %d\n", num));
stack[depth++] = num;
return 0;
}
int stack_add()
{
if (depth < 2) return 4;
--depth;
stack[depth-1] = stack[depth-1] + stack[depth];
DEBUG(printf("+\n"));
return 0;
}
int stack_sub()
{
if (depth < 2) return 4;
--depth;
stack[depth-1] = stack[depth-1] - stack[depth];
DEBUG(printf("-\n"));
return 0;
}
int scan(char *s)
{
unsigned char *p = (unsigned char*)s;
unsigned char *t;
int res = 0;
#define YYCTYPE unsigned char
#define YYCURSOR p
while(!res)
{
t = p;
#line 69 "<stdout>"
{
YYCTYPE yych;
yych = *YYCURSOR;
if (yych <= '*') {
if (yych <= '\t') {
if (yych <= 0x00) goto yy11;
if (yych <= 0x08) goto yy13;
} else {
if (yych != ' ') goto yy13;
}
} else {
if (yych <= '-') {
if (yych <= '+') goto yy7;
if (yych <= ',') goto yy13;
goto yy9;
} else {
if (yych <= '/') goto yy13;
if (yych <= '0') goto yy4;
if (yych <= '9') goto yy6;
goto yy13;
}
}
++YYCURSOR;
yych = *YYCURSOR;
goto yy21;
yy3:
#line 107 "calc_006.s.re"
{ continue; }
#line 99 "<stdout>"
yy4:
++YYCURSOR;
if ((yych = *YYCURSOR) <= '/') goto yy5;
if (yych <= '9') goto yy17;
yy5:
#line 109 "calc_006.s.re"
{ res = push_num(t, p, 10); continue; }
#line 107 "<stdout>"
yy6:
yych = *++YYCURSOR;
goto yy16;
yy7:
++YYCURSOR;
#line 110 "calc_006.s.re"
{ res = stack_add(); continue; }
#line 115 "<stdout>"
yy9:
++YYCURSOR;
#line 111 "calc_006.s.re"
{ res = stack_sub(); continue; }
#line 120 "<stdout>"
yy11:
++YYCURSOR;
#line 112 "calc_006.s.re"
{ res = depth == 1 ? 0 : 2; break; }
#line 125 "<stdout>"
yy13:
++YYCURSOR;
#line 113 "calc_006.s.re"
{ res = 1; continue; }
#line 130 "<stdout>"
yy15:
++YYCURSOR;
yych = *YYCURSOR;
yy16:
if (yych <= '/') goto yy5;
if (yych <= '9') goto yy15;
goto yy5;
yy17:
++YYCURSOR;
yych = *YYCURSOR;
if (yych <= '/') goto yy19;
if (yych <= '9') goto yy17;
yy19:
#line 108 "calc_006.s.re"
{ res = push_num(t, p, 8); continue; }
#line 146 "<stdout>"
yy20:
++YYCURSOR;
yych = *YYCURSOR;
yy21:
if (yych == '\t') goto yy20;
if (yych == ' ') goto yy20;
goto yy3;
}
#line 114 "calc_006.s.re"
}
return res;
}
int main(int argc, char **argv)
{
if (argc > 1)
{
char *inp;
int res = 0, argp = 0, len;
while(!res && ++argp < argc)
{
inp = strdup(argv[argp]);
len = strlen(inp);
if (inp[0] == '\"' && inp[len-1] == '\"')
{
inp[len - 1] = '\0';
++inp;
}
res = scan(inp);
free(inp);
}
switch(res)
{
case 0:
printf("Result: %d\n", stack[0]);
return 0;
case 1:
fprintf(stderr, "Illegal character in input.\n");
return 1;
case 2:
fprintf(stderr, "Premature end of input.\n");
return 2;
case 3:
fprintf(stderr, "Stack overflow.\n");
return 3;
case 4:
fprintf(stderr, "Stack underflow.\n");
return 4;
}
}
else
{
fprintf(stderr, "%s <expr>\n", argv[0]);
return 0;
}
}
@@ -1,162 +0,0 @@
/* re2c lesson 001_upn_calculator, calc_006, (c) M. Boerger 2006 - 2007 */
/*!ignore:re2c
- avoiding YYFILL()
. We use the inplace configuration re2c:yyfill to suppress generation of
YYFILL() blocks. This of course means we no longer have to provide the
macro.
. We also drop the YYMARKER stuff since we know that re2c does not generate
it for this example.
. Since re2c does no longer check for out of data situations we must do this.
For that reason we first reintroduce our zero rule and second we need to
ensure that the scanner does not take more than one bytes in one go.
In the example suppose "0" is passed. The scanner reads the first "0" and
then is in an undecided state. The scanner can earliest decide on the next
char what the token is. In case of a zero the input ends and it was a
number, 0 to be precise. In case of a digit it is an octal number and the
next character needs to be read. In case of any other character the scanner
will detect an error with the any rule [^].
Now the above shows that the scanner may read two characters directly. But
only if the first is a "0". So we could easily check that if the first char
is "0" and the next char is a digit then yet another charcter is present.
But we require our inut to be zero terminated. And that means we do not
have to check anything for this scanner.
However with other rule sets re2c might read more then one character in a
row. In those cases it is normally hard to impossible to avoid YYFILL.
- optimizing the generated code by using -s command line switch of re2c
. This tells re2c to generate code that uses if statements rather
then endless switch/case expressions where appropriate. Note that the
generated code now requires the input to be unsigned char rather than char
due to the way comparisons are generated.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define DEBUG(stmt) stmt
int stack[4];
int depth = 0;
int push_num(const unsigned char *t, const unsigned char *l, int radix)
{
int num = 0;
if (depth >= sizeof(stack))
{
return 3;
}
--t;
while(++t < l)
{
num = num * radix + (*t - (unsigned char)'0');
}
DEBUG(printf("Num: %d\n", num));
stack[depth++] = num;
return 0;
}
int stack_add()
{
if (depth < 2) return 4;
--depth;
stack[depth-1] = stack[depth-1] + stack[depth];
DEBUG(printf("+\n"));
return 0;
}
int stack_sub()
{
if (depth < 2) return 4;
--depth;
stack[depth-1] = stack[depth-1] - stack[depth];
DEBUG(printf("-\n"));
return 0;
}
int scan(char *s)
{
unsigned char *p = (unsigned char*)s;
unsigned char *t;
int res = 0;
#define YYCTYPE unsigned char
#define YYCURSOR p
while(!res)
{
t = p;
/*!re2c
re2c:indent:top = 2;
re2c:yyfill:enable = 0;
DIGIT = [0-9] ;
OCT = "0" DIGIT+ ;
INT = "0" | ( [1-9] DIGIT* ) ;
WS = [ \t]+ ;
WS { continue; }
OCT { res = push_num(t, p, 8); continue; }
INT { res = push_num(t, p, 10); continue; }
"+" { res = stack_add(); continue; }
"-" { res = stack_sub(); continue; }
"\000" { res = depth == 1 ? 0 : 2; break; }
[^] { res = 1; continue; }
*/
}
return res;
}
int main(int argc, char **argv)
{
if (argc > 1)
{
char *inp;
int res = 0, argp = 0, len;
while(!res && ++argp < argc)
{
inp = strdup(argv[argp]);
len = strlen(inp);
if (inp[0] == '\"' && inp[len-1] == '\"')
{
inp[len - 1] = '\0';
++inp;
}
res = scan(inp);
free(inp);
}
switch(res)
{
case 0:
printf("Result: %d\n", stack[0]);
return 0;
case 1:
fprintf(stderr, "Illegal character in input.\n");
return 1;
case 2:
fprintf(stderr, "Premature end of input.\n");
return 2;
case 3:
fprintf(stderr, "Stack overflow.\n");
return 3;
case 4:
fprintf(stderr, "Stack underflow.\n");
return 4;
}
}
else
{
fprintf(stderr, "%s <expr>\n", argv[0]);
return 0;
}
}
@@ -1,239 +0,0 @@
/* Generated by re2c */
#line 1 "calc_007.b.re"
/* re2c lesson 001_upn_calculator, calc_007, (c) M. Boerger 2006 - 2007 */
#line 9 "calc_007.b.re"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define DEBUG(stmt) stmt
int stack[4];
int depth = 0;
int push_num(const unsigned char *t, const unsigned char *l, int radix)
{
int num = 0;
if (depth >= sizeof(stack))
{
return 3;
}
--t;
while(++t < l)
{
num = num * radix + (*t - (unsigned char)'0');
}
DEBUG(printf("Num: %d\n", num));
stack[depth++] = num;
return 0;
}
int stack_add()
{
if (depth < 2) return 4;
--depth;
stack[depth-1] = stack[depth-1] + stack[depth];
DEBUG(printf("+\n"));
return 0;
}
int stack_sub()
{
if (depth < 2) return 4;
--depth;
stack[depth-1] = stack[depth-1] - stack[depth];
DEBUG(printf("+\n"));
return 0;
}
int scan(char *s)
{
unsigned char *p = (unsigned char*)s;
unsigned char *t;
int res = 0;
#define YYCTYPE unsigned char
#define YYCURSOR p
while(!res)
{
t = p;
#line 69 "<stdout>"
{
YYCTYPE yych;
static const unsigned char yybm[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 128, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
128, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
yych = *YYCURSOR;
if (yych <= '*') {
if (yych <= '\t') {
if (yych <= 0x00) goto yy11;
if (yych <= 0x08) goto yy13;
} else {
if (yych != ' ') goto yy13;
}
} else {
if (yych <= '-') {
if (yych <= '+') goto yy7;
if (yych <= ',') goto yy13;
goto yy9;
} else {
if (yych <= '/') goto yy13;
if (yych <= '0') goto yy4;
if (yych <= '9') goto yy6;
goto yy13;
}
}
++YYCURSOR;
yych = *YYCURSOR;
goto yy21;
yy3:
#line 80 "calc_007.b.re"
{ continue; }
#line 133 "<stdout>"
yy4:
++YYCURSOR;
if ((yych = *YYCURSOR) <= '/') goto yy5;
if (yych <= '9') goto yy17;
yy5:
#line 82 "calc_007.b.re"
{ res = push_num(t, p, 10); continue; }
#line 141 "<stdout>"
yy6:
yych = *++YYCURSOR;
goto yy16;
yy7:
++YYCURSOR;
#line 83 "calc_007.b.re"
{ res = stack_add(); continue; }
#line 149 "<stdout>"
yy9:
++YYCURSOR;
#line 84 "calc_007.b.re"
{ res = stack_sub(); continue; }
#line 154 "<stdout>"
yy11:
++YYCURSOR;
#line 85 "calc_007.b.re"
{ res = depth == 1 ? 0 : 2; break; }
#line 159 "<stdout>"
yy13:
++YYCURSOR;
#line 86 "calc_007.b.re"
{ res = 1; continue; }
#line 164 "<stdout>"
yy15:
++YYCURSOR;
yych = *YYCURSOR;
yy16:
if (yybm[0+yych] & 64) {
goto yy15;
}
goto yy5;
yy17:
++YYCURSOR;
yych = *YYCURSOR;
if (yych <= '/') goto yy19;
if (yych <= '9') goto yy17;
yy19:
#line 81 "calc_007.b.re"
{ res = push_num(t, p, 8); continue; }
#line 181 "<stdout>"
yy20:
++YYCURSOR;
yych = *YYCURSOR;
yy21:
if (yybm[0+yych] & 128) {
goto yy20;
}
goto yy3;
}
#line 87 "calc_007.b.re"
}
return res;
}
int main(int argc, char **argv)
{
if (argc > 1)
{
char *inp;
int res = 0, argp = 0, len;
while(!res && ++argp < argc)
{
inp = strdup(argv[argp]);
len = strlen(inp);
if (inp[0] == '\"' && inp[len-1] == '\"')
{
inp[len - 1] = '\0';
++inp;
}
res = scan(inp);
free(inp);
}
switch(res)
{
case 0:
printf("Result: %d\n", stack[0]);
return 0;
case 1:
fprintf(stderr, "Illegal character in input.\n");
return 1;
case 2:
fprintf(stderr, "Premature end of input.\n");
return 2;
case 3:
fprintf(stderr, "Stack overflow.\n");
return 3;
case 4:
fprintf(stderr, "Stack underflow.\n");
return 4;
}
}
else
{
fprintf(stderr, "%s <expr>\n", argv[0]);
return 0;
}
}
@@ -1,135 +0,0 @@
/* re2c lesson 001_upn_calculator, calc_007, (c) M. Boerger 2006 - 2007 */
/*!ignore:re2c
- optimizing the generated code by using -b command line switch of re2c
. This tells re2c to generate code that uses a decision table. The -b switch
also contains the -s behavior. And -b also requires the input to be
unsigned chars.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define DEBUG(stmt) stmt
int stack[4];
int depth = 0;
int push_num(const unsigned char *t, const unsigned char *l, int radix)
{
int num = 0;
if (depth >= sizeof(stack))
{
return 3;
}
--t;
while(++t < l)
{
num = num * radix + (*t - (unsigned char)'0');
}
DEBUG(printf("Num: %d\n", num));
stack[depth++] = num;
return 0;
}
int stack_add()
{
if (depth < 2) return 4;
--depth;
stack[depth-1] = stack[depth-1] + stack[depth];
DEBUG(printf("+\n"));
return 0;
}
int stack_sub()
{
if (depth < 2) return 4;
--depth;
stack[depth-1] = stack[depth-1] - stack[depth];
DEBUG(printf("+\n"));
return 0;
}
int scan(char *s)
{
unsigned char *p = (unsigned char*)s;
unsigned char *t;
int res = 0;
#define YYCTYPE unsigned char
#define YYCURSOR p
while(!res)
{
t = p;
/*!re2c
re2c:indent:top = 2;
re2c:yyfill:enable = 0;
DIGIT = [0-9] ;
OCT = "0" DIGIT+ ;
INT = "0" | ( [1-9] DIGIT* ) ;
WS = [ \t]+ ;
WS { continue; }
OCT { res = push_num(t, p, 8); continue; }
INT { res = push_num(t, p, 10); continue; }
"+" { res = stack_add(); continue; }
"-" { res = stack_sub(); continue; }
"\000" { res = depth == 1 ? 0 : 2; break; }
[^] { res = 1; continue; }
*/
}
return res;
}
int main(int argc, char **argv)
{
if (argc > 1)
{
char *inp;
int res = 0, argp = 0, len;
while(!res && ++argp < argc)
{
inp = strdup(argv[argp]);
len = strlen(inp);
if (inp[0] == '\"' && inp[len-1] == '\"')
{
inp[len - 1] = '\0';
++inp;
}
res = scan(inp);
free(inp);
}
switch(res)
{
case 0:
printf("Result: %d\n", stack[0]);
return 0;
case 1:
fprintf(stderr, "Illegal character in input.\n");
return 1;
case 2:
fprintf(stderr, "Premature end of input.\n");
return 2;
case 3:
fprintf(stderr, "Stack overflow.\n");
return 3;
case 4:
fprintf(stderr, "Stack underflow.\n");
return 4;
}
}
else
{
fprintf(stderr, "%s <expr>\n", argv[0]);
return 0;
}
}
@@ -1,235 +0,0 @@
/* Generated by re2c */
#line 1 "calc_008.b.re"
/* re2c lesson 001_upn_calculator, calc_008, (c) M. Boerger 2006 - 2007 */
#line 31 "calc_008.b.re"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define DEBUG(stmt) stmt
int stack[4];
int depth = 0;
int push_num(const char *t, const char *l, int radix)
{
int num = 0;
if (depth >= sizeof(stack))
{
return 3;
}
--t;
while(++t < l)
{
num = num * radix + (*t - '0');
}
DEBUG(printf("Num: %d\n", num));
stack[depth++] = num;
return 0;
}
int stack_add()
{
if (depth < 2) return 4;
--depth;
stack[depth-1] = stack[depth-1] + stack[depth];
DEBUG(printf("+\n"));
return 0;
}
int stack_sub()
{
if (depth < 2) return 4;
--depth;
stack[depth-1] = stack[depth-1] - stack[depth];
DEBUG(printf("+\n"));
return 0;
}
int scan(char *p)
{
char *t;
int res = 0;
while(!res)
{
t = p;
#line 65 "<stdout>"
{
unsigned char curr;
static const unsigned char yybm[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 128, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
128, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
curr = (unsigned char)*p;
if (curr <= '*') {
if (curr <= '\t') {
if (curr <= 0x00) goto scan11;
if (curr <= 0x08) goto scan13;
} else {
if (curr != ' ') goto scan13;
}
} else {
if (curr <= '-') {
if (curr <= '+') goto scan7;
if (curr <= ',') goto scan13;
goto scan9;
} else {
if (curr <= '/') goto scan13;
if (curr <= '0') goto scan4;
if (curr <= '9') goto scan6;
goto scan13;
}
}
++p;
curr = (unsigned char)*p;
goto scan21;
scan3:
#line 103 "calc_008.b.re"
{ continue; }
#line 129 "<stdout>"
scan4:
++p;
if ((curr = (unsigned char)*p) <= '/') goto scan5;
if (curr <= '9') goto scan17;
scan5:
#line 105 "calc_008.b.re"
{ res = push_num(t, p, 10); continue; }
#line 137 "<stdout>"
scan6:
curr = (unsigned char)*++p;
goto scan16;
scan7:
++p;
#line 106 "calc_008.b.re"
{ res = stack_add(); continue; }
#line 145 "<stdout>"
scan9:
++p;
#line 107 "calc_008.b.re"
{ res = stack_sub(); continue; }
#line 150 "<stdout>"
scan11:
++p;
#line 108 "calc_008.b.re"
{ res = depth == 1 ? 0 : 2; break; }
#line 155 "<stdout>"
scan13:
++p;
#line 109 "calc_008.b.re"
{ res = 1; continue; }
#line 160 "<stdout>"
scan15:
++p;
curr = (unsigned char)*p;
scan16:
if (yybm[0+curr] & 64) {
goto scan15;
}
goto scan5;
scan17:
++p;
curr = (unsigned char)*p;
if (curr <= '/') goto scan19;
if (curr <= '9') goto scan17;
scan19:
#line 104 "calc_008.b.re"
{ res = push_num(t, p, 8); continue; }
#line 177 "<stdout>"
scan20:
++p;
curr = (unsigned char)*p;
scan21:
if (yybm[0+curr] & 128) {
goto scan20;
}
goto scan3;
}
#line 110 "calc_008.b.re"
}
return res;
}
int main(int argc, char **argv)
{
if (argc > 1)
{
char *inp;
int res = 0, argp = 0, len;
while(!res && ++argp < argc)
{
inp = strdup(argv[argp]);
len = strlen(inp);
if (inp[0] == '\"' && inp[len-1] == '\"')
{
inp[len - 1] = '\0';
++inp;
}
res = scan(inp);
free(inp);
}
switch(res)
{
case 0:
printf("Result: %d\n", stack[0]);
return 0;
case 1:
fprintf(stderr, "Illegal character in input.\n");
return 1;
case 2:
fprintf(stderr, "Premature end of input.\n");
return 2;
case 3:
fprintf(stderr, "Stack overflow.\n");
return 3;
case 4:
fprintf(stderr, "Stack underflow.\n");
return 4;
}
}
else
{
fprintf(stderr, "%s <expr>\n", argv[0]);
return 0;
}
}
@@ -1,158 +0,0 @@
/* re2c lesson 001_upn_calculator, calc_008, (c) M. Boerger 2006 - 2007 */
/*!ignore:re2c
- using -b with signed character input
. Since the code is being generated with -b switch re2c requires the internal
character variable yych to use an unsigned character type. For that reason
the previous lessons had a conversion at the beginning of their scan()
function. Other re2c generated code often have the scanners work completely
on unsigned input. Thus requesting a conversion.
To avoid the conversion on input, re2c allows to do the conversion when
reading the internal yych variable. To enable that conversion you need to
use the implace configuration 're2c:yych:conversion' and set it to 1. This
will change the generated code to insert conversions to YYCTYPE whenever
yych is being read.
- More inplace configurations for better/nicer code
. re2c allows to overwrite the generation of any define, label or variable
used in the generated code. For example we overwrite the 'yych' variable
name to 'curr' using inplace configuration 're2c:variable:yych = curr;'.
. We further more use inplace configurations instead of defines. This allows
to use correct conversions to 'unsigned char' instead of having to convert
to 'YYCTYPE' when placing 're2c:define:YYCTYPE = "unsigned char";' infront
of 're2c:yych:conversion'. Note that we have to use apostrophies for the
first setting as it contains a space.
. Last but not least we use 're2c:labelprefix = scan' to change the prefix
of generated labels.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define DEBUG(stmt) stmt
int stack[4];
int depth = 0;
int push_num(const char *t, const char *l, int radix)
{
int num = 0;
if (depth >= sizeof(stack))
{
return 3;
}
--t;
while(++t < l)
{
num = num * radix + (*t - '0');
}
DEBUG(printf("Num: %d\n", num));
stack[depth++] = num;
return 0;
}
int stack_add()
{
if (depth < 2) return 4;
--depth;
stack[depth-1] = stack[depth-1] + stack[depth];
DEBUG(printf("+\n"));
return 0;
}
int stack_sub()
{
if (depth < 2) return 4;
--depth;
stack[depth-1] = stack[depth-1] - stack[depth];
DEBUG(printf("+\n"));
return 0;
}
int scan(char *p)
{
char *t;
int res = 0;
while(!res)
{
t = p;
/*!re2c
re2c:define:YYCTYPE = "unsigned char";
re2c:define:YYCURSOR = p;
re2c:variable:yych = curr;
re2c:indent:top = 2;
re2c:yyfill:enable = 0;
re2c:yych:conversion = 1;
re2c:labelprefix = scan;
DIGIT = [0-9] ;
OCT = "0" DIGIT+ ;
INT = "0" | ( [1-9] DIGIT* ) ;
WS = [ \t]+ ;
WS { continue; }
OCT { res = push_num(t, p, 8); continue; }
INT { res = push_num(t, p, 10); continue; }
"+" { res = stack_add(); continue; }
"-" { res = stack_sub(); continue; }
"\000" { res = depth == 1 ? 0 : 2; break; }
[^] { res = 1; continue; }
*/
}
return res;
}
int main(int argc, char **argv)
{
if (argc > 1)
{
char *inp;
int res = 0, argp = 0, len;
while(!res && ++argp < argc)
{
inp = strdup(argv[argp]);
len = strlen(inp);
if (inp[0] == '\"' && inp[len-1] == '\"')
{
inp[len - 1] = '\0';
++inp;
}
res = scan(inp);
free(inp);
}
switch(res)
{
case 0:
printf("Result: %d\n", stack[0]);
return 0;
case 1:
fprintf(stderr, "Illegal character in input.\n");
return 1;
case 2:
fprintf(stderr, "Premature end of input.\n");
return 2;
case 3:
fprintf(stderr, "Stack overflow.\n");
return 3;
case 4:
fprintf(stderr, "Stack underflow.\n");
return 4;
}
}
else
{
fprintf(stderr, "%s <expr>\n", argv[0]);
return 0;
}
}
@@ -1,83 +0,0 @@
re2c lesson 001_upn_calculator, (c) M. Boerger 2006
This lesson gets you started with re2c. In the end you will have an easy RPN
(reverse polish notation) 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.
Once you have successfully installed re2c you can use it to generate *.c files
from the *.re files presented in this lesson. Actually the expected *.c files
are already present. So you should name them *.cc or something alike or just
give them a different name like test.c. To do so you simply change into the
directory and execute the following command:
re2c calc_001.re > test.c
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 <input_file_name>
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
followed by the output filename:
re2c -o test.c calc_001.re
The input files *.re each contain basic step by comments that explain what is
going on and what you can see in the examples.
In order to optimize the generated code we will use the -s command line switch
of re2c. This tells re2c to generate code that uses if statements rather
then endless switch/case expressions where appropriate. Note that the file name
extension is actually '.s.re' to tell the test system to use the -s switch. To
invoke re2 you do the following:
re2c -s -o test.c calc_006.s.re
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 Allan 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.
-------------------------------------------------------------------------------
Sidenote: UPN is the german translation of RPN, somehow hardcoded into the
authors brain :-)
@@ -1,48 +0,0 @@
@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
@@ -1,54 +0,0 @@
/**
* @file HiResTimer.h
* @brief
* @note
*/
#ifndef _HI_RES_TIMER_H_
#define _HI_RES_TIMER_H_
#ifdef WIN32
#include <windows.h> // 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
@@ -1,19 +0,0 @@
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
@@ -1,252 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="TestRe2c"
ProjectGUID="{E2CEB3D0-066A-4C9A-B32C-B2197448A57A}"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/TestRe2c.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
PrecompiledHeaderThrough=""
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Debug/TestRe2c.exe"
LinkIncremental="0"
SuppressStartupBanner="true"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/TestRe2c.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/TestRe2c.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/O2"
Optimization="2"
InlineFunctionExpansion="1"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
PrecompiledHeaderThrough=""
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="true"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Release/TestRe2c.exe"
LinkIncremental="0"
SuppressStartupBanner="true"
ProgramDatabaseFile=".\Release/TestRe2c.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath="main.b.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="main.b.re"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="Generate $(InputName).c from $(InputName).re using Re2c"
CommandLine="..\..\..\Release-2005\re2c.exe -b -o$(InputName).c $(InputName).re&#x0D;&#x0A;"
Outputs="$(InputName).c"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="Generate $(InputName).c from $(InputName).re using Re2c"
CommandLine="..\..\..\Rlease-2005\re2c.exe -b -o$(InputName).c $(InputName).re&#x0D;&#x0A;"
Outputs="$(InputName).c"
/>
</FileConfiguration>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
@@ -1,124 +0,0 @@
# 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
@@ -1,29 +0,0 @@
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>
{{{
}}}
###############################################################################
@@ -1,21 +0,0 @@
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
@@ -1,138 +0,0 @@
<?xml version="1.0" encoding = "Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.00"
Name="Re2cTest"
ProjectGUID="{BEC086F1-62CD-4BA7-8E17-367B825FA721}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/Re2cTest.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/Re2cTest.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
OmitFramePointers="TRUE"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/Re2cTest.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
</Configuration>
</Configurations>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
<File
RelativePath="main.b.c">
</File>
<File
RelativePath="main.b.re">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCustomBuildTool"
Description="Generate $(InputName).c from $(InputName).re using Re2c"
CommandLine="..\..\..\Release\re2c.exe -b -o$(InputName).c $(InputName).re"
Outputs="$(InputName).c"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCustomBuildTool"
Description="Generate $(InputName).c from $(InputName).re using Re2c"
CommandLine="..\..\..\Release\re2c.exe -b -o$(InputName).c $(InputName).re"
Outputs="$(InputName).c"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx">
<File
RelativePath="HiResTimer.h">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
@@ -1,452 +0,0 @@
/* Generated by re2c */
#line 1 "main.b.re"
/* re2c lesson 001_upn_calculator, main.b.re, (c) M. Boerger, L. Allan 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 <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <windows.h>
#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)
{
unsigned char *pzCurScanPos = (unsigned char*)pzStrToScan;
unsigned char *pzBacktrackInfo = 0;
#define YYCTYPE unsigned char
#define YYCURSOR pzCurScanPos
#define YYLIMIT (pzStrToScan+lenStrToScan)
#define YYMARKER pzBacktrackInfo
#define YYFILL(n)
for(;;)
{
#line 55 "<stdout>"
{
YYCTYPE yych;
static const 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,
};
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 114 "<stdout>"
yy4:
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 128) {
goto yy13;
}
yy5:
#line 98 "main.b.re"
{ return 1; }
#line 123 "<stdout>"
yy6:
++YYCURSOR;
#line 95 "main.b.re"
{ continue; }
#line 128 "<stdout>"
yy8:
++YYCURSOR;
#line 96 "main.b.re"
{ continue; }
#line 133 "<stdout>"
yy10:
++YYCURSOR;
#line 97 "main.b.re"
{ return 0; }
#line 138 "<stdout>"
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 151 "<stdout>"
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)
{
unsigned char *pzCurScanPos = (unsigned char*)pzStrToScan;
unsigned char *pzBacktrackInfo = 0;
#define YYCTYPE unsigned char
#define YYCURSOR pzCurScanPos
#define YYLIMIT (pzStrToScan+lenStrToScan)
#define YYMARKER pzBacktrackInfo
#define YYFILL(n)
for(;;)
{
#line 182 "<stdout>"
{
YYCTYPE yych;
static const 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,
};
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 240 "<stdout>"
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 249 "<stdout>"
yy24:
++YYCURSOR;
#line 122 "main.b.re"
{ printf("+\n"); strcat(gTestBuf, "+ "); continue; }
#line 254 "<stdout>"
yy26:
++YYCURSOR;
#line 123 "main.b.re"
{ printf("-\n"); strcat(gTestBuf, "- "); continue; }
#line 259 "<stdout>"
yy28:
++YYCURSOR;
#line 124 "main.b.re"
{ printf("EOF\n"); return 0; }
#line 264 "<stdout>"
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 277 "<stdout>"
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;
}
@@ -1,291 +0,0 @@
/* re2c lesson 001_upn_calculator, main.b.re, (c) M. Boerger, L. Allan 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' scanner
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
our 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 <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <windows.h>
#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)
{
unsigned char *pzCurScanPos = (unsigned char*)pzStrToScan;
unsigned char *pzBacktrackInfo = 0;
#define YYCTYPE unsigned 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)
{
unsigned char *pzCurScanPos = (unsigned char*)pzStrToScan;
unsigned char *pzBacktrackInfo = 0;
#define YYCTYPE unsigned 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;
}
@@ -1,21 +0,0 @@
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
will have a scanner that filters comments out of c source files but keeps re2c
comments.
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.
re2c -s -0 t.c strip_002.b.re
The third step brings trailing contexts that are stored in YYCTXMARKER. We also
change to use -b instead of -s option since the scanner gets more and more
complex.
re2c -b -0 t.c strip_002.b.re
@@ -1,187 +0,0 @@
/* Generated by re2c */
#line 1 "strip_001.s.re"
/* re2c lesson 002_strip_comments, strip_001.s, (c) M. Boerger 2006 - 2007 */
#line 32 "strip_001.s.re"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define YYMAXFILL 2
#define BSIZE 128
#if BSIZE < YYMAXFILL
# error BSIZE must be greater YYMAXFILL
#endif
#define YYCTYPE unsigned char
#define YYCURSOR s.cur
#define YYLIMIT s.lim
#define YYFILL(n) { if ((res = fill(&s, n)) >= 0) break; }
typedef struct Scanner
{
FILE *fp;
unsigned char *cur, *tok, *lim, *eof;
unsigned char buffer[BSIZE];
} Scanner;
int fill(Scanner *s, int len)
{
if (!len)
{
s->cur = s->tok = s->lim = s->buffer;
s->eof = 0;
}
if (!s->eof)
{
int got, cnt = s->tok - s->buffer;
if (cnt > 0)
{
memcpy(s->buffer, s->tok, s->lim - s->tok);
s->tok -= cnt;
s->cur -= cnt;
s->lim -= cnt;
}
cnt = BSIZE - cnt;
if ((got = fread(s->lim, 1, cnt, s->fp)) != cnt)
{
s->eof = &s->lim[got];
}
s->lim += got;
}
else if (s->cur + len > s->eof)
{
return 0; /* not enough input data */
}
return -1;
}
int scan(FILE *fp)
{
int res = 0;
Scanner s;
if (!fp)
{
return 1; /* no file was opened */
}
s.fp = fp;
fill(&s, 0);
for(;;)
{
s.tok = s.cur;
#line 80 "<stdout>"
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
if (yych != '/') goto yy4;
++YYCURSOR;
if ((yych = *YYCURSOR) == '*') goto yy5;
if (yych == '/') goto yy7;
yy3:
#line 113 "strip_001.s.re"
{ fputc(*s.tok, stdout); continue; }
#line 93 "<stdout>"
yy4:
yych = *++YYCURSOR;
goto yy3;
yy5:
++YYCURSOR;
#line 112 "strip_001.s.re"
{ goto comment; }
#line 101 "<stdout>"
yy7:
++YYCURSOR;
#line 111 "strip_001.s.re"
{ goto cppcomment; }
#line 106 "<stdout>"
}
#line 114 "strip_001.s.re"
comment:
s.tok = s.cur;
#line 113 "<stdout>"
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
if (yych != '*') goto yy13;
++YYCURSOR;
if ((yych = *YYCURSOR) == '/') goto yy14;
yy12:
#line 119 "strip_001.s.re"
{ goto comment; }
#line 124 "<stdout>"
yy13:
yych = *++YYCURSOR;
goto yy12;
yy14:
++YYCURSOR;
#line 118 "strip_001.s.re"
{ continue; }
#line 132 "<stdout>"
}
#line 120 "strip_001.s.re"
cppcomment:
s.tok = s.cur;
#line 139 "<stdout>"
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
if (yych == '\n') goto yy20;
if (yych != '\r') goto yy22;
++YYCURSOR;
if ((yych = *YYCURSOR) == '\n') goto yy23;
yy19:
#line 125 "strip_001.s.re"
{ goto cppcomment; }
#line 151 "<stdout>"
yy20:
++YYCURSOR;
yy21:
#line 124 "strip_001.s.re"
{ fwrite(s.tok, 1, s.cur - s.tok, stdout); continue; }
#line 157 "<stdout>"
yy22:
yych = *++YYCURSOR;
goto yy19;
yy23:
++YYCURSOR;
yych = *YYCURSOR;
goto yy21;
}
#line 126 "strip_001.s.re"
}
if (fp != stdin)
{
fclose(fp); /* close only if not stdin */
}
return res; /* return result */
}
int main(int argc, char **argv)
{
if (argc > 1)
{
return scan(!strcmp(argv[1], "-") ? stdin : fopen(argv[1], "r"));
}
else
{
fprintf(stderr, "%s <expr>\n", argv[0]);
return 1;
}
}
@@ -1,147 +0,0 @@
/* re2c lesson 002_strip_comments, strip_001.s, (c) M. Boerger 2006 - 2007 */
/*!ignore:re2c
- basic interface for file reading
. This scanner will read chunks of input from a file. The easiest way would
be to read the whole file into a memory buffer and use that a zero
terminated string.
. Instead we want to read input chunks of a reasonable size as they are neede
by the scanner. Thus we basically need YYFILL(n) to call fread(n).
. Before we provide a buffer that we constantly reallocate we instead use
one buffer that we get from the stack or global memory just once. When we
reach the end of the buffer we simply move the beginning of our input
that is somewhere in our buffer to the beginning of our buffer and then
append the next chunk of input to the correct end inside our buffer.
. As re2c scanners might read more than one character we need to ensure our
buffer is long enough. We can use re2c to inform about the maximum size
by placing a "!max:re2c" comment somewhere. This gets translated to a
"#define YYMAXFILL <n>" line where <n> is the maximum length value. This
define can be used as precompiler condition.
- multiple scanner blocks
. We use a main scanner block that outputs every input character unless the
input is two /s or a / followed by a *. In the latter two cases we switch
to a special c++ comment and a comment block respectively.
. Both special blocks simply detect their end ignore any other character.
. The c++ block is a bit special. Since the terminating new line needs to
be output and that can either be a new line or a carridge return followed
by a new line.
. In order to ensure that we do not read behind our buffer we reset the token
pointer to the cursor on every scanner run.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/*!max:re2c */
#define BSIZE 128
#if BSIZE < YYMAXFILL
# error BSIZE must be greater YYMAXFILL
#endif
#define YYCTYPE unsigned char
#define YYCURSOR s.cur
#define YYLIMIT s.lim
#define YYFILL(n) { if ((res = fill(&s, n)) >= 0) break; }
typedef struct Scanner
{
FILE *fp;
unsigned char *cur, *tok, *lim, *eof;
unsigned char buffer[BSIZE];
} Scanner;
int fill(Scanner *s, int len)
{
if (!len)
{
s->cur = s->tok = s->lim = s->buffer;
s->eof = 0;
}
if (!s->eof)
{
int got, cnt = s->tok - s->buffer;
if (cnt > 0)
{
memcpy(s->buffer, s->tok, s->lim - s->tok);
s->tok -= cnt;
s->cur -= cnt;
s->lim -= cnt;
}
cnt = BSIZE - cnt;
if ((got = fread(s->lim, 1, cnt, s->fp)) != cnt)
{
s->eof = &s->lim[got];
}
s->lim += got;
}
else if (s->cur + len > s->eof)
{
return 0; /* not enough input data */
}
return -1;
}
int scan(FILE *fp)
{
int res = 0;
Scanner s;
if (!fp)
{
return 1; /* no file was opened */
}
s.fp = fp;
fill(&s, 0);
for(;;)
{
s.tok = s.cur;
/*!re2c
re2c:indent:top = 2;
NL = "\r"? "\n" ;
ANY = [^] ;
"/" "/" { goto cppcomment; }
"/" "*" { goto comment; }
ANY { fputc(*s.tok, stdout); continue; }
*/
comment:
s.tok = s.cur;
/*!re2c
"*" "/" { continue; }
ANY { goto comment; }
*/
cppcomment:
s.tok = s.cur;
/*!re2c
NL { fwrite(s.tok, 1, s.cur - s.tok, stdout); continue; }
ANY { goto cppcomment; }
*/
}
if (fp != stdin)
{
fclose(fp); /* close only if not stdin */
}
return res; /* return result */
}
int main(int argc, char **argv)
{
if (argc > 1)
{
return scan(!strcmp(argv[1], "-") ? stdin : fopen(argv[1], "r"));
}
else
{
fprintf(stderr, "%s <expr>\n", argv[0]);
return 1;
}
}
@@ -1,240 +0,0 @@
/* Generated by re2c */
#line 1 "strip_002.s.re"
/* re2c lesson 002_strip_comments, strip_002.s, (c) M. Boerger 2006 - 2007 */
#line 32 "strip_002.s.re"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define YYMAXFILL 2
#define BSIZE 128
#if BSIZE < YYMAXFILL
# error BSIZE must be greater YYMAXFILL
#endif
#define YYCTYPE unsigned char
#define YYCURSOR s.cur
#define YYLIMIT s.lim
#define YYMARKER s.mrk
#define YYFILL(n) { if ((res = fill(&s, n)) >= 0) break; }
typedef struct Scanner
{
FILE *fp;
unsigned char *cur, *tok, *lim, *eof, *mrk;
unsigned char buffer[BSIZE];
} Scanner;
int fill(Scanner *s, int len)
{
if (!len)
{
s->cur = s->tok = s->lim = s->mrk = s->buffer;
s->eof = 0;
}
if (!s->eof)
{
int got, cnt = s->tok - s->buffer;
if (cnt > 0)
{
memcpy(s->buffer, s->tok, s->lim - s->tok);
s->tok -= cnt;
s->cur -= cnt;
s->lim -= cnt;
s->mrk -= cnt;
}
cnt = BSIZE - cnt;
if ((got = fread(s->lim, 1, cnt, s->fp)) != cnt)
{
s->eof = &s->lim[got];
}
s->lim += got;
}
else if (s->cur + len > s->eof)
{
return 0; /* not enough input data */
}
return -1;
}
void echo(Scanner *s)
{
fwrite(s->tok, 1, s->cur - s->tok, stdout);
}
int scan(FILE *fp)
{
int res = 0;
Scanner s;
if (!fp)
{
return 1; /* no file was opened */
}
s.fp = fp;
fill(&s, 0);
for(;;)
{
s.tok = s.cur;
#line 87 "<stdout>"
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
if (yych != '/') goto yy4;
++YYCURSOR;
if ((yych = *YYCURSOR) == '*') goto yy5;
if (yych == '/') goto yy7;
yy3:
#line 121 "strip_002.s.re"
{ fputc(*s.tok, stdout); continue; }
#line 100 "<stdout>"
yy4:
yych = *++YYCURSOR;
goto yy3;
yy5:
++YYCURSOR;
#line 120 "strip_002.s.re"
{ goto comment; }
#line 108 "<stdout>"
yy7:
++YYCURSOR;
#line 119 "strip_002.s.re"
{ goto cppcomment; }
#line 113 "<stdout>"
}
#line 122 "strip_002.s.re"
comment:
s.tok = s.cur;
#line 120 "<stdout>"
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
if (yych != '*') goto yy13;
++YYCURSOR;
if ((yych = *YYCURSOR) == '/') goto yy14;
yy12:
#line 127 "strip_002.s.re"
{ goto comment; }
#line 131 "<stdout>"
yy13:
yych = *++YYCURSOR;
goto yy12;
yy14:
++YYCURSOR;
#line 126 "strip_002.s.re"
{ goto commentws; }
#line 139 "<stdout>"
}
#line 128 "strip_002.s.re"
commentws:
s.tok = s.cur;
#line 146 "<stdout>"
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
if (yych <= '\f') {
if (yych <= 0x08) goto yy23;
if (yych <= '\t') goto yy22;
if (yych <= '\n') goto yy20;
goto yy23;
} else {
if (yych <= '\r') goto yy18;
if (yych == ' ') goto yy22;
goto yy23;
}
yy18:
++YYCURSOR;
if ((yych = *YYCURSOR) == '\n') goto yy25;
yy19:
#line 133 "strip_002.s.re"
{ goto commentws; }
#line 167 "<stdout>"
yy20:
++YYCURSOR;
yy21:
#line 132 "strip_002.s.re"
{ echo(&s); continue; }
#line 173 "<stdout>"
yy22:
yych = *++YYCURSOR;
goto yy19;
yy23:
++YYCURSOR;
#line 134 "strip_002.s.re"
{ echo(&s); continue; }
#line 181 "<stdout>"
yy25:
++YYCURSOR;
yych = *YYCURSOR;
goto yy21;
}
#line 135 "strip_002.s.re"
cppcomment:
s.tok = s.cur;
#line 192 "<stdout>"
{
YYCTYPE yych;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
if (yych == '\n') goto yy30;
if (yych != '\r') goto yy32;
++YYCURSOR;
if ((yych = *YYCURSOR) == '\n') goto yy33;
yy29:
#line 140 "strip_002.s.re"
{ goto cppcomment; }
#line 204 "<stdout>"
yy30:
++YYCURSOR;
yy31:
#line 139 "strip_002.s.re"
{ echo(&s); continue; }
#line 210 "<stdout>"
yy32:
yych = *++YYCURSOR;
goto yy29;
yy33:
++YYCURSOR;
yych = *YYCURSOR;
goto yy31;
}
#line 141 "strip_002.s.re"
}
if (fp != stdin)
{
fclose(fp); /* close only if not stdin */
}
return res; /* return result */
}
int main(int argc, char **argv)
{
if (argc > 1)
{
return scan(!strcmp(argv[1], "-") ? stdin : fopen(argv[1], "r"));
}
else
{
fprintf(stderr, "%s <expr>\n", argv[0]);
return 1;
}
}
@@ -1,162 +0,0 @@
/* re2c lesson 002_strip_comments, strip_002.s, (c) M. Boerger 2006 - 2007 */
/*!ignore:re2c
- complexity
. When a comment is preceded by a new line and followed by whitespace and a
new line then we can drop the trailing whitespace and new line.
. Additional to what we strip out already what about two consecutive comment
blocks? When two comments are only separated by whitespace we want to drop
both. In other words when detecting the end of a comment block we need to
check whether it is followed by only whitespace and the a new comment in
which case we continue ignoring the input. If it is followed only by white
space and a new line we strip out the new white space and new line. In any
other case we start outputting all that follows.
But we cannot simply use the following two rules:
"*" "/" WS* "/" "*" { continue; }
"*" "/" WS* NL { continue; }
The main problem is that WS* can get bigger then our buffer, so we need a
new scanner.
. Meanwhile our scanner gets a bit more complex and we have to add two more
things. First the scanner code now uses a YYMARKER to store backtracking
information.
- backtracking information
. When the scanner has two rules that can have the same beginning but a
different ending then it needs to store the position that identifies the
common part. This is called backtracking. As mentioned above re2c expects
you to provide compiler define YYMARKER and a pointer variable.
. When shifting buffer contents as done in our fill function the marker needs
to be corrected, too.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/*!max:re2c */
#define BSIZE 128
#if BSIZE < YYMAXFILL
# error BSIZE must be greater YYMAXFILL
#endif
#define YYCTYPE unsigned char
#define YYCURSOR s.cur
#define YYLIMIT s.lim
#define YYMARKER s.mrk
#define YYFILL(n) { if ((res = fill(&s, n)) >= 0) break; }
typedef struct Scanner
{
FILE *fp;
unsigned char *cur, *tok, *lim, *eof, *mrk;
unsigned char buffer[BSIZE];
} Scanner;
int fill(Scanner *s, int len)
{
if (!len)
{
s->cur = s->tok = s->lim = s->mrk = s->buffer;
s->eof = 0;
}
if (!s->eof)
{
int got, cnt = s->tok - s->buffer;
if (cnt > 0)
{
memcpy(s->buffer, s->tok, s->lim - s->tok);
s->tok -= cnt;
s->cur -= cnt;
s->lim -= cnt;
s->mrk -= cnt;
}
cnt = BSIZE - cnt;
if ((got = fread(s->lim, 1, cnt, s->fp)) != cnt)
{
s->eof = &s->lim[got];
}
s->lim += got;
}
else if (s->cur + len > s->eof)
{
return 0; /* not enough input data */
}
return -1;
}
void echo(Scanner *s)
{
fwrite(s->tok, 1, s->cur - s->tok, stdout);
}
int scan(FILE *fp)
{
int res = 0;
Scanner s;
if (!fp)
{
return 1; /* no file was opened */
}
s.fp = fp;
fill(&s, 0);
for(;;)
{
s.tok = s.cur;
/*!re2c
re2c:indent:top = 2;
NL = "\r"? "\n" ;
WS = [\r\n\t ] ;
ANY = [^] ;
"/" "/" { goto cppcomment; }
"/" "*" { goto comment; }
ANY { fputc(*s.tok, stdout); continue; }
*/
comment:
s.tok = s.cur;
/*!re2c
"*" "/" { goto commentws; }
ANY { goto comment; }
*/
commentws:
s.tok = s.cur;
/*!re2c
NL { echo(&s); continue; }
WS { goto commentws; }
ANY { echo(&s); continue; }
*/
cppcomment:
s.tok = s.cur;
/*!re2c
NL { echo(&s); continue; }
ANY { goto cppcomment; }
*/
}
if (fp != stdin)
{
fclose(fp); /* close only if not stdin */
}
return res; /* return result */
}
int main(int argc, char **argv)
{
if (argc > 1)
{
return scan(!strcmp(argv[1], "-") ? stdin : fopen(argv[1], "r"));
}
else
{
fprintf(stderr, "%s <expr>\n", argv[0]);
return 1;
}
}

Some files were not shown because too many files have changed in this diff Show More