Minimum flex version 2.6 and a bit of cleanup

Fixes #43903
Fixes #43795
This commit is contained in:
Matthias Kuhn 2021-06-24 19:43:03 +02:00
parent 91ebc53fcd
commit a20c909c1b
10 changed files with 68 additions and 254 deletions

View File

@ -311,25 +311,8 @@ if(WITH_CORE)
set (USING_NINJA TRUE)
endif()
#############################################################
# check if lexer and parser are not missing
# http://www.mail-archive.com/cmake@cmake.org/msg02861.html
include(Flex)
FIND_FLEX()
if (NOT FLEX_EXECUTABLE)
message(FATAL_ERROR "Couldn't find Flex")
endif()
include(Bison)
FIND_BISON()
if (NOT BISON_EXECUTABLE)
message(FATAL_ERROR "Couldn't find Bison")
endif()
find_package(FLEX 2.6 REQUIRED)
find_package(BISON REQUIRED)
#############################################################
# search for dependencies

View File

@ -1,99 +0,0 @@
# Macros for Bison
# ~~~~~~~~~~~~~~~~
# Copyright (c) 2007, Martin Dobias <wonder.sk at gmail.com>
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
# use bison for .yy files
# search for bison
MACRO(FIND_BISON)
IF(NOT BISON_EXECUTABLE)
IF (MSVC)
FIND_PROGRAM(BISON_EXECUTABLE PATHS
NAMES bison.exe
PATHS $ENV{LIB_DIR}/bin c:/cygwin/bin $ENV{PROGRAMFILES}/GnuWin32/bin
)
ELSEIF(APPLE AND QGIS_MAC_DEPS_DIR)
FIND_PROGRAM(BISON_EXECUTABLE bison PATHS $ENV{LIB_DIR}/bin NO_DEFAULT_PATH)
ELSE (MSVC)
FIND_PROGRAM(BISON_EXECUTABLE bison)
ENDIF (MSVC)
IF (NOT BISON_EXECUTABLE)
MESSAGE(FATAL_ERROR "Bison not found - aborting")
ELSE (NOT BISON_EXECUTABLE)
EXEC_PROGRAM(${BISON_EXECUTABLE} ARGS --version OUTPUT_VARIABLE BISON_VERSION_STR)
# get first line in case it's multiline
STRING(REGEX REPLACE "([^\n]+).*" "\\1" FIRST_LINE "${BISON_VERSION_STR}")
# get version information
STRING(REGEX REPLACE ".* ([0-9]+)\\.([0-9]+)(\\..*)?" "\\1" BISON_VERSION_MAJOR "${FIRST_LINE}")
STRING(REGEX REPLACE ".* ([0-9]+)\\.([0-9]+)(\\..*)?" "\\2" BISON_VERSION_MINOR "${FIRST_LINE}")
IF (BISON_VERSION_MAJOR LESS 2 OR (BISON_VERSION_MAJOR EQUAL 2 AND BISON_VERSION_MINOR LESS 4))
MESSAGE (FATAL_ERROR "Bison version is too old (${BISON_VERSION_MAJOR}.${BISON_VERSION_MINOR}). Use 2.4 or higher.")
ENDIF (BISON_VERSION_MAJOR LESS 2 OR (BISON_VERSION_MAJOR EQUAL 2 AND BISON_VERSION_MINOR LESS 4))
ENDIF (NOT BISON_EXECUTABLE)
ENDIF(NOT BISON_EXECUTABLE)
ENDMACRO(FIND_BISON)
MACRO(ADD_BISON_FILES _sources )
FIND_BISON()
FOREACH (_current_FILE ${ARGN})
GET_FILENAME_COMPONENT(_in ${_current_FILE} ABSOLUTE)
GET_FILENAME_COMPONENT(_basename ${_current_FILE} NAME_WE)
SET(_out ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.cpp)
# bison options:
# -t add debugging facilities
# -d produce additional header file (used in parser.l)
# -v produce additional *.output file with parser states
ADD_CUSTOM_COMMAND(
OUTPUT ${_out}
COMMAND ${BISON_EXECUTABLE}
ARGS
-o${_out} -d -v -t
${_in}
DEPENDS ${_in}
)
SET(${_sources} ${${_sources}} ${_out} )
ENDFOREACH (_current_FILE)
ENDMACRO(ADD_BISON_FILES)
MACRO(ADD_BISON_FILES_PREFIX _sources prefix)
FIND_BISON()
FOREACH (_current_FILE ${ARGN})
GET_FILENAME_COMPONENT(_in ${_current_FILE} ABSOLUTE)
GET_FILENAME_COMPONENT(_basename ${_current_FILE} NAME_WE)
SET(_out ${CMAKE_CURRENT_BINARY_DIR}/${_basename}.cpp)
# bison options:
# -t add debugging facilities
# -d produce additional header file (used in parser.l)
# -v produce additional *.output file with parser states
ADD_CUSTOM_COMMAND(
OUTPUT ${_out}
COMMAND ${BISON_EXECUTABLE}
ARGS
-p ${prefix}
-o${_out} -d -v -t
${_in}
DEPENDS ${_in}
)
SET(${_sources} ${${_sources}} ${_out} )
ENDFOREACH (_current_FILE)
ENDMACRO(ADD_BISON_FILES_PREFIX)

