- expressions can now be read from streams; the input expression can contain
[ginac.git] / ginac / input_lexer.ll
1 /** @file input_lexer.ll
2  *
3  *  Lexical analyzer definition for reading expressions.
4  *  This file must be processed with flex. */
5
6 /*
7  *  GiNaC Copyright (C) 1999-2000 Johannes Gutenberg University Mainz, Germany
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23
24
25 /*
26  *  Definitions
27  */
28
29 %{
30 #include <iostream>
31 #include <string>
32 #include <map>
33 #include <stdexcept>
34
35 #include "input_lexer.h"
36 #include "ex.h"
37 #include "constant.h"
38 #include "fail.h"
39 #include "numeric.h"
40 #include "symbol.h"
41
42 #ifndef NO_NAMESPACE_GINAC
43 using namespace GiNaC;
44 namespace GiNaC {
45 #endif // ndef NO_NAMESPACE_GINAC
46
47 #include "input_parser.h"
48
49 #ifndef NO_NAMESPACE_GINAC
50 } // namespace GiNaC
51 #endif // ndef NO_NAMESPACE_GINAC
52
53 // Table of all used symbols
54 typedef map<string, ex> sym_tab;
55 static sym_tab syms;
56
57 // lex input function
58 static int lexer_input(char *buf, int max_size);
59 #define YY_INPUT(buf, result, max_size) (result = lexer_input(buf, max_size))
60 %}
61
62         /* The code output by flex doesn't work well with namespaces, so we're doing it this way */
63 %option prefix="ginac_yy"
64
65         /* Abbreviations */
66 D       [0-9]
67 E       [elEL][-+]?{D}+
68 A       [a-zA-Z_]
69 AN      [0-9a-zA-Z_]
70
71
72 /*
73  *  Lexical rules
74  */
75
76 %%
77 [ \t]+                  /* skip whitespace */
78
79                         /* special values */
80 Pi                      yylval = Pi; return T_LITERAL;
81 gamma                   yylval = gamma; return T_LITERAL;
82 Catalan                 yylval = Catalan; return T_LITERAL;
83 FAIL                    yylval = *new fail(); return T_LITERAL;
84 I                       yylval = I; return T_NUMBER;
85 Digits                  yylval = (long)Digits; return T_DIGITS;
86
87                         /* comparison */
88 "=="                    return T_EQUAL;
89 "!="                    return T_NOTEQ;
90 "<="                    return T_LESSEQ;
91 ">="                    return T_GREATEREQ;
92
93                         /* matrix delimiters */
94 \[\[                    return T_MATRIX_BEGIN;
95 \]\]                    return T_MATRIX_END;
96
97                         /* numbers */
98 {D}+                    |
99 {D}+"."{D}*({E})?       |
100 {D}*"."{D}+({E})?       |
101 {D}+{E}                 yylval = numeric(yytext); return T_NUMBER;
102
103                         /* symbols */
104 {A}{AN}*                {
105                                 if (syms.find(yytext) == syms.end())
106                                         syms[yytext] = *(new symbol(yytext));
107                                 yylval = syms[yytext];
108                                 return T_SYMBOL;
109                         }
110
111                         /* everything else */
112 .                       return *yytext;
113
114 %%
115
116
117 /*
118  *  Routines
119  */
120
121 // The string from which we will read
122 static string lexer_string;
123
124 // The current position within the string
125 static int curr_pos = 0;
126
127 // Input function that reads from string
128 static int lexer_input(char *buf, int max_size)
129 {
130         int actual = lexer_string.length() - curr_pos;
131         if (actual > max_size)
132                 actual = max_size;
133         if (actual <= 0)
134                 return YY_NULL;
135         lexer_string.copy(buf, actual, curr_pos);
136         curr_pos += actual;
137         return actual;
138 }
139
140 // EOF encountered, terminate the scanner
141 int ginac_yywrap()
142 {
143         return 1;
144 }
145
146 #ifndef NO_NAMESPACE_GINAC
147 namespace GiNaC {
148 #endif // ndef NO_NAMESPACE_GINAC
149
150 // Set the input string
151 void set_lexer_string(const string &s)
152 {
153         lexer_string = s;
154         curr_pos = 0;
155 }
156
157 // Set the list of predefined symbols
158 void set_lexer_symbols(ex l)
159 {
160         syms.clear();
161         if (!is_ex_exactly_of_type(l, lst))
162                 return;
163         for (int i=0; i<l.nops(); i++) {
164                 if (is_ex_exactly_of_type(l.op(i), symbol))
165                         syms[ex_to_symbol(l.op(i)).getname()] = l.op(i);
166         }
167 }
168
169 #ifndef NO_NAMESPACE_GINAC
170 } // namespace GiNaC
171 #endif // ndef NO_NAMESPACE_GINAC