X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?a=blobdiff_plain;f=ginac%2Finput_lexer.ll;h=84998d6cb25292493a90ab8abd3618564a7d6fa3;hb=568524ae4543f305035f4c5b2ecdb4cf78514c33;hp=eebdae4ae418030b4bbee9d736bc6e2298cc1368;hpb=956a3ad3779759028bfd742456ed9eafc3e85063;p=ginac.git diff --git a/ginac/input_lexer.ll b/ginac/input_lexer.ll index eebdae4a..84998d6c 100644 --- a/ginac/input_lexer.ll +++ b/ginac/input_lexer.ll @@ -4,7 +4,7 @@ * This file must be processed with flex. */ /* - * GiNaC Copyright (C) 1999-2000 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2005 Johannes Gutenberg University Mainz, Germany * * 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 @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -26,6 +26,8 @@ * Definitions */ +%pointer + %{ #include #include @@ -38,20 +40,36 @@ #include "fail.h" #include "numeric.h" #include "symbol.h" +#include "lst.h" +#include "idx.h" -#ifndef NO_NAMESPACE_GINAC using namespace GiNaC; namespace GiNaC { -#endif // ndef NO_NAMESPACE_GINAC #include "input_parser.h" -#ifndef NO_NAMESPACE_GINAC } // namespace GiNaC -#endif // ndef NO_NAMESPACE_GINAC -// Table of all used symbols -typedef map sym_tab; +// Table of all used symbols/indices +struct sym_def { + sym_def() : predefined(false) {} + sym_def(const ex &s, bool predef) : sym(s), predefined(predef) {} + ~sym_def() {} + + sym_def(const sym_def &other) {sym = other.sym; predefined = other.predefined;} + const sym_def &operator=(const sym_def &other) + { + if (this != &other) { + sym = other.sym; + predefined = other.predefined; + } + return *this; + } + + ex sym; + bool predefined; // true = user supplied symbol, false = lexer generated symbol +}; +typedef std::map sym_tab; static sym_tab syms; // lex input function @@ -59,9 +77,6 @@ static int lexer_input(char *buf, int max_size); #define YY_INPUT(buf, result, max_size) (result = lexer_input(buf, max_size)) %} - /* The code output by flex doesn't work well with namespaces, so we're doing it this way */ -%option prefix="ginac_yy" - /* Abbreviations */ D [0-9] E [elEL][-+]?{D}+ @@ -74,15 +89,15 @@ AN [0-9a-zA-Z_] */ %% -[ \t]+ /* skip whitespace */ +[ \t\n]+ /* skip whitespace */ /* special values */ -Pi yylval = Pi; return T_LITERAL; -gamma yylval = gamma; return T_LITERAL; -Catalan yylval = Catalan; return T_LITERAL; -FAIL yylval = *new fail(); return T_LITERAL; -I yylval = I; return T_NUMBER; -Digits yylval = (long)Digits; return T_DIGITS; +Pi ginac_yylval = Pi; return T_LITERAL; +Euler ginac_yylval = Euler; return T_LITERAL; +Catalan ginac_yylval = Catalan; return T_LITERAL; +FAIL ginac_yylval = *new fail(); return T_LITERAL; +I ginac_yylval = I; return T_NUMBER; +Digits ginac_yylval = (long)Digits; return T_DIGITS; /* comparison */ "==" return T_EQUAL; @@ -90,24 +105,29 @@ Digits yylval = (long)Digits; return T_DIGITS; "<=" return T_LESSEQ; ">=" return T_GREATEREQ; - /* matrix delimiters */ -\[\[ return T_MATRIX_BEGIN; -\]\] return T_MATRIX_END; - /* numbers */ {D}+ | +"#"{D}+"R"{AN}+ | +"#b"([01])+ | +"#o"[0-7]+ | +"#x"[0-9a-fA-F]+ | {D}+"."{D}*({E})? | {D}*"."{D}+({E})? | -{D}+{E} yylval = numeric(yytext); return T_NUMBER; +{D}+{E} ginac_yylval = numeric(yytext); return T_NUMBER; /* symbols */ {A}{AN}* { - if (syms.find(yytext) == syms.end()) - syms[yytext] = *(new symbol(yytext)); - yylval = syms[yytext]; + sym_tab::const_iterator i = syms.find(yytext); + if (i == syms.end()) { + syms[yytext] = sym_def(ginac_yylval = *(new symbol(yytext)), false); + } else + ginac_yylval = (*i).second.sym; return T_SYMBOL; } + /* end of input */ +<> return T_EOF; + /* everything else */ . return *yytext; @@ -119,7 +139,7 @@ Digits yylval = (long)Digits; return T_DIGITS; */ // The string from which we will read -static string lexer_string; +static std::string lexer_string; // The current position within the string static int curr_pos = 0; @@ -143,29 +163,47 @@ int ginac_yywrap() return 1; } -#ifndef NO_NAMESPACE_GINAC namespace GiNaC { -#endif // ndef NO_NAMESPACE_GINAC // Set the input string -void set_lexer_string(const string &s) +void set_lexer_string(const std::string &s) { lexer_string = s; curr_pos = 0; } -// Set the list of predefined symbols +// Get name of symbol/index +std::string get_symbol_name(const ex & s) +{ + if (is_a(s)) + return ex_to(s).get_name(); + else if (is_a(s) && is_a(s.op(0))) + return ex_to(s.op(0)).get_name(); + else + throw (std::runtime_error("get_symbol_name(): unexpected expression type")); +} + +// Set the list of predefined symbols/indices void set_lexer_symbols(ex l) { syms.clear(); - if (!is_ex_exactly_of_type(l, lst)) + if (!is_exactly_a(l)) return; - for (int i=0; i(o) || (is_a(o) && is_a(o.op(0)))) + syms[get_symbol_name(o)] = sym_def(o, true); } } -#ifndef NO_NAMESPACE_GINAC +// Check whether symbol/index was predefined +bool is_lexer_symbol_predefined(const ex &s) +{ + sym_tab::const_iterator i = syms.find(get_symbol_name(s)); + if (i == syms.end()) + return false; + else + return (*i).second.predefined; +} + } // namespace GiNaC -#endif // ndef NO_NAMESPACE_GINAC