View File

@ -1,92 +0,0 @@
# Macros for Bison
# ~~~~~~~~~~~~~~~~
# Copyright (c) 2007, Martin Dobias <wonder.sk at gmail.com>
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
# flex a .ll file
# search flex
MACRO(FIND_FLEX)
IF(NOT FLEX_EXECUTABLE)
IF (MSVC)
FIND_PROGRAM(FLEX_EXECUTABLE
NAMES flex.exe
PATHS $ENV{LIB_DIR}/bin c:/cygwin/bin $ENV{PROGRAMFILES}/GnuWin32/bin
)
ELSEIF(APPLE AND QGIS_MAC_DEPS_DIR)
FIND_PROGRAM(FLEX_EXECUTABLE flex PATHS $ENV{LIB_DIR}/bin NO_DEFAULT_PATH)
ELSE(MSVC)
FIND_PROGRAM(FLEX_EXECUTABLE flex)
ENDIF (MSVC)
IF (NOT FLEX_EXECUTABLE)
MESSAGE(FATAL_ERROR "flex not found - aborting")
ENDIF (NOT FLEX_EXECUTABLE)
ENDIF(NOT FLEX_EXECUTABLE)
ENDMACRO(FIND_FLEX)
MACRO(ADD_FLEX_FILES _sources )
FIND_FLEX()
FOREACH (_current_FILE ${ARGN})
GET_FILENAME_COMPONENT(_in ${_current_FILE} ABSOLUTE)
GET_FILENAME_COMPONENT(_basename ${_current_FILE} NAME_WE)
SET(_out ${CMAKE_CURRENT_BINARY_DIR}/flex_${_basename}.cpp)
# -d option for flex means that it will produce output to stderr while analyzing
ADD_CUSTOM_COMMAND(
OUTPUT ${_out}
COMMAND ${FLEX_EXECUTABLE}
ARGS
-o${_out}
${_in}
DEPENDS ${_in}
)
SET(${_sources} ${${_sources}} ${_out} )
# Disable warnings
IF(MSVC)
SET_SOURCE_FILES_PROPERTIES(${_out} PROPERTIES COMPILE_FLAGS /W0)
ELSE(MSVC)
SET_SOURCE_FILES_PROPERTIES(${_out} PROPERTIES COMPILE_FLAGS -w)
ENDIF(MSVC)
ENDFOREACH (_current_FILE)
ENDMACRO(ADD_FLEX_FILES)
MACRO(ADD_FLEX_FILES_PREFIX _sources prefix )
FIND_FLEX()
FOREACH (_current_FILE ${ARGN})
GET_FILENAME_COMPONENT(_in ${_current_FILE} ABSOLUTE)
GET_FILENAME_COMPONENT(_basename ${_current_FILE} NAME_WE)
SET(_out ${CMAKE_CURRENT_BINARY_DIR}/flex_${_basename}.cpp)
# -d option for flex means that it will produce output to stderr while analyzing
ADD_CUSTOM_COMMAND(
OUTPUT ${_out}
COMMAND ${FLEX_EXECUTABLE}
ARGS
-P${prefix}
-o${_out}
${_in}
DEPENDS ${_in}
)
SET(${_sources} ${${_sources}} ${_out} )
# Disable warnings
IF(MSVC)
SET_SOURCE_FILES_PROPERTIES(${_out} PROPERTIES COMPILE_FLAGS /W0)
ELSE(MSVC)
SET_SOURCE_FILES_PROPERTIES(${_out} PROPERTIES COMPILE_FLAGS -w)
ENDIF(MSVC)
ENDFOREACH (_current_FILE)
ENDMACRO(ADD_FLEX_FILES_PREFIX)

