summaryrefslogtreecommitdiff
path: root/demos/calc/calclex.l
blob: b5ba6875dd16c067d2033f545db441b95ff737d8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/* Lexical analyzer for calc program.

Copyright 2000, 2001, 2002 Free Software Foundation, Inc.

This file is part of the GNU MP Library.

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 the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.  See the GNU General Public License for more details.

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. */

%{
#include <string.h>
#include "calc-common.h"


#if WITH_READLINE
/* Let GNU flex use readline.  See the calcread.c redefined input() for a
   way that might work for a standard lex too.  */
#define YY_INPUT(buf,result,max_size)   \
  result = calc_input (buf, max_size);
#endif


/* Non-zero when reading the second or subsequent line of an expression,
   used to give a different prompt when using readline.  */
int  calc_more_input = 0;


const struct calc_keywords_t  calc_keywords[] = {
  { "abs",       ABS },
  { "bin",       BIN },
  { "decimal",   DECIMAL },
  { "fib",       FIB },
  { "hex",       HEX },
  { "help",      HELP },
  { "gcd",       GCD },
  { "kron",      KRON },
  { "lcm",       LCM },
  { "lucnum",    LUCNUM },
  { "nextprime", NEXTPRIME },
  { "powm",      POWM },
  { "quit",      QUIT },
  { "root",      ROOT },
  { "sqrt",      SQRT },
  { NULL }
};
%}

%%

[ \t\f] { /* white space is skipped */ }

[;\n]   { /* semicolon or newline separates statements */
          calc_more_input = 0;
          return EOS; }
\\\n    { /* escaped newlines are skipped */ }


#(([^\\\n]*)\\)+\n {
            /* comment through to escaped newline is skipped */ }
#[^\n]*\n { /* comment through to newline is a separator */
            calc_more_input = 0;
            return EOS; }
#[^\n]* {   /* comment through to EOF skipped */ }


[-+*/%()<>^!=,] { return yytext[0]; }
"<="    { return LE; }
">="    { return GE; }
"=="    { return EQ; }
"!="    { return NE; }
"<<"    { return LSHIFT; }
">>"    { return RSHIFT; }
"&&"    { return LAND; }
"||"    { return LOR; }

(0[xX])?[0-9A-F]+ {
        yylval.str = yytext;
        return NUMBER; }

[a-zA-Z][a-zA-Z0-9]* {
        int  i;

        for (i = 0; calc_keywords[i].name != NULL; i++)
          if (strcmp (yytext, calc_keywords[i].name) == 0)
            return calc_keywords[i].value;

        if (yytext[0] >= 'a' && yytext[0] <= 'z' && yytext[1] == '\0')
          {
            yylval.var = yytext[0] - 'a';
            return VARIABLE;
          }

        return BAD;
}

. { return BAD; }

%%

int
yywrap ()
{
  return 1;
}