/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2009,2010,2011,2012, by the GROMACS development team, led by
+ * Copyright (c) 2009,2010,2011,2012,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* \ingroup module_selection
* \endcond
*/
+#include "gmxpre.h"
+
+#include "scanner_internal.h"
+
#include <stdlib.h>
#include <string.h>
#include <string>
-#include "gromacs/legacyheaders/typedefs.h"
-#include "gromacs/legacyheaders/smalloc.h"
-#include "gromacs/legacyheaders/string2.h"
-
+#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/exceptions.h"
#include "gromacs/utility/gmxassert.h"
-#include "gromacs/utility/messagestringcollector.h"
+#include "gromacs/utility/smalloc.h"
#include "gromacs/utility/stringutil.h"
+#include "parser.h"
#include "parsetree.h"
+#include "scanner.h"
#include "selectioncollection-impl.h"
#include "selelem.h"
#include "selmethod.h"
#include "symrec.h"
-#include "parser.h"
-#include "scanner.h"
-#include "scanner_internal.h"
-
-//! Step in which the allocated memory for pretty-printed input is incremented.
+/*! \brief
+ * Step in which the allocated memory for pretty-printed input is incremented.
+ */
#define STRSTORE_ALLOCSTEP 1000
/* These are defined as macros in the generated scanner_flex.h.
}
else
{
- yylval->str = param->name ? strdup(param->name) : NULL;
+ yylval->str = param->name ? gmx_strdup(param->name) : NULL;
}
return PARAM;
}
* Processes a selection method token.
*/
static int
-init_method_token(YYSTYPE *yylval, gmx_ana_selmethod_t *method, bool bPosMod,
- gmx_sel_lexer_t *state)
+init_method_token(YYSTYPE *yylval, YYLTYPE *yylloc,
+ const gmx::SelectionParserSymbol *symbol,
+ bool bPosMod, gmx_sel_lexer_t *state)
{
+ gmx_ana_selmethod_t *method = symbol->methodValue();
/* If the previous token was not KEYWORD_POS, return EMPTY_POSMOD
* before the actual method to work around a limitation in Bison. */
if (!bPosMod && method->type != POS_VALUE)
{
- state->nextmethod = method;
+ state->nextMethodSymbol = symbol;
+ _gmx_sel_lexer_add_token(yylloc, NULL, 0, state);
return EMPTY_POSMOD;
}
+ _gmx_sel_lexer_add_token(yylloc, symbol->name().c_str(), -1, state);
yylval->meth = method;
if (!(method->flags & SMETH_MODIFIER) && method->nparams == 0)
{
/* Keyword */
switch (method->type)
{
- case INT_VALUE: return KEYWORD_NUMERIC;
- case REAL_VALUE: return KEYWORD_NUMERIC;
+ case INT_VALUE:
+ case REAL_VALUE:
+ state->bMatchOf = true;
+ return KEYWORD_NUMERIC;
case STR_VALUE: return KEYWORD_STR;
case GROUP_VALUE: return KEYWORD_GROUP;
default:
}
int
-_gmx_sel_lexer_process_pending(YYSTYPE *yylval, gmx_sel_lexer_t *state)
+_gmx_sel_lexer_process_pending(YYSTYPE *yylval, YYLTYPE *yylloc,
+ gmx_sel_lexer_t *state)
{
if (state->nextparam)
{
if (state->neom > 0)
{
--state->neom;
+ _gmx_sel_lexer_add_token(yylloc, NULL, 0, state);
return END_OF_METHOD;
}
state->nextparam = NULL;
state->bBoolNo = false;
- _gmx_sel_lexer_add_token(param->name, -1, state);
+ _gmx_sel_lexer_add_token(yylloc, param->name, -1, state);
return init_param_token(yylval, param, bBoolNo);
}
if (state->prev_pos_kw > 0)
{
--state->prev_pos_kw;
}
- if (state->nextmethod)
+ if (state->nextMethodSymbol)
{
- gmx_ana_selmethod_t *method = state->nextmethod;
-
- state->nextmethod = NULL;
- return init_method_token(yylval, method, true, state);
+ const gmx::SelectionParserSymbol *symbol = state->nextMethodSymbol;
+ state->nextMethodSymbol = NULL;
+ return init_method_token(yylval, yylloc, symbol, true, state);
}
return 0;
}
int
-_gmx_sel_lexer_process_identifier(YYSTYPE *yylval, char *yytext, size_t yyleng,
+_gmx_sel_lexer_process_identifier(YYSTYPE *yylval, YYLTYPE *yylloc,
+ char *yytext, size_t yyleng,
gmx_sel_lexer_t *state)
{
/* Check if the identifier matches with a parameter name */
state->bBoolNo = bBoolNo;
return END_OF_METHOD;
}
- _gmx_sel_lexer_add_token(param->name, -1, state);
+ _gmx_sel_lexer_add_token(yylloc, param->name, -1, state);
return init_param_token(yylval, param, bBoolNo);
}
}
/* Check if the identifier matches with a symbol */
const gmx::SelectionParserSymbol *symbol
- = state->sc->symtab->findSymbol(std::string(yytext, yyleng), false);
+ = state->sc->symtab->findSymbol(std::string(yytext, yyleng));
/* If there is no match, return the token as a string */
if (!symbol)
{
yylval->str = gmx_strndup(yytext, yyleng);
- _gmx_sel_lexer_add_token(yytext, yyleng, state);
+ _gmx_sel_lexer_add_token(yylloc, yytext, yyleng, state);
return IDENTIFIER;
}
- _gmx_sel_lexer_add_token(symbol->name().c_str(), -1, state);
gmx::SelectionParserSymbol::SymbolType symtype = symbol->type();
+ /* For method symbols, we need some extra processing. */
+ if (symtype == gmx::SelectionParserSymbol::MethodSymbol)
+ {
+ return init_method_token(yylval, yylloc, symbol, state->prev_pos_kw > 0, state);
+ }
+ _gmx_sel_lexer_add_token(yylloc, symbol->name().c_str(), -1, state);
/* Reserved symbols should have been caught earlier */
if (symtype == gmx::SelectionParserSymbol::ReservedSymbol)
{
GMX_THROW(gmx::InternalError("Unsupported variable type"));
return INVALID;
}
- delete yylval->sel;
- return INVALID; /* Should not be reached. */
- }
- /* For method symbols, return the correct type */
- if (symtype == gmx::SelectionParserSymbol::MethodSymbol)
- {
- gmx_ana_selmethod_t *method = symbol->methodValue();
- return init_method_token(yylval, method, state->prev_pos_kw > 0, state);
+ /* This position should not be reached. */
}
/* For position symbols, we need to return KEYWORD_POS, but we also need
* some additional handling. */
if (symtype == gmx::SelectionParserSymbol::PositionSymbol)
{
state->bMatchOf = true;
- yylval->str = strdup(symbol->name().c_str());
+ yylval->str = gmx_strdup(symbol->name().c_str());
state->prev_pos_kw = 2;
return KEYWORD_POS;
}
}
void
-_gmx_sel_lexer_add_token(const char *str, int len, gmx_sel_lexer_t *state)
+_gmx_sel_lexer_add_token(YYLTYPE *yylloc, const char *str, int len,
+ gmx_sel_lexer_t *state)
{
+ yylloc->startIndex = yylloc->endIndex = state->pslen;
/* Do nothing if the string is empty, or if it is a space and there is
* no other text yet, or if there already is a space. */
if (!str || len == 0 || strlen(str) == 0
strncpy(state->pselstr + state->pslen, str, len);
state->pslen += len;
state->pselstr[state->pslen] = 0;
+ yylloc->endIndex = state->pslen;
}
void
_gmx_sel_init_lexer(yyscan_t *scannerp, struct gmx_ana_selcollection_t *sc,
- bool bInteractive, int maxnr, bool bGroups,
- struct gmx_ana_indexgrps_t *grps)
+ gmx::TextWriter *statusWriter, int maxnr,
+ bool bGroups, struct gmx_ana_indexgrps_t *grps)
{
int rc = _gmx_sel_yylex_init(scannerp);
if (rc != 0)
gmx_sel_lexer_t *state = new gmx_sel_lexer_t;
state->sc = sc;
- state->errors = NULL;
state->bGroups = bGroups;
state->grps = grps;
state->nexpsel = (maxnr > 0 ? static_cast<int>(sc->sel.size()) + maxnr : -1);
- state->bInteractive = bInteractive;
+ state->statusWriter = statusWriter;
snew(state->pselstr, STRSTORE_ALLOCSTEP);
- state->pselstr[0] = 0;
- state->pslen = 0;
- state->nalloc_psel = STRSTORE_ALLOCSTEP;
+ state->pselstr[0] = 0;
+ state->pslen = 0;
+ state->nalloc_psel = STRSTORE_ALLOCSTEP;
+ state->currentLocation.startIndex = 0;
+ state->currentLocation.endIndex = 0;
snew(state->mstack, 20);
- state->mstack_alloc = 20;
- state->msp = -1;
- state->neom = 0;
- state->nextparam = NULL;
- state->nextmethod = NULL;
- state->prev_pos_kw = 0;
- state->bBoolNo = false;
- state->bMatchOf = false;
- state->bMatchBool = false;
- state->bCmdStart = true;
- state->bBuffer = false;
+ state->mstack_alloc = 20;
+ state->msp = -1;
+ state->neom = 0;
+ state->nextparam = NULL;
+ state->nextMethodSymbol = NULL;
+ state->prev_pos_kw = 0;
+ state->bBoolNo = false;
+ state->bMatchOf = false;
+ state->bMatchBool = false;
+ state->bCmdStart = true;
+ state->bBuffer = false;
_gmx_sel_yyset_extra(state, *scannerp);
}
_gmx_sel_yylex_destroy(scanner);
}
-void
-_gmx_sel_set_lexer_error_reporter(yyscan_t scanner,
- gmx::MessageStringCollector *errors)
-{
- gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner);
- state->errors = errors;
-}
-
void
_gmx_sel_lexer_set_exception(yyscan_t scanner,
const boost::exception_ptr &ex)
}
}
-bool
-_gmx_sel_is_lexer_interactive(yyscan_t scanner)
+gmx::TextWriter *
+_gmx_sel_lexer_get_status_writer(yyscan_t scanner)
{
gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner);
- return state->bInteractive;
+ return state->statusWriter;
}
struct gmx_ana_selcollection_t *
return state->sc;
}
-gmx::MessageStringCollector *
-_gmx_sel_lexer_error_reporter(yyscan_t scanner)
-{
- gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner);
- GMX_RELEASE_ASSERT(state->errors != NULL, "Error reporter not set");
- return state->errors;
-}
-
bool
_gmx_sel_lexer_has_groups_set(yyscan_t scanner)
{
return state->pselstr;
}
+void
+_gmx_sel_lexer_set_current_location(yyscan_t scanner,
+ const gmx::SelectionLocation &location)
+{
+ gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner);
+ state->currentLocation = location;
+}
+
+const gmx::SelectionLocation &
+_gmx_sel_lexer_get_current_location(yyscan_t scanner)
+{
+ gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner);
+ return state->currentLocation;
+}
+
+std::string
+_gmx_sel_lexer_get_current_text(yyscan_t scanner)
+{
+ gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner);
+ return _gmx_sel_lexer_get_text(scanner, state->currentLocation);
+}
+
+std::string
+_gmx_sel_lexer_get_text(yyscan_t scanner,
+ const gmx::SelectionLocation &location)
+{
+ gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner);
+ const int startIndex = location.startIndex;
+ const int endIndex = location.endIndex;
+ if (startIndex >= endIndex)
+ {
+ return std::string();
+ }
+ return std::string(&state->pselstr[startIndex], endIndex - startIndex);
+}
+
void
_gmx_sel_lexer_clear_pselstr(yyscan_t scanner)
{