View File

@ -1,9 +1,17 @@
#############################################################
# sources
BISON_TARGET(QgsRasterCalcParser raster/qgsrastercalcparser.yy ${CMAKE_CURRENT_BINARY_DIR}/qgsrastercalcparser.cpp COMPILE_FLAGS "-p raster_")
FLEX_TARGET(QgsRasterCalcLexer raster/qgsrastercalclexer.ll ${CMAKE_CURRENT_BINARY_DIR}/qgsrastercalclexer.cpp)
ADD_FLEX_BISON_DEPENDENCY(QgsRasterCalcLexer QgsRasterCalcParser)
set(QGIS_ANALYSIS_SRCS
qgsanalysis.cpp
${FLEX_QgsRasterCalcLexer_OUTPUTS}
${BISON_QgsRasterCalcParser_OUTPUTS}
georeferencing/qgsgcpgeometrytransformer.cpp
georeferencing/qgsgcptransformer.cpp
georeferencing/qgsleastsquares.cpp
@ -408,9 +416,6 @@ if(HAVE_GSL)
include_directories(SYSTEM ${GSL_INCLUDE_DIR})
endif()
ADD_FLEX_FILES_PREFIX(QGIS_ANALYSIS_SRCS raster raster/qgsrastercalclexer.ll)
ADD_BISON_FILES_PREFIX(QGIS_ANALYSIS_SRCS raster raster/qgsrastercalcparser.yy)
if(NOT MSVC)
set_source_files_properties(
${CMAKE_BINARY_DIR}/src/analysis/qgsrastercalcparser.cpp

View File

@ -20,6 +20,7 @@
%option nounput
%option case-insensitive
%option never-interactive
%option prefix="raster_"
// ensure that lexer will be 8-bit (and not just 7-bit)
%option 8bit
@ -53,18 +54,18 @@ raster_band_ref_quoted \"(\\.|[^"])*\"
%%
"sqrt" { rasterlval.op = QgsRasterCalcNode::opSQRT; return FUNCTION;}
"sin" { rasterlval.op = QgsRasterCalcNode::opSIN; return FUNCTION;}
"cos" { rasterlval.op = QgsRasterCalcNode::opCOS; return FUNCTION;}
"tan" { rasterlval.op = QgsRasterCalcNode::opTAN; return FUNCTION;}
"asin" { rasterlval.op = QgsRasterCalcNode::opASIN; return FUNCTION;}
"acos" { rasterlval.op = QgsRasterCalcNode::opACOS; return FUNCTION;}
"atan" { rasterlval.op = QgsRasterCalcNode::opATAN; return FUNCTION;}
"ln" { rasterlval.op = QgsRasterCalcNode::opLOG; return FUNCTION;}
"log10" { rasterlval.op = QgsRasterCalcNode::opLOG10; return FUNCTION;}
"abs" { rasterlval.op = QgsRasterCalcNode::opABS; return FUNCTION;}
"min" { rasterlval.op = QgsRasterCalcNode::opMIN; return FUNCTION_2_ARGS;}
"max" { rasterlval.op = QgsRasterCalcNode::opMAX; return FUNCTION_2_ARGS;}
"sqrt" { raster_lval.op = QgsRasterCalcNode::opSQRT; return FUNCTION;}
"sin" { raster_lval.op = QgsRasterCalcNode::opSIN; return FUNCTION;}
"cos" { raster_lval.op = QgsRasterCalcNode::opCOS; return FUNCTION;}
"tan" { raster_lval.op = QgsRasterCalcNode::opTAN; return FUNCTION;}
"asin" { raster_lval.op = QgsRasterCalcNode::opASIN; return FUNCTION;}
"acos" { raster_lval.op = QgsRasterCalcNode::opACOS; return FUNCTION;}
"atan" { raster_lval.op = QgsRasterCalcNode::opATAN; return FUNCTION;}
"ln" { raster_lval.op = QgsRasterCalcNode::opLOG; return FUNCTION;}
"log10" { raster_lval.op = QgsRasterCalcNode::opLOG10; return FUNCTION;}
"abs" { raster_lval.op = QgsRasterCalcNode::opABS; return FUNCTION;}
"min" { raster_lval.op = QgsRasterCalcNode::opMIN; return FUNCTION_2_ARGS;}
"max" { raster_lval.op = QgsRasterCalcNode::opMAX; return FUNCTION_2_ARGS;}
"AND" { return AND; }
"OR" { return OR; }
@ -77,7 +78,7 @@ raster_band_ref_quoted \"(\\.|[^"])*\"
[()] { return yytext[0]; }
{number} { rasterlval.number = atof(rastertext); return NUMBER; }
{number} { raster_lval.number = atof(raster_text); return NUMBER; }
{raster_band_ref} { return RASTER_BAND_REF; }
@ -92,5 +93,5 @@ raster_band_ref_quoted \"(\\.|[^"])*\"
void set_raster_input_buffer(const char* buffer)
{
raster_scan_string(buffer);
raster__scan_string(buffer);
}

