ENH: Add rudamentary mathematical expression support
This commit is contained in:
parent
427ed70363
commit
985d092d4d
|
@ -21,6 +21,7 @@ OPTION(CMAKE_REGENERATE_YACCLEX
|
|||
"Regenerate YACC and LEXX files" OFF)
|
||||
MARK_AS_ADVANCED(CMAKE_REGENERATE_YACCLEX)
|
||||
IF(CMAKE_REGENERATE_YACCLEX)
|
||||
SET(parsersLexers cmCommandArgument cmExpr)
|
||||
FIND_PROGRAM(YACC_EXECUTABLE
|
||||
NAMES yacc bison
|
||||
PATHS /usr/bin
|
||||
|
@ -36,7 +37,7 @@ IF(CMAKE_REGENERATE_YACCLEX)
|
|||
SET(BISON_FLAGS "--yacc")
|
||||
ENDIF(YACC_EXECUTABLE MATCHES "bison")
|
||||
SET(yacc_files)
|
||||
FOREACH(name cmCommandArgument)
|
||||
FOREACH(name ${parsersLexers})
|
||||
SET(src "${CMAKE_CURRENT_SOURCE_DIR}/${name}Parser.y")
|
||||
SET(dst "${CMAKE_CURRENT_BINARY_DIR}/${name}Parser.cxx")
|
||||
SET(hdr "${CMAKE_CURRENT_BINARY_DIR}/${name}ParserTokens.h")
|
||||
|
@ -51,7 +52,7 @@ IF(CMAKE_REGENERATE_YACCLEX)
|
|||
ENDIF(YACC_EXECUTABLE)
|
||||
IF(FLEX_EXECUTABLE)
|
||||
SET(lex_files)
|
||||
FOREACH(name cmCommandArgument)
|
||||
FOREACH(name ${parsersLexers})
|
||||
SET(src "${CMAKE_CURRENT_SOURCE_DIR}/${name}Lexer.in.l")
|
||||
SET(dst "${CMAKE_CURRENT_BINARY_DIR}/${name}Lexer.cxx")
|
||||
SET(hdr "${CMAKE_CURRENT_BINARY_DIR}/${name}Lexer.h")
|
||||
|
@ -98,6 +99,9 @@ SET(SRCS
|
|||
cmDocumentation.cxx
|
||||
cmDynamicLoader.cxx
|
||||
cmDynamicLoader.h
|
||||
cmExprLexer.cxx
|
||||
cmExprParser.cxx
|
||||
cmExprParserHelper.cxx
|
||||
cmGeneratedFileStream.cxx
|
||||
cmGlob.cxx
|
||||
cmGlobalGenerator.cxx
|
||||
|
@ -346,6 +350,16 @@ IF(BUILD_TESTING)
|
|||
--build-makeprogram ${MAKEPROGRAM}
|
||||
--test-command StringFileTest)
|
||||
|
||||
ADD_TEST(MathTest ${CMAKE_CTEST_COMMAND}
|
||||
--build-and-test
|
||||
"${CMake_SOURCE_DIR}/Tests/MathTest"
|
||||
"${CMake_BINARY_DIR}/Tests/MathTest"
|
||||
--build-two-config
|
||||
--build-generator ${CMAKE_GENERATOR}
|
||||
--build-project MathTest
|
||||
--build-makeprogram ${MAKEPROGRAM}
|
||||
--test-command MathTestExec)
|
||||
|
||||
ADD_TEST(TryCompile ${CMAKE_CTEST_COMMAND}
|
||||
--build-and-test
|
||||
"${CMake_SOURCE_DIR}/Tests/TryCompile"
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "cmIncludeExternalMSProjectCommand.cxx"
|
||||
#include "cmLinkLibrariesCommand.cxx"
|
||||
#include "cmLoadCacheCommand.cxx"
|
||||
#include "cmMathCommand.cxx"
|
||||
#include "cmOutputRequiredFilesCommand.cxx"
|
||||
#include "cmRemoveCommand.cxx"
|
||||
#include "cmSetDirectoryPropertiesCommand.cxx"
|
||||
|
@ -68,6 +69,7 @@ void GetPredefinedCommands(std::list<cmCommand*>&
|
|||
commands.push_back(new cmLinkLibrariesCommand);
|
||||
commands.push_back(new cmLoadCacheCommand);
|
||||
commands.push_back(new cmLoadCommandCommand);
|
||||
commands.push_back(new cmMathCommand);
|
||||
commands.push_back(new cmOutputRequiredFilesCommand);
|
||||
commands.push_back(new cmRemoveCommand);
|
||||
commands.push_back(new cmSetDirectoryPropertiesCommand);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,316 @@
|
|||
#ifndef cmExpr_yyHEADER_H
|
||||
#define cmExpr_yyHEADER_H 1
|
||||
#define cmExpr_yyIN_HEADER 1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define YY_INT_ALIGNED short int
|
||||
|
||||
/* A lexical scanner generated by flex */
|
||||
|
||||
#define FLEX_SCANNER
|
||||
#define YY_FLEX_MAJOR_VERSION 2
|
||||
#define YY_FLEX_MINOR_VERSION 5
|
||||
#define YY_FLEX_SUBMINOR_VERSION 31
|
||||
#if YY_FLEX_SUBMINOR_VERSION > 0
|
||||
#define FLEX_BETA
|
||||
#endif
|
||||
|
||||
/* First, we deal with platform-specific or compiler-specific issues. */
|
||||
|
||||
/* begin standard C headers. */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* end standard C headers. */
|
||||
|
||||
/* flex integer type definitions */
|
||||
|
||||
#ifndef FLEXINT_H
|
||||
#define FLEXINT_H
|
||||
|
||||
/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
|
||||
|
||||
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
|
||||
#include <inttypes.h>
|
||||
typedef int8_t flex_int8_t;
|
||||
typedef uint8_t flex_uint8_t;
|
||||
typedef int16_t flex_int16_t;
|
||||
typedef uint16_t flex_uint16_t;
|
||||
typedef int32_t flex_int32_t;
|
||||
typedef uint32_t flex_uint32_t;
|
||||
#else
|
||||
typedef signed char flex_int8_t;
|
||||
typedef short int flex_int16_t;
|
||||
typedef int flex_int32_t;
|
||||
typedef unsigned char flex_uint8_t;
|
||||
typedef unsigned short int flex_uint16_t;
|
||||
typedef unsigned int flex_uint32_t;
|
||||
#endif /* ! C99 */
|
||||
|
||||
/* Limits of integral types. */
|
||||
#ifndef INT8_MIN
|
||||
#define INT8_MIN (-128)
|
||||
#endif
|
||||
#ifndef INT16_MIN
|
||||
#define INT16_MIN (-32767-1)
|
||||
#endif
|
||||
#ifndef INT32_MIN
|
||||
#define INT32_MIN (-2147483647-1)
|
||||
#endif
|
||||
#ifndef INT8_MAX
|
||||
#define INT8_MAX (127)
|
||||
#endif
|
||||
#ifndef INT16_MAX
|
||||
#define INT16_MAX (32767)
|
||||
#endif
|
||||
#ifndef INT32_MAX
|
||||
#define INT32_MAX (2147483647)
|
||||
#endif
|
||||
#ifndef UINT8_MAX
|
||||
#define UINT8_MAX (255U)
|
||||
#endif
|
||||
#ifndef UINT16_MAX
|
||||
#define UINT16_MAX (65535U)
|
||||
#endif
|
||||
#ifndef UINT32_MAX
|
||||
#define UINT32_MAX (4294967295U)
|
||||
#endif
|
||||
|
||||
#endif /* ! FLEXINT_H */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/* The "const" storage-class-modifier is valid. */
|
||||
#define YY_USE_CONST
|
||||
|
||||
#else /* ! __cplusplus */
|
||||
|
||||
#if __STDC__
|
||||
|
||||
#define YY_USE_CONST
|
||||
|
||||
#endif /* __STDC__ */
|
||||
#endif /* ! __cplusplus */
|
||||
|
||||
#ifdef YY_USE_CONST
|
||||
#define yyconst const
|
||||
#else
|
||||
#define yyconst
|
||||
#endif
|
||||
|
||||
/* An opaque pointer. */
|
||||
#ifndef YY_TYPEDEF_YY_SCANNER_T
|
||||
#define YY_TYPEDEF_YY_SCANNER_T
|
||||
typedef void* yyscan_t;
|
||||
#endif
|
||||
|
||||
/* For convenience, these vars (plus the bison vars far below)
|
||||
are macros in the reentrant scanner. */
|
||||
#define yyin yyg->yyin_r
|
||||
#define yyout yyg->yyout_r
|
||||
#define yyextra yyg->yyextra_r
|
||||
#define yyleng yyg->yyleng_r
|
||||
#define yytext yyg->yytext_r
|
||||
#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
|
||||
#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
|
||||
#define yy_flex_debug yyg->yy_flex_debug_r
|
||||
|
||||
int cmExpr_yylex_init (yyscan_t* scanner);
|
||||
|
||||
#ifndef YY_TYPEDEF_YY_BUFFER_STATE
|
||||
#define YY_TYPEDEF_YY_BUFFER_STATE
|
||||
typedef struct yy_buffer_state *YY_BUFFER_STATE;
|
||||
#endif
|
||||
|
||||
/* The following is because we cannot portably get our hands on size_t
|
||||
* (without autoconf's help, which isn't available because we want
|
||||
* flex-generated scanners to compile on their own).
|
||||
*/
|
||||
|
||||
#ifndef YY_TYPEDEF_YY_SIZE_T
|
||||
#define YY_TYPEDEF_YY_SIZE_T
|
||||
typedef unsigned int yy_size_t;
|
||||
#endif
|
||||
|
||||
#ifndef YY_STRUCT_YY_BUFFER_STATE
|
||||
#define YY_STRUCT_YY_BUFFER_STATE
|
||||
struct yy_buffer_state
|
||||
{
|
||||
FILE *yy_input_file;
|
||||
|
||||
char *yy_ch_buf; /* input buffer */
|
||||
char *yy_buf_pos; /* current position in input buffer */
|
||||
|
||||
/* Size of input buffer in bytes, not including room for EOB
|
||||
* characters.
|
||||
*/
|
||||
yy_size_t yy_buf_size;
|
||||
|
||||
/* Number of characters read into yy_ch_buf, not including EOB
|
||||
* characters.
|
||||
*/
|
||||
int yy_n_chars;
|
||||
|
||||
/* Whether we "own" the buffer - i.e., we know we created it,
|
||||
* and can realloc() it to grow it, and should free() it to
|
||||
* delete it.
|
||||
*/
|
||||
int yy_is_our_buffer;
|
||||
|
||||
/* Whether this is an "interactive" input source; if so, and
|
||||
* if we're using stdio for input, then we want to use getc()
|
||||
* instead of fread(), to make sure we stop fetching input after
|
||||
* each newline.
|
||||
*/
|
||||
int yy_is_interactive;
|
||||
|
||||
/* Whether we're considered to be at the beginning of a line.
|
||||
* If so, '^' rules will be active on the next match, otherwise
|
||||
* not.
|
||||
*/
|
||||
int yy_at_bol;
|
||||
|
||||
int yy_bs_lineno; /**< The line count. */
|
||||
int yy_bs_column; /**< The column count. */
|
||||
|
||||
/* Whether to try to fill the input buffer when we reach the
|
||||
* end of it.
|
||||
*/
|
||||
int yy_fill_buffer;
|
||||
|
||||
int yy_buffer_status;
|
||||
|
||||
};
|
||||
#endif /* !YY_STRUCT_YY_BUFFER_STATE */
|
||||
|
||||
void cmExpr_yyrestart (FILE *input_file ,yyscan_t yyscanner );
|
||||
void cmExpr_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
|
||||
YY_BUFFER_STATE cmExpr_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
|
||||
void cmExpr_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
|
||||
void cmExpr_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
|
||||
void cmExpr_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
|
||||
void cmExpr_yypop_buffer_state (yyscan_t yyscanner );
|
||||
|
||||
YY_BUFFER_STATE cmExpr_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
|
||||
YY_BUFFER_STATE cmExpr_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
|
||||
YY_BUFFER_STATE cmExpr_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
|
||||
|
||||
void *cmExpr_yyalloc (yy_size_t ,yyscan_t yyscanner );
|
||||
void *cmExpr_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
|
||||
void cmExpr_yyfree (void * ,yyscan_t yyscanner );
|
||||
|
||||
/* Begin user sect3 */
|
||||
|
||||
#define cmExpr_yywrap(n) 1
|
||||
#define YY_SKIP_YYWRAP
|
||||
|
||||
#define yytext_ptr yytext_r
|
||||
|
||||
#ifdef YY_HEADER_EXPORT_START_CONDITIONS
|
||||
#define INITIAL 0
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef YY_EXTRA_TYPE
|
||||
#define YY_EXTRA_TYPE void *
|
||||
#endif
|
||||
|
||||
/* Accessor methods to globals.
|
||||
These are made visible to non-reentrant scanners for convenience. */
|
||||
|
||||
int cmExpr_yylex_destroy (yyscan_t yyscanner );
|
||||
|
||||
int cmExpr_yyget_debug (yyscan_t yyscanner );
|
||||
|
||||
void cmExpr_yyset_debug (int debug_flag ,yyscan_t yyscanner );
|
||||
|
||||
YY_EXTRA_TYPE cmExpr_yyget_extra (yyscan_t yyscanner );
|
||||
|
||||
void cmExpr_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
|
||||
|
||||
FILE *cmExpr_yyget_in (yyscan_t yyscanner );
|
||||
|
||||
void cmExpr_yyset_in (FILE * in_str ,yyscan_t yyscanner );
|
||||
|
||||
FILE *cmExpr_yyget_out (yyscan_t yyscanner );
|
||||
|
||||
void cmExpr_yyset_out (FILE * out_str ,yyscan_t yyscanner );
|
||||
|
||||
int cmExpr_yyget_leng (yyscan_t yyscanner );
|
||||
|
||||
char *cmExpr_yyget_text (yyscan_t yyscanner );
|
||||
|
||||
int cmExpr_yyget_lineno (yyscan_t yyscanner );
|
||||
|
||||
void cmExpr_yyset_lineno (int line_number ,yyscan_t yyscanner );
|
||||
|
||||
/* Macros after this point can all be overridden by user definitions in
|
||||
* section 1.
|
||||
*/
|
||||
|
||||
#ifndef YY_SKIP_YYWRAP
|
||||
#ifdef __cplusplus
|
||||
extern "C" int cmExpr_yywrap (yyscan_t yyscanner );
|
||||
#else
|
||||
extern int cmExpr_yywrap (yyscan_t yyscanner );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef yytext_ptr
|
||||
static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
|
||||
#endif
|
||||
|
||||
#ifdef YY_NEED_STRLEN
|
||||
static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
|
||||
#endif
|
||||
|
||||
#ifndef YY_NO_INPUT
|
||||
|
||||
#endif
|
||||
|
||||
/* Amount of stuff to slurp up with each read. */
|
||||
#ifndef YY_READ_BUF_SIZE
|
||||
#define YY_READ_BUF_SIZE 8192
|
||||
#endif
|
||||
|
||||
/* Number of entries by which start-condition stack grows. */
|
||||
#ifndef YY_START_STACK_INCR
|
||||
#define YY_START_STACK_INCR 25
|
||||
#endif
|
||||
|
||||
/* Default declaration of generated scanner - a define so the user can
|
||||
* easily add parameters.
|
||||
*/
|
||||
#ifndef YY_DECL
|
||||
#define YY_DECL_IS_OURS 1
|
||||
|
||||
extern int cmExpr_yylex (yyscan_t yyscanner);
|
||||
|
||||
#define YY_DECL int cmExpr_yylex (yyscan_t yyscanner)
|
||||
#endif /* !YY_DECL */
|
||||
|
||||
/* yy_get_previous_state - get the state just before the EOB char was reached */
|
||||
|
||||
#undef YY_NEW_FILE
|
||||
#undef YY_FLUSH_BUFFER
|
||||
#undef yy_set_bol
|
||||
#undef yy_new_buffer
|
||||
#undef yy_set_interactive
|
||||
#undef yytext_ptr
|
||||
#undef YY_DO_BEFORE_ACTION
|
||||
|
||||
#ifdef YY_DECL_IS_OURS
|
||||
#undef YY_DECL_IS_OURS
|
||||
#undef YY_DECL
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#undef cmExpr_yyIN_HEADER
|
||||
#endif /* cmExpr_yyHEADER_H */
|
|
@ -0,0 +1,104 @@
|
|||
%{
|
||||
/*=========================================================================
|
||||
|
||||
Program: CMake - Cross-Platform Makefile Generator
|
||||
Module: $RCSfile$
|
||||
Language: C++
|
||||
Date: $Date$
|
||||
Version: $Revision$
|
||||
|
||||
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
|
||||
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the above copyright notices for more information.
|
||||
|
||||
=========================================================================*/
|
||||
/*
|
||||
|
||||
This file must be translated to C and modified to build everywhere.
|
||||
|
||||
Run flex like this:
|
||||
|
||||
flex --prefix=cmExpr_yy --header-file=cmExprLexer.h -ocmExprLexer.cxx cmExprLexer.in.l
|
||||
|
||||
Modify cmExprLexer.cxx:
|
||||
- remove TABs
|
||||
- remove "yyscanner" argument from these methods:
|
||||
yy_fatal_error, yyalloc, yyrealloc, yyfree
|
||||
- remove all YY_BREAK lines occurring right after return statements
|
||||
- change while ( 1 ) to for(;;)
|
||||
|
||||
Modify cmExprLexer.h:
|
||||
- remove TABs
|
||||
- remove the yy_init_globals function
|
||||
- remove the block that includes unistd.h
|
||||
- remove #line directives (avoids bogus warning on old Sun)
|
||||
|
||||
*/
|
||||
|
||||
#include "cmExprParserHelper.h"
|
||||
|
||||
/* Disable some warnings. */
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning ( disable : 4127 )
|
||||
# pragma warning ( disable : 4131 )
|
||||
# pragma warning ( disable : 4244 )
|
||||
# pragma warning ( disable : 4251 )
|
||||
# pragma warning ( disable : 4267 )
|
||||
# pragma warning ( disable : 4305 )
|
||||
# pragma warning ( disable : 4309 )
|
||||
# pragma warning ( disable : 4706 )
|
||||
# pragma warning ( disable : 4786 )
|
||||
#endif
|
||||
|
||||
/* Disable features we do not need. */
|
||||
#define YY_NEVER_INTERACTIVE 1
|
||||
#undef ECHO /* SGI termios defines this differently. */
|
||||
#define ECHO
|
||||
|
||||
/* Replace the lexer input function. */
|
||||
#undef YY_INPUT
|
||||
#define YY_INPUT(buf, result, max_size) \
|
||||
{ result = yyextra->LexInput(buf, max_size); }
|
||||
|
||||
/* Include the set of tokens from the parser. */
|
||||
#include "cmExprParserTokens.h"
|
||||
|
||||
|
||||
#if defined( _WIN32 ) && !defined( __CYGWIN__ )
|
||||
/* Handle Windows properly */
|
||||
# include <io.h>
|
||||
# if defined( _MSC_VER )
|
||||
# define isatty _isatty
|
||||
# endif
|
||||
# define YY_NO_UNISTD_H 1
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
%}
|
||||
|
||||
%option reentrant
|
||||
%option noyywrap
|
||||
%pointer
|
||||
|
||||
%%
|
||||
|
||||
[0-9][0-9]* { yylvalp->Number = atoi(yytext); return exp_NUMBER; }
|
||||
|
||||
"+" { return exp_PLUS; }
|
||||
"-" { return exp_MINUS; }
|
||||
"*" { return exp_TIMES; }
|
||||
"/" { return exp_DIVIDE; }
|
||||
"%" { return exp_MOD; }
|
||||
"\|" { return exp_OR; }
|
||||
"&" { return exp_AND; }
|
||||
"^" { return exp_XOR; }
|
||||
"~" { return exp_NOT; }
|
||||
"<<" { return exp_SHIFTLEFT; }
|
||||
">>" { return exp_SHIFTRIGHT; }
|
||||
"(" { return exp_OPENPARENT; }
|
||||
")" { return exp_CLOSEPARENT; }
|
||||
|
||||
%%
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,171 @@
|
|||
%{
|
||||
/*=========================================================================
|
||||
|
||||
Program: CMake - Cross-Platform Makefile Generator
|
||||
Module: $RCSfile$
|
||||
Language: C++
|
||||
Date: $Date$
|
||||
Version: $Revision$
|
||||
|
||||
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
|
||||
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the above copyright notices for more information.
|
||||
|
||||
=========================================================================*/
|
||||
/*
|
||||
|
||||
This file must be translated to C and modified to build everywhere.
|
||||
|
||||
Run bison like this:
|
||||
|
||||
bison --yacc --name-prefix=cmExpr_yy --defines=cmExprParserTokens.h -ocmExprParser.cxx cmExprParser.y
|
||||
|
||||
Modify cmExprParser.cxx:
|
||||
- remove TABs
|
||||
- add __HP_aCC to the #if test for yyerrorlab warning suppression
|
||||
|
||||
*/
|
||||
|
||||
/* Configure the parser to use a lexer object. */
|
||||
#define YYPARSE_PARAM yyscanner
|
||||
#define YYLEX_PARAM yyscanner
|
||||
#define YYERROR_VERBOSE 1
|
||||
#define cmExpr_yyerror(x) \
|
||||
cmExprError(yyscanner, x)
|
||||
#define yyGetParser (cmExpr_yyget_extra(yyscanner))
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
#include "cmExprParserHelper.h" /* Interface to parser object. */
|
||||
#include "cmExprLexer.h" /* Interface to lexer object. */
|
||||
#include "cmExprParserTokens.h" /* Need YYSTYPE for YY_DECL. */
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/* Forward declare the lexer entry point. */
|
||||
YY_DECL;
|
||||
|
||||
/* Internal utility functions. */
|
||||
static void cmExprError(yyscan_t yyscanner, const char* message);
|
||||
|
||||
#define YYDEBUG 1
|
||||
//#define YYMAXDEPTH 100000
|
||||
//#define YYINITDEPTH 10000
|
||||
|
||||
|
||||
/* Disable some warnings in the generated code. */
|
||||
#ifdef __BORLANDC__
|
||||
# pragma warn -8004 /* Variable assigned a value that is not used. */
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning (disable: 4102) /* Unused goto label. */
|
||||
# pragma warning (disable: 4065) /* Switch statement contains default but no case. */
|
||||
#endif
|
||||
%}
|
||||
|
||||
/* Generate a reentrant parser object. */
|
||||
%pure_parser
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/* Tokens */
|
||||
%token exp_PLUS
|
||||
%token exp_MINUS
|
||||
%token exp_TIMES
|
||||
%token exp_DIVIDE
|
||||
%token exp_MOD
|
||||
%token exp_SHIFTLEFT
|
||||
%token exp_SHIFTRIGHT
|
||||
%token exp_OPENPARENT
|
||||
%token exp_CLOSEPARENT
|
||||
%token exp_OR;
|
||||
%token exp_AND;
|
||||
%token exp_XOR;
|
||||
%token exp_NOT;
|
||||
%token exp_NUMBER;
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/* grammar */
|
||||
%%
|
||||
|
||||
|
||||
Start:
|
||||
exp
|
||||
{
|
||||
yyGetParser->SetResult($<Number>1);
|
||||
}
|
||||
|
||||
exp:
|
||||
bitwiseor
|
||||
{$<Number>$ = $<Number>1;}
|
||||
|
|
||||
exp exp_OR bitwiseor
|
||||
{$<Number>$ = $<Number>1 | $<Number>3;}
|
||||
|
||||
bitwiseor:
|
||||
bitwisexor
|
||||
{$<Number>$ = $<Number>1;}
|
||||
|
|
||||
bitwiseor exp_XOR bitwisexor
|
||||
{$<Number>$ = $<Number>1 ^ $<Number>3;}
|
||||
|
||||
bitwisexor:
|
||||
bitwiseand
|
||||
{$<Number>$ = $<Number>1;}
|
||||
|
|
||||
bitwisexor exp_AND bitwiseand
|
||||
{$<Number>$ = $<Number>1 & $<Number>3;}
|
||||
|
||||
bitwiseand:
|
||||
term
|
||||
{$<Number>$ = $<Number>1;}
|
||||
|
|
||||
bitwiseand exp_PLUS term
|
||||
{$<Number>$ = $<Number>1 + $<Number>3;}
|
||||
|
|
||||
bitwiseand exp_MINUS term
|
||||
{$<Number>$ = $<Number>1 - $<Number>3;}
|
||||
|
||||
term:
|
||||
factor
|
||||
{$<Number>$ = $<Number>1;}
|
||||
|
|
||||
term exp_TIMES factor
|
||||
{$<Number>$ = $<Number>1 * $<Number>3;}
|
||||
|
|
||||
term exp_DIVIDE factor
|
||||
{$<Number>$ = $<Number>1 / $<Number>3;}
|
||||
|
|
||||
term exp_MOD factor
|
||||
{$<Number>$ = $<Number>1 % $<Number>3;}
|
||||
|
||||
factor:
|
||||
shift
|
||||
{$<Number>$ = $<Number>1;}
|
||||
|
|
||||
factor exp_SHIFTLEFT shift
|
||||
{$<Number>$ = $<Number>1 << $<Number>3;}
|
||||
|
|
||||
factor exp_SHIFTRIGHT shift
|
||||
{$<Number>$ = $<Number>1 >> $<Number>3;}
|
||||
|
||||
|
||||
shift:
|
||||
exp_NUMBER
|
||||
{$<Number>$ = $<Number>1;}
|
||||
|
|
||||
exp_OPENPARENT exp exp_CLOSEPARENT
|
||||
{$<Number>$ = $<Number>2;}
|
||||
;
|
||||
|
||||
|
||||
%%
|
||||
/* End of grammar */
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void cmExprError(yyscan_t yyscanner, const char* message)
|
||||
{
|
||||
yyGetParser->Error(message);
|
||||
}
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
/*=========================================================================
|
||||
|
||||
Program: CMake - Cross-Platform Makefile Generator
|
||||
Module: $RCSfile$
|
||||
Language: C++
|
||||
Date: $Date$
|
||||
Version: $Revision$
|
||||
|
||||
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
|
||||
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the above copyright notices for more information.
|
||||
|
||||
=========================================================================*/
|
||||
#include "cmExprParserHelper.h"
|
||||
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmExprLexer.h"
|
||||
|
||||
#include "cmMakefile.h"
|
||||
|
||||
int cmExpr_yyparse( yyscan_t yyscanner );
|
||||
//
|
||||
cmExprParserHelper::cmExprParserHelper()
|
||||
{
|
||||
m_FileLine = -1;
|
||||
m_FileName = 0;
|
||||
}
|
||||
|
||||
|
||||
cmExprParserHelper::~cmExprParserHelper()
|
||||
{
|
||||
this->CleanupParser();
|
||||
}
|
||||
|
||||
void cmExprParserHelper::SetLineFile(long line, const char* file)
|
||||
{
|
||||
m_FileLine = line;
|
||||
m_FileName = file;
|
||||
}
|
||||
|
||||
int cmExprParserHelper::ParseString(const char* str, int verb)
|
||||
{
|
||||
if ( !str)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
//printf("Do some parsing: %s\n", str);
|
||||
|
||||
this->Verbose = verb;
|
||||
this->InputBuffer = str;
|
||||
this->InputBufferPos = 0;
|
||||
this->CurrentLine = 0;
|
||||
|
||||
m_Result = 0;
|
||||
|
||||
yyscan_t yyscanner;
|
||||
cmExpr_yylex_init(&yyscanner);
|
||||
cmExpr_yyset_extra(this, yyscanner);
|
||||
int res = cmExpr_yyparse(yyscanner);
|
||||
cmExpr_yylex_destroy(yyscanner);
|
||||
if ( res != 0 )
|
||||
{
|
||||
//str << "CAL_Parser returned: " << res << std::endl;
|
||||
//std::cerr << "When parsing: [" << str << "]" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
this->CleanupParser();
|
||||
|
||||
if ( Verbose )
|
||||
{
|
||||
std::cerr << "Expanding [" << str << "] produced: [" << m_Result << "]" << std::endl;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void cmExprParserHelper::CleanupParser()
|
||||
{
|
||||
}
|
||||
|
||||
int cmExprParserHelper::LexInput(char* buf, int maxlen)
|
||||
{
|
||||
//std::cout << "JPLexInput ";
|
||||
//std::cout.write(buf, maxlen);
|
||||
//std::cout << std::endl;
|
||||
if ( maxlen < 1 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( this->InputBufferPos < this->InputBuffer.size() )
|
||||
{
|
||||
buf[0] = this->InputBuffer[ this->InputBufferPos++ ];
|
||||
if ( buf[0] == '\n' )
|
||||
{
|
||||
this->CurrentLine ++;
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
buf[0] = '\n';
|
||||
return( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
void cmExprParserHelper::Error(const char* str)
|
||||
{
|
||||
unsigned long pos = static_cast<unsigned long>(this->InputBufferPos);
|
||||
//fprintf(stderr, "Argument Parser Error: %s (%lu / Line: %d)\n", str, pos, this->CurrentLine);
|
||||
cmOStringStream ostr;
|
||||
ostr << str << " (" << pos << ")";
|
||||
/*
|
||||
int cc;
|
||||
std::cerr << "String: [";
|
||||
for ( cc = 0; cc < 30 && *(this->InputBuffer.c_str() + this->InputBufferPos + cc);
|
||||
cc ++ )
|
||||
{
|
||||
std::cerr << *(this->InputBuffer.c_str() + this->InputBufferPos + cc);
|
||||
}
|
||||
std::cerr << "]" << std::endl;
|
||||
*/
|
||||
m_Error = ostr.str();
|
||||
}
|
||||
|
||||
void cmExprParserHelper::SetResult(int value)
|
||||
{
|
||||
m_Result = value;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/*=========================================================================
|
||||
|
||||
Program: CMake - Cross-Platform Makefile Generator
|
||||
Module: $RCSfile$
|
||||
Language: C++
|
||||
Date: $Date$
|
||||
Version: $Revision$
|
||||
|
||||
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
|
||||
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the above copyright notices for more information.
|
||||
|
||||
=========================================================================*/
|
||||
#ifndef cmExprParserHelper_h
|
||||
#define cmExprParserHelper_h
|
||||
|
||||
#include "cmStandardIncludes.h"
|
||||
|
||||
#define YYSTYPE cmExprParserHelper::ParserType
|
||||
#define YYSTYPE_IS_DECLARED
|
||||
#define YY_EXTRA_TYPE cmExprParserHelper*
|
||||
#define YY_DECL int cmExpr_yylex(YYSTYPE* yylvalp, yyscan_t yyscanner)
|
||||
|
||||
/** \class cmExprParserHelper
|
||||
* \brief Helper class for parsing java source files
|
||||
*
|
||||
* Finds dependencies for java file and list of outputs
|
||||
*/
|
||||
|
||||
class cmMakefile;
|
||||
|
||||
class cmExprParserHelper
|
||||
{
|
||||
public:
|
||||
typedef struct {
|
||||
int Number;
|
||||
} ParserType;
|
||||
|
||||
cmExprParserHelper();
|
||||
~cmExprParserHelper();
|
||||
|
||||
int ParseString(const char* str, int verb);
|
||||
|
||||
int LexInput(char* buf, int maxlen);
|
||||
void Error(const char* str);
|
||||
|
||||
void SetResult(int value);
|
||||
|
||||
int GetResult() { return m_Result; }
|
||||
|
||||
void SetLineFile(long line, const char* file);
|
||||
|
||||
const char* GetError() { return m_Error.c_str(); }
|
||||
|
||||
private:
|
||||
cmStdString::size_type InputBufferPos;
|
||||
cmStdString InputBuffer;
|
||||
std::vector<char> OutputBuffer;
|
||||
int CurrentLine;
|
||||
int UnionsAvailable;
|
||||
int Verbose;
|
||||
|
||||
void Print(const char* place, const char* str);
|
||||
|
||||
void CleanupParser();
|
||||
|
||||
int m_Result;
|
||||
const char* m_FileName;
|
||||
long m_FileLine;
|
||||
std::string m_Error;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/* A Bison parser, made by GNU Bison 1.875d. */
|
||||
|
||||
/* Skeleton parser for Yacc-like parsing with Bison,
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* As a special exception, when this file is copied by Bison into a
|
||||
Bison output file, you may use that output file without restriction.
|
||||
This special exception was added by the Free Software Foundation
|
||||
in version 1.24 of Bison. */
|
||||
|
||||
/* Tokens. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
/* Put the tokens into the symbol table, so that GDB and other debuggers
|
||||
know about them. */
|
||||
enum yytokentype {
|
||||
exp_PLUS = 258,
|
||||
exp_MINUS = 259,
|
||||
exp_TIMES = 260,
|
||||
exp_DIVIDE = 261,
|
||||
exp_MOD = 262,
|
||||
exp_SHIFTLEFT = 263,
|
||||
exp_SHIFTRIGHT = 264,
|
||||
exp_OPENPARENT = 265,
|
||||
exp_CLOSEPARENT = 266,
|
||||
exp_OR = 267,
|
||||
exp_AND = 268,
|
||||
exp_XOR = 269,
|
||||
exp_NOT = 270,
|
||||
exp_NUMBER = 271
|
||||
};
|
||||
#endif
|
||||
#define exp_PLUS 258
|
||||
#define exp_MINUS 259
|
||||
#define exp_TIMES 260
|
||||
#define exp_DIVIDE 261
|
||||
#define exp_MOD 262
|
||||
#define exp_SHIFTLEFT 263
|
||||
#define exp_SHIFTRIGHT 264
|
||||
#define exp_OPENPARENT 265
|
||||
#define exp_CLOSEPARENT 266
|
||||
#define exp_OR 267
|
||||
#define exp_AND 268
|
||||
#define exp_XOR 269
|
||||
#define exp_NOT 270
|
||||
#define exp_NUMBER 271
|
||||
|
||||
|
||||
|
||||
|
||||
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
|
||||
typedef int YYSTYPE;
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*=========================================================================
|
||||
|
||||
Program: CMake - Cross-Platform Makefile Generator
|
||||
Module: $RCSfile$
|
||||
Language: C++
|
||||
Date: $Date$
|
||||
Version: $Revision$
|
||||
|
||||
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
|
||||
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the above copyright notices for more information.
|
||||
|
||||
=========================================================================*/
|
||||
#include "cmMathCommand.h"
|
||||
|
||||
#include "cmExprParserHelper.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmMathCommand::InitialPass(std::vector<std::string> const& args)
|
||||
{
|
||||
if ( args.size() < 1 )
|
||||
{
|
||||
this->SetError("must be called with at least one argument.");
|
||||
return false;
|
||||
}
|
||||
const std::string &subCommand = args[0];
|
||||
if(subCommand == "EXPR")
|
||||
{
|
||||
return this->HandleExprCommand(args);
|
||||
}
|
||||
std::string e = "does not recognize sub-command "+subCommand;
|
||||
this->SetError(e.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmMathCommand::HandleExprCommand(std::vector<std::string> const& args)
|
||||
{
|
||||
if ( args.size() != 3 )
|
||||
{
|
||||
this->SetError("EXPR called with incorrect arguments.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string& outputVariable = args[1];
|
||||
const std::string& expression = args[2];
|
||||
|
||||
cmExprParserHelper helper;
|
||||
if ( !helper.ParseString(expression.c_str(), 0) )
|
||||
{
|
||||
std::string e = "cannot parse the expression: \""+expression+"\": ";
|
||||
e += helper.GetError();
|
||||
this->SetError(e.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
char buffer[1024];
|
||||
sprintf(buffer, "%d", helper.GetResult());
|
||||
|
||||
m_Makefile->AddDefinition(outputVariable.c_str(), buffer);
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/*=========================================================================
|
||||
|
||||
Program: CMake - Cross-Platform Makefile Generator
|
||||
Module: $RCSfile$
|
||||
Language: C++
|
||||
Date: $Date$
|
||||
Version: $Revision$
|
||||
|
||||
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
|
||||
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the above copyright notices for more information.
|
||||
|
||||
=========================================================================*/
|
||||
#ifndef cmMathCommand_h
|
||||
#define cmMathCommand_h
|
||||
|
||||
#include "cmCommand.h"
|
||||
|
||||
/** \class cmMathCommand
|
||||
* \brief Common string operations
|
||||
*
|
||||
*/
|
||||
class cmMathCommand : public cmCommand
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This is a virtual constructor for the command.
|
||||
*/
|
||||
virtual cmCommand* Clone()
|
||||
{
|
||||
return new cmMathCommand;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called when the command is first encountered in
|
||||
* the CMakeLists.txt file.
|
||||
*/
|
||||
virtual bool InitialPass(std::vector<std::string> const& args);
|
||||
|
||||
/**
|
||||
* This determines if the command is invoked when in script mode.
|
||||
*/
|
||||
virtual bool IsScriptable() { return true; }
|
||||
|
||||
/**
|
||||
* The name of the command as specified in CMakeList.txt.
|
||||
*/
|
||||
virtual const char* GetName() { return "MATH";}
|
||||
|
||||
/**
|
||||
* Succinct documentation.
|
||||
*/
|
||||
virtual const char* GetTerseDocumentation()
|
||||
{
|
||||
return "Mathematical expressions.";
|
||||
}
|
||||
|
||||
/**
|
||||
* More documentation.
|
||||
*/
|
||||
virtual const char* GetFullDocumentation()
|
||||
{
|
||||
return
|
||||
" MATH(EXPR <output variable> <math expression>)\n"
|
||||
"EXPR evaluates mathematical expression and return result in the "
|
||||
"output variable. Example mathematical expression is '5 * ( 10 + 13 )'.";
|
||||
}
|
||||
|
||||
cmTypeMacro(cmMathCommand, cmCommand);
|
||||
protected:
|
||||
|
||||
bool HandleExprCommand(std::vector<std::string> const& args);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -29,7 +29,7 @@ bool cmStringCommand::InitialPass(std::vector<std::string> const& args)
|
|||
return false;
|
||||
}
|
||||
|
||||
std::string subCommand = args[0];
|
||||
const std::string &subCommand = args[0];
|
||||
if(subCommand == "REGEX")
|
||||
{
|
||||
return this->HandleRegexCommand(args);
|
||||
|
|
Loading…
Reference in New Issue