Statistics
| Branch: | Revision:

root / src / common / expression.lex @ master

History | View | Annotate | Download (6.53 KB)

1
/*==================================================
2
 * File: expression.lex
3
 *
4
 *  Lexical analyser for generic arithmetic expressions.
5
 *
6
 *  Author: Andras Varga
7
 *
8
 ==================================================*/
9

    
10
/*--------------------------------------------------------------*
11
  Copyright (C) 2006-2008 OpenSim Ltd.
12

    
13
  This file is distributed WITHOUT ANY WARRANTY. See the file
14
  `license' for details on this and other legal matters.
15
*--------------------------------------------------------------*/
16

    
17

    
18
D  [0-9]
19
L  [$@a-zA-Z_]
20
X  [0-9a-fA-F]
21
E  [Ee][+-]?{D}+
22
S  [ \t\v\n\r\f]
23

    
24
%x cplusplusbody
25
%x stringliteral
26

    
27
/* the following option keeps isatty() out */
28
%option never-interactive
29

    
30
%{
31
#include <string.h>
32
#include "expressionyydefs.h"
33
#include "exception.h"
34
#include "expression.tab.hh"
35

    
36
#define yylval expressionyylval
37
extern YYSTYPE yylval;
38

    
39
// wrap symbols to allow several .lex files coexist
40
#define comment     expressionComment
41
#define countChars  expressionCount
42
#define extendCount expressionExtendCount
43

    
44
void comment();
45
void countChars();
46
void extendCount();
47

    
48
#define TEXTBUF_LEN 1024
49
static char textbuf[TEXTBUF_LEN];
50

    
51
// buffer to collect characters during extendCount()
52
static std::string extendbuf;
53

    
54
#include "stringutil.h"  // opp_strdup()
55
%}
56

    
57
%%
58
"//"                     { comment(); }
59

    
60
"double"                 { countChars(); return DOUBLETYPE; }
61
"int"                    { countChars(); return INTTYPE; }
62
"string"                 { countChars(); return STRINGTYPE; }
63
"bool"                   { countChars(); return BOOLTYPE; }
64

    
65
"true"                   { countChars(); return TRUE_; }
66
"false"                  { countChars(); return FALSE_; }
67

    
68
{L}({L}|{D})*            { countChars(); yylval = opp_strdup(yytext); return NAME; }
69
{D}+                     { countChars(); yylval = opp_strdup(yytext); return INTCONSTANT; }
70
0[xX]{X}+                { countChars(); yylval = opp_strdup(yytext); return INTCONSTANT; }
71
{D}+{E}                  { countChars(); yylval = opp_strdup(yytext); return REALCONSTANT; }
72
{D}*"."{D}+({E})?        { countChars(); yylval = opp_strdup(yytext); return REALCONSTANT; }
73

    
74
\"                       { BEGIN(stringliteral); countChars(); }
75
<stringliteral>{
76
      \n                 { BEGIN(INITIAL); throw std::runtime_error("Error parsing expression: unterminated string literal (append backslash to line for multi-line strings)"); /* NOTE: BEGIN(INITIAL) is important, otherwise parsing of the next file will start from the <stringliteral> state! */  }
77
      \\\n               { extendCount(); /* line continuation */ }
78
      \\\"               { extendCount(); /* qouted quote */ }
79
      \\[^\n\"]          { extendCount(); /* qouted char */ }
80
      [^\\\n\"]+         { extendCount(); /* character inside string literal */ }
81
      \"                 { extendCount(); yylval = opp_strdup(extendbuf.c_str()); BEGIN(INITIAL); return STRINGCONSTANT; /* closing quote */ }
82
}
83

    
84
","                      { countChars(); return ','; }
85
":"                      { countChars(); return ':'; }
86
"="                      { countChars(); return '='; }
87
"("                      { countChars(); return '('; }
88
")"                      { countChars(); return ')'; }
89
"["                      { countChars(); return '['; }
90
"]"                      { countChars(); return ']'; }
91
"."                      { countChars(); return '.'; }
92
"?"                      { countChars(); return '?'; }
93

    
94
"||"                     { countChars(); return OR_; }
95
"&&"                     { countChars(); return AND_; }
96
"##"                     { countChars(); return XOR_; }
97
"!"                      { countChars(); return NOT_; }
98

    
99
"|"                      { countChars(); return BINOR_; }
100
"&"                      { countChars(); return BINAND_; }
101
"#"                      { countChars(); return BINXOR_; }
102
"~"                      { countChars(); return BINCOMPL_; }
103
"<<"                     { countChars(); return SHIFTLEFT_; }
104
">>"                     { countChars(); return SHIFTRIGHT_; }
105

    
106
"^"                      { countChars(); return '^'; }
107
"+"                      { countChars(); return '+'; }
108
"-"                      { countChars(); return '-'; }
109
"*"                      { countChars(); return '*'; }
110
"/"                      { countChars(); return '/'; }
111
"%"                      { countChars(); return '%'; }
112
"<"                      { countChars(); return '<'; }
113
">"                      { countChars(); return '>'; }
114

    
115
"=="                     { countChars(); return EQ_; }
116
"!="                     { countChars(); return NE_; }
117
"<="                     { countChars(); return LE_; }
118
">="                     { countChars(); return GE_; }
119

    
120
{S}                      { countChars(); }
121
.                        { countChars(); return INVALID_CHAR; }
122

    
123
%%
124

    
125
int yywrap()
126
{
127
     return 1;
128
}
129

    
130
/*
131
 * - discards all remaining characters of a line of
132
 *   text from the inputstream.
133
 * - the characters are read with the input() and
134
 *   unput() functions.
135
 * - input() is sometimes called yyinput()...
136
 */
137
#ifdef __cplusplus
138
#define input  yyinput
139
#endif
140

    
141
/* the following #define is needed for broken flex versions */
142
#define yytext_ptr yytext
143

    
144
void comment()
145
{
146
    int c;
147
    while ((c = input())!='\n' && c!=0 && c!=EOF);
148
    if (c=='\n') unput(c);
149
}
150

    
151
/*
152
 * - counts the line and column number of the current token in `pos'
153
 * - keeps a record of the complete current line in `textbuf[]'
154
 * - yytext[] is the current token passed by (f)lex
155
 */
156
static void _count(bool updateprevpos)
157
{
158
    static int textbuflen;
159
    int i;
160

    
161
    /* printf("DBG: countChars(): prev=%d,%d  xpos=%d,%d yytext=>>%s<<\n",
162
           xprevpos.li, xprevpos.co, xpos.li, xpos.co, yytext);
163
    */
164

    
165
    /* init textbuf */
166
    if (xpos.li==1 && xpos.co==0) {
167
        textbuf[0]='\0'; textbuflen=0;
168
    }
169

    
170
    if (updateprevpos) {
171
        extendbuf = "";
172
        xprevpos = xpos;
173
    }
174
    extendbuf += yytext;
175
    for (i = 0; yytext[i] != '\0'; i++) {
176
        if (yytext[i] == '\n') {
177
            xpos.co = 0;
178
            xpos.li++;
179
            textbuflen=0; textbuf[0]='\0';
180
        } else if (yytext[i] == '\t')
181
            xpos.co += 8 - (xpos.co % 8);
182
        else
183
            xpos.co++;
184
        if (yytext[i] != '\n') {
185
            if (textbuflen < TEXTBUF_LEN-5) {
186
                textbuf[textbuflen++]=yytext[i]; textbuf[textbuflen]='\0';
187
            }
188
            else if (textbuflen == TEXTBUF_LEN-5) {
189
                strcpy(textbuf+textbuflen, "...");
190
                textbuflen++;
191
            } else {
192
                /* line too long -- ignore */
193
            }
194
        }
195
    }
196
}
197

    
198
void countChars()
199
{
200
    _count(true);
201
}
202

    
203
void extendCount()
204
{
205
    _count(false);
206
}
207

    
208