View File

@ -30,15 +30,15 @@
QgsRasterCalcNode* parseRasterCalcString(const QString& str, QString& parserErrorMsg);
//! from lex.yy.c
extern int rasterlex();
extern char* rastertext;
extern int raster_lex();
extern char* raster_text;
extern void set_raster_input_buffer(const char* buffer);
//! variable where the parser error will be stored
QString rParserErrorMsg;
//! sets gParserErrorMsg
void rastererror(const char* msg);
void raster_error(const char* msg);
//! temporary list for nodes without parent (if parsing fails these nodes are removed)
QList<QgsRasterCalcNode*> gTmpNodes;
@ -98,7 +98,7 @@ raster_exp:
| '+' raster_exp %prec UMINUS { $$ = $2; }
| '-' raster_exp %prec UMINUS { $$ = new QgsRasterCalcNode( QgsRasterCalcNode::opSIGN, $2, 0 ); joinTmpNodes($$, $2, 0); }
| NUMBER { $$ = new QgsRasterCalcNode($1); addToTmpNodes($$); }
| RASTER_BAND_REF { $$ = new QgsRasterCalcNode(QString::fromUtf8(rastertext)); addToTmpNodes($$); }
| RASTER_BAND_REF { $$ = new QgsRasterCalcNode(QString::fromUtf8(raster_text)); addToTmpNodes($$); }
;
%%
@ -136,7 +136,7 @@ QgsRasterCalcNode* localParseRasterCalcString(const QString& str, QString& parse
Q_ASSERT(gTmpNodes.count() == 0);
set_raster_input_buffer(str.toUtf8().constData());
int res = rasterparse();
int res = raster_parse();
// list should be empty when parsing was OK
if (res == 0) // success?

View File

@ -1,6 +1,16 @@
############################################################
# sources
BISON_TARGET(QgsExpressionParser qgsexpressionparser.yy ${CMAKE_CURRENT_BINARY_DIR}/qgsexpressionparser.cpp COMPILE_FLAGS "-p exp_")
FLEX_TARGET(QgsExpressionLexer qgsexpressionlexer.ll ${CMAKE_CURRENT_BINARY_DIR}/qgsexpressionlexer.cpp)
ADD_FLEX_BISON_DEPENDENCY(QgsExpressionLexer QgsExpressionParser)
BISON_TARGET(QgsSqlStatementParser qgssqlstatementparser.yy ${CMAKE_CURRENT_BINARY_DIR}/qgssqlstatementparser.cpp COMPILE_FLAGS "-p sqlstatement_")
FLEX_TARGET(QgsSqlStatementLexer qgssqlstatementlexer.ll ${CMAKE_CURRENT_BINARY_DIR}/qgssqlstatementlexer.cpp)
ADD_FLEX_BISON_DEPENDENCY(QgsSqlStatementLexer QgsSqlStatementParser)
BISON_TARGET(QgsMeshCalcParser mesh/qgsmeshcalcparser.yy ${CMAKE_CURRENT_BINARY_DIR}/qgsmeshcalcparser.cpp COMPILE_FLAGS "-p mesh_")
FLEX_TARGET(QgsMeshCalcLexer mesh/qgsmeshcalclexer.ll ${CMAKE_CURRENT_BINARY_DIR}/qgsmeshcalclexer.cpp)
ADD_FLEX_BISON_DEPENDENCY(QgsMeshCalcLexer QgsMeshCalcParser)
set(QGIS_CORE_SRCS
${CMAKE_SOURCE_DIR}/external/kdbush/include/kdbush.hpp
@ -14,6 +24,13 @@ set(QGIS_CORE_SRCS
${CMAKE_SOURCE_DIR}/external/meshOptimizer/simplifier.cpp
${FLEX_QgsExpressionLexer_OUTPUTS}
${BISON_QgsExpressionParser_OUTPUTS}
${FLEX_QgsSqlStatementLexer_OUTPUTS}
${BISON_QgsSqlStatementParser_OUTPUTS}
${FLEX_QgsMeshCalcLexer_OUTPUTS}
${BISON_QgsMeshCalcParser_OUTPUTS}
callouts/qgscallout.cpp
callouts/qgscalloutsregistry.cpp
@ -793,6 +810,7 @@ set(QGIS_CORE_SRCS
qgsuserprofile.cpp
qgsuserprofilemanager.cpp
)
if (WITH_INTERNAL_POLY2TRI)
@ -842,13 +860,6 @@ if (${QT_VERSION_BASE}Positioning_FOUND)
)
endif()
ADD_FLEX_FILES_PREFIX(QGIS_CORE_SRCS exp_ qgsexpressionlexer.ll)
ADD_FLEX_FILES_PREFIX(QGIS_CORE_SRCS sqlstatement_ qgssqlstatementlexer.ll)
ADD_FLEX_FILES_PREFIX(QGIS_CORE_SRCS mesh mesh/qgsmeshcalclexer.ll)
ADD_BISON_FILES_PREFIX(QGIS_CORE_SRCS exp_ qgsexpressionparser.yy)
ADD_BISON_FILES_PREFIX(QGIS_CORE_SRCS sqlstatement_ qgssqlstatementparser.yy)
ADD_BISON_FILES_PREFIX(QGIS_CORE_SRCS mesh mesh/qgsmeshcalcparser.yy)
if(NOT MSVC)
set_source_files_properties(
qgsexpressionparser.cpp
@ -1821,8 +1832,11 @@ set(IMAGE_RCCS ../../images/images.qrc)
#############################################################
# qgis_core library
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_library(qgis_core ${LIBRARY_TYPE} ${QGIS_CORE_SRCS} ${QGIS_CORE_HDRS} ${QGIS_CORE_PRIVATE_HDRS} ${IMAGE_RCCS})
# require c++17
target_compile_features(qgis_core PRIVATE cxx_std_17)

View File

@ -19,6 +19,7 @@
%option nounput
%option case-insensitive
%option never-interactive
%option prefix="mesh_"
// ensure that lexer will be 8-bit (and not just 7-bit)
%option 8bit
@ -55,14 +56,14 @@ dataset_ref_quoted \"(\\.|[^"])*\"
%%
"sum_aggr" { meshlval.op = QgsMeshCalcNode::opSUM_AGGR; return FUNCTION; }
"max_aggr" { meshlval.op = QgsMeshCalcNode::opMAX_AGGR; return FUNCTION; }
"min_aggr" { meshlval.op = QgsMeshCalcNode::opMIN_AGGR; return FUNCTION; }
"average_aggr" { meshlval.op = QgsMeshCalcNode::opAVG_AGGR; return FUNCTION; }
"abs" { meshlval.op = QgsMeshCalcNode::opABS; return FUNCTION; }
"sum_aggr" { mesh_lval.op = QgsMeshCalcNode::opSUM_AGGR; return FUNCTION; }
"max_aggr" { mesh_lval.op = QgsMeshCalcNode::opMAX_AGGR; return FUNCTION; }
"min_aggr" { mesh_lval.op = QgsMeshCalcNode::opMIN_AGGR; return FUNCTION; }
"average_aggr" { mesh_lval.op = QgsMeshCalcNode::opAVG_AGGR; return FUNCTION; }
"abs" { mesh_lval.op = QgsMeshCalcNode::opABS; return FUNCTION; }
"max" { meshlval.op = QgsMeshCalcNode::opMAX; return FUNCTION2; }
"min" { meshlval.op = QgsMeshCalcNode::opMIN; return FUNCTION2; }
"max" { mesh_lval.op = QgsMeshCalcNode::opMAX; return FUNCTION2; }
"min" { mesh_lval.op = QgsMeshCalcNode::opMIN; return FUNCTION2; }
"IF" { return IF; }
"AND" { return AND; }
@ -77,7 +78,7 @@ dataset_ref_quoted \"(\\.|[^"])*\"
[()] { return yytext[0]; }
{number} { meshlval.number = atof(meshtext); return NUMBER; }
{number} { mesh_lval.number = atof(mesh_text); return NUMBER; }
{dataset_ref} { return DATASET_REF; }
@ -88,5 +89,5 @@ dataset_ref_quoted \"(\\.|[^"])*\"
void set_mesh_input_buffer(const char* buffer)
{
mesh_scan_string(buffer);
mesh__scan_string(buffer);
}

