]> www.ginac.de Git - ginac.git/blobdiff - ginac/input_lexer.ll
remove dependence on YYTEXT_POINTER which is not being defined when lex is
[ginac.git] / ginac / input_lexer.ll
index e0e9b468a1186c37f3e98a01574d011b96c7f1be..9098b4f91125c3dccbcb3be5e507392f8384d756 100644 (file)
@@ -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-2004 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
@@ -26,6 +26,8 @@
  *  Definitions
  */
 
+%pointer
+
 %{
 #include <iostream>
 #include <string>
 #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<string, ex> 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<std::string, sym_def> 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;
-Euler                  yylval = Euler; 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 */
+<<EOF>>                        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<symbol>(s))
+               return ex_to<symbol>(s).get_name();
+       else if (is_a<idx>(s) && is_a<symbol>(s.op(0)))
+               return ex_to<symbol>(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<lst>(l))
                return;
-       for (int i=0; i<l.nops(); i++) {
-               if (is_ex_exactly_of_type(l.op(i), symbol))
-                       syms[ex_to_symbol(l.op(i)).getname()] = l.op(i);
+       for (unsigned i=0; i<l.nops(); i++) {
+               const ex &o = l.op(i);
+               if (is_a<symbol>(o) || (is_a<idx>(o) && is_a<symbol>(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