1 /** @file ginsh_lexer.lpp
3 * Lexical analyzer definition for ginsh.
4 * This file must be processed with flex. */
7 * GiNaC Copyright (C) 1999-2021 Johannes Gutenberg University Mainz, Germany
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
39 #include "ginsh_parser.hpp"
42 using namespace GiNaC;
44 #define YY_INPUT(buf, result, max_size) (result = ginsh_input(buf, max_size))
46 // Table of all used symbols
49 // Type of symbols to generate (real or complex)
50 unsigned symboltype = domain::complex;
53 static int ginsh_input(char *buf, int max_size);
68 [ \t\n]+ /* skip whitespace */
69 \\$ /* skip line continuations */
70 "//".* /* skip comments starting with "//" */
71 ^"#".* /* skip lines starting with "#" */
72 ^"!".* system(yytext + 1); /* execute shell command */
75 Pi yylval = Pi; return T_LITERAL;
76 Euler yylval = Euler; return T_LITERAL;
77 Catalan yylval = Catalan; return T_LITERAL;
78 FAIL yylval = *new fail(); return T_LITERAL;
79 I yylval = I; return T_NUMBER;
80 Digits yylval = (long)Digits; return T_DIGITS;
83 quit|exit return T_QUIT;
84 warranty return T_WARRANTY;
86 iprint return T_IPRINT;
87 print_latex return T_PRINTLATEX;
88 print_csrc return T_PRINTCSRC;
91 inventory return T_INVENTORY;
94 complex_symbols return T_COMPLEX_SYMBOLS;
95 real_symbols return T_REAL_SYMBOLS;
100 "<=" return T_LESSEQ;
101 ">=" return T_GREATEREQ;
103 /* last 1..3 expressions */
105 \%\% return T_QUOTE2;
106 \%\%\% return T_QUOTE3;
116 {D}+{E} yylval = numeric(yytext); return T_NUMBER;
120 sym_tab::const_iterator i = syms.find(yytext);
121 if (i == syms.end()) {
122 if (symboltype == domain::complex) {
127 realsymbol tmp(yytext);
137 \${D}+ yylval = wild(atoi(yytext + 1)); return T_LITERAL;
139 /* everything else */
149 static int line_length = 0;
150 static char *line_read = nullptr;
151 static char *line_ptr;
153 // Input function that uses libreadline for interactive input
154 static int ginsh_input(char *buf, int max_size)
157 #if defined(YY_CURRENT_BUFFER)
158 if (YY_CURRENT_BUFFER->yy_is_interactive) {
160 if (yy_current_buffer->yy_is_interactive) {
162 #ifdef HAVE_LIBREADLINE
163 // Do we need to read a new line?
165 if (line_length == 0) {
171 // Read new line, prompt "> "
172 line_read = line_ptr = readline("> ");
180 // Add non-empty lines to history
181 line_length = strlen(line_read) + 1;
183 add_history(line_read);
185 // Reappend trailing '\n' which is stripped by readline()
186 line_read[line_length - 1] = '\n';
189 // Copy data to lex buffer
190 actual = line_length > max_size ? max_size : line_length;
191 memcpy(buf, line_ptr, actual);
192 line_length -= actual;
196 printf("> "); fflush(stdout);
198 for (n = 0; n < max_size && (c = getc(yyin)) != EOF && c != '\n'; ++n)
202 if (c == EOF && ferror(yyin))
203 YY_FATAL_ERROR("input in flex scanner failed");
206 } else if (((result = fread(buf, 1, max_size, yyin)) == 0) && ferror(yyin))
207 YY_FATAL_ERROR("input in flex scanner failed");
212 // List of input files to be processed
214 char **file_list = nullptr;
216 // EOF encountered, connect to next file. If this was the last file,
217 // connect to stdin. If this was stdin, terminate the scanner.
225 yyin = fopen(*file_list, "r");
226 if (yyin == nullptr) {
227 cerr << "Can't open " << *file_list << endl;