]> www.ginac.de Git - ginac.git/blob - ginsh/ginsh_lexer.ll
- switched to automake build environment
[ginac.git] / ginsh / ginsh_lexer.ll
1 /*
2  *  ginsh.l - GiNaC Interactive Shell, lexical analyzer definition
3  *
4  *  This file must be processed with flex
5  */
6
7
8 /*
9  *  Definitions
10  */
11
12 %{
13 #include "config.h"
14
15 #include <stdio.h>
16 extern "C" {
17 #include <readline/readline.h>
18 #include <readline/history.h>
19 }
20 #include <map>
21
22 #include <ginac/ginac.h>
23 #include "ginsh.h"
24
25 #include "ginsh_parser.h"
26
27 #define YY_INPUT(buf, result, max_size) (result = ginsh_input(buf, max_size))
28
29 // Table of all used symbols
30 sym_tab syms;
31
32 // lex input function
33 static int ginsh_input(char *buf, int max_size);
34 %}
35
36         /* Abbreviations */
37 D       [0-9]
38 E       [elEL][-+]?{D}+
39 A       [a-zA-Z_]
40 AN      [0-9a-zA-Z_]
41
42
43 /*
44  *  Lexical rules
45  */
46
47 %%
48 [ \t\n]+                /* skip whitespace */
49 \\$                     /* skip line continuations */
50 "#".*                   /* skip comments starting with "#" */
51 ^"!".*                  system(yytext + 1);     /* execute shell command */
52
53                         /* special values */
54 Pi                      yylval = Pi; return T_LITERAL;
55 EulerGamma              yylval = EulerGamma; return T_LITERAL;
56 Catalan                 yylval = Catalan; return T_LITERAL;
57 FAIL                    yylval = *new fail(); return T_LITERAL;
58 I                       yylval = I; return T_NUMBER;
59 Digits                  yylval = (long)Digits; return T_DIGITS;
60
61                         /* keywords */
62 quit|exit               return T_QUIT;
63 print                   return T_PRINT;
64 time                    return T_TIME;
65 xyzzy                   return T_XYZZY;
66 inventory               return T_INVENTORY;
67 look                    return T_LOOK;
68 score                   return T_SCORE;
69
70                         /* comparison */
71 "=="                    return T_EQUAL;
72 "!="                    return T_NOTEQ;
73 "<="                    return T_LESSEQ;
74 ">="                    return T_GREATEREQ;
75
76                         /* last 1..3 expressions */
77 \"                      return T_QUOTE;
78 \"\"                    return T_QUOTE2;
79 \"\"\"                  return T_QUOTE3;
80
81                         /* matrix delimiters */
82 \[\[                    return T_MATRIX_BEGIN;
83 \]\]                    return T_MATRIX_END;
84
85                         /* numbers */
86 {D}+                    |
87 {D}+"."{D}*({E})?       |
88 {D}*"."{D}+({E})?       |
89 {D}+{E}                 yylval = numeric(yytext); return T_NUMBER;
90
91                         /* symbols */
92 {A}{AN}*                {
93                                 if (syms.find(yytext) == syms.end())
94                                         syms[yytext] = *(new symbol(yytext));
95                                 yylval = syms[yytext];
96                                 return T_SYMBOL;
97                         }
98
99                         /* everything else */
100 .                       return *yytext;
101
102 %%
103
104
105 /*
106  *  Routines
107  */
108
109 static int line_length = 0;
110 static char *line_read = NULL;
111 static char *line_ptr;
112
113 // Input function that uses libreadline for interactive input
114 static int ginsh_input(char *buf, int max_size)
115 {
116         int result;
117         if (yy_current_buffer->yy_is_interactive) {
118                 int actual;
119
120                 // Do we need to read a new line?
121                 if (line_length == 0) {
122
123                         // Free old line
124                         if (line_read)
125                                 free(line_read);
126
127                         // Read new line, prompt "> "
128                         line_read = line_ptr = readline("> ");
129
130                         // EOF?
131                         if (!line_read) {
132                                 line_length = 0;
133                                 return YY_NULL;
134                         }
135
136                         // Add non-empty lines to history
137                         line_length = strlen(line_read) + 1;
138                         if (line_length > 1)
139                                 add_history(line_read);
140
141                         // Reappend trailing '\n' which is stripped by readline()
142                         line_read[line_length - 1] = '\n';
143                 }
144
145                 // Copy data to lex buffer
146                 actual = line_length > max_size ? max_size : line_length;
147                 memcpy(buf, line_ptr, actual);
148                 line_length -= actual;
149                 line_ptr += actual;
150                 result = actual;
151
152         } else if (((result = fread(buf, 1, max_size, yyin)) == 0) && ferror(yyin))
153                 YY_FATAL_ERROR("input in flex scanner failed");
154
155         return result;
156 }
157
158 // Scanner terminates on EOF
159 int yywrap()
160 {
161         return 1;
162 }