View File

@ -29,15 +29,15 @@
QgsMeshCalcNode* parseMeshCalcString(const QString& str, QString& parserErrorMsg);
//! from lex.yy.c
extern int meshlex();
extern char* meshtext;
extern int mesh_lex();
extern char* mesh_text;
extern void set_mesh_input_buffer(const char* buffer);
//! variable where the parser error will be stored
QString rMeshParserErrorMsg;
//! sets gParserErrorMsg
void mesherror(const char* msg);
void mesh_error(const char* msg);
//! temporary list for nodes without parent (if parsing fails these nodes are removed)
QList<QgsMeshCalcNode*> gMeshTmpNodes;
@ -102,7 +102,7 @@ mesh_exp:
| '+' mesh_exp %prec UMINUS { $$ = $2; }
| '-' mesh_exp %prec UMINUS { $$ = new QgsMeshCalcNode( QgsMeshCalcNode::opSIGN, $2, 0 ); joinTmpNodes($$, $2, 0, 0); }
| NUMBER { $$ = new QgsMeshCalcNode($1); addToTmpNodes($$); }
| DATASET_REF { $$ = new QgsMeshCalcNode(QString::fromUtf8(meshtext)); addToTmpNodes($$); }
| DATASET_REF { $$ = new QgsMeshCalcNode(QString::fromUtf8(mesh_text)); addToTmpNodes($$); }
| NODATA { $$ = new QgsMeshCalcNode(); addToTmpNodes($$); }
;
@ -141,7 +141,7 @@ QgsMeshCalcNode* localParseMeshCalcString(const QString& str, QString& parserErr
Q_ASSERT(gMeshTmpNodes.count() == 0);
set_mesh_input_buffer(str.toUtf8().constData());
int res = meshparse();
int res = mesh_parse();
// list should be empty when parsing was OK
if (res == 0) // success?
@ -159,7 +159,7 @@ QgsMeshCalcNode* localParseMeshCalcString(const QString& str, QString& parserErr
}
}
void mesherror(const char* msg)
void mesh_error(const char* msg)
{
rMeshParserErrorMsg = msg;
}

View File

@ -412,3 +412,4 @@ void exp_error(YYLTYPE* yyloc,expression_parser_context* parser_ctx, const char*
parser_ctx->errorMsg = parser_ctx->errorMsg + "\n" + msg;
}