Commit | Line | Data |
---|---|---|
970ed795 | 1 | /****************************************************************************** |
d44e3c4f | 2 | * Copyright (c) 2000-2016 Ericsson Telecom AB |
970ed795 EL |
3 | * All rights reserved. This program and the accompanying materials |
4 | * are made available under the terms of the Eclipse Public License v1.0 | |
5 | * which accompanies this distribution, and is available at | |
6 | * http://www.eclipse.org/legal/epl-v10.html | |
d44e3c4f | 7 | * |
8 | * Contributors: | |
9 | * Baji, Laszlo | |
10 | * Balasko, Jeno | |
11 | * Delic, Adam | |
12 | * Forstner, Matyas | |
13 | * Raduly, Csaba | |
14 | * Szabo, Janos Zoltan – initial implementation | |
15 | * | |
970ed795 EL |
16 | ******************************************************************************/ |
17 | ||
18 | /** | |
19 | * Lexical analyzer for TTCN-3 character patterns. | |
20 | * | |
21 | * \author Matyas Forstner (Matyas.Forstner@eth.ericsson.se) | |
22 | * | |
23 | * 20031121 | |
24 | */ | |
25 | ||
26 | %option nostack | |
27 | %option noyylineno | |
28 | %option noyywrap | |
29 | %option nounput | |
30 | %option never-interactive | |
31 | %option prefix="pattern_yy" | |
32 | ||
33 | %{ /* ****************** C declarations ***************** */ | |
34 | ||
35 | #include <ctype.h> | |
36 | #include <stddef.h> | |
37 | #include "pattern.hh" | |
38 | #include "pattern_p.hh" | |
39 | ||
40 | /* Access the semantic value of the bison parser. Usually this is done by | |
41 | * #defining yylval to the appropriate symbol whose name depends on the | |
42 | * %name-prefix of the parser, e.g. pattern_yylval or pattern_unilval. | |
43 | * | |
44 | * Because we need to be able to access either one or the other, | |
45 | * we keep a pointer which is set by the parser when it calls | |
46 | * init_pattern_yylex() */ | |
47 | static YYSTYPE *yylval_ptr; | |
48 | #define yylval (*yylval_ptr) | |
49 | ||
50 | static unsigned int nof_parentheses = 0; | |
51 | static bool meta = false; | |
52 | ||
53 | %} /* ***************** definitions ***************** */ | |
54 | ||
55 | NUMBER 0|([1-9][0-9]*) | |
56 | ||
57 | /* start conditions */ | |
58 | %x SC_Set SC_Hash SC_HashParen SC_Quadruple SC_Quadruple_Set | |
59 | ||
60 | %% /* ***************** rules ************************* */ | |
61 | ||
62 | /* drop whitespaces */ | |
63 | <SC_Hash,SC_HashParen,SC_Quadruple,SC_Quadruple_Set>[ \t\r\n\v\f]+ | |
64 | ||
65 | <SC_Set> | |
66 | { | |
67 | ||
68 | "]" { | |
69 | BEGIN(INITIAL); | |
70 | return KW_Set_End; | |
71 | } | |
72 | ||
73 | "-]" { | |
74 | BEGIN(INITIAL); | |
75 | return KW_Set_Dash_End; | |
76 | } | |
77 | ||
78 | "-" return '-'; | |
79 | ||
80 | } /* SC_Set */ | |
81 | ||
82 | <SC_Hash> | |
83 | { | |
84 | ||
85 | [0-9] { | |
86 | BEGIN(INITIAL); | |
87 | yylval.u = yytext[0] - '0'; | |
88 | return TOK_Digit; | |
89 | } | |
90 | ||
91 | "(" { | |
92 | BEGIN(SC_HashParen); | |
93 | return '('; | |
94 | } | |
95 | ||
96 | } /* SC_Hash */ | |
97 | ||
98 | <SC_HashParen,SC_Quadruple,SC_Quadruple_Set> | |
99 | { | |
100 | ||
101 | {NUMBER} { | |
102 | errno = 0; | |
103 | yylval.u = strtoul(yytext, NULL, 10); | |
104 | if (errno != 0) TTCN_pattern_error("Number `%s' is too large to be " | |
105 | "represented in memory. (%s)", yytext, strerror(errno)); | |
106 | return TOK_Number; | |
107 | } | |
108 | ||
109 | "," return ','; | |
110 | ||
111 | } /* SC_HashParen,SC_Quadruple,SC_Quadruple_Set */ | |
112 | ||
113 | <SC_HashParen>")" { | |
114 | BEGIN(INITIAL); | |
115 | return ')'; | |
116 | } | |
117 | ||
118 | <SC_Quadruple,SC_Quadruple_Set> | |
119 | { | |
120 | ||
121 | "{" return '{'; | |
122 | ||
123 | "}" { | |
124 | if (YY_START == SC_Quadruple) BEGIN(INITIAL); | |
125 | else BEGIN(SC_Set); | |
126 | return '}'; | |
127 | } | |
128 | ||
129 | } /* SC_Quadruple,SC_Quadruple_Set */ | |
130 | ||
131 | "*" { meta = true; return '*'; } | |
132 | "+" { meta = true; return '+'; } | |
133 | "?" { meta = true; return '?'; } | |
134 | "|" { meta = true; return '|'; } | |
135 | ||
136 | "(" { | |
137 | nof_parentheses++; | |
138 | meta = true; | |
139 | return KW_Group_Begin; | |
140 | } | |
141 | ||
142 | ")" { | |
143 | if (nof_parentheses > 0) { | |
144 | nof_parentheses--; | |
145 | return KW_Group_End; | |
146 | } else { | |
147 | TTCN_pattern_error("Unmatched `)'."); | |
148 | yylval.c = ')'; | |
149 | return TOK_Char; | |
150 | } | |
151 | } | |
152 | ||
153 | "[" { | |
154 | BEGIN(SC_Set); | |
155 | meta = true; | |
156 | return KW_Set_Begin; | |
157 | } | |
158 | ||
159 | "[^" { | |
160 | BEGIN(SC_Set); | |
161 | meta = true; | |
162 | return KW_Set_Begin_Neg; | |
163 | } | |
164 | ||
165 | "[]" { | |
166 | BEGIN(SC_Set); | |
167 | meta = true; | |
168 | return KW_Set_Begin_Rsbrkt; | |
169 | } | |
170 | ||
171 | "[^]" { | |
172 | BEGIN(SC_Set); | |
173 | meta = true; | |
174 | return KW_Set_Begin_Neg_Rsbrkt; | |
175 | } | |
176 | ||
177 | "]" { | |
178 | TTCN_pattern_error("Unmatched `]'."); | |
179 | yylval.c = ']'; | |
180 | return TOK_Char; | |
181 | } | |
182 | ||
183 | "#" { | |
184 | BEGIN(SC_Hash); | |
185 | meta = true; | |
186 | return '#'; | |
187 | } | |
188 | ||
189 | <INITIAL,SC_Set> | |
190 | { | |
191 | ||
192 | /* \metacharacters */ | |
193 | "\\d" { meta = true; return KW_BS_d; } | |
194 | "\\w" { meta = true; return KW_BS_w; } | |
195 | "\\t" { meta = true; return KW_BS_t; } | |
196 | "\\n" { meta = true; return KW_BS_n; } | |
197 | "\\r" { meta = true; return KW_BS_r; } | |
198 | "\\s" { meta = true; return KW_BS_s; } | |
199 | "\\b" { meta = true; return KW_BS_b; } | |
200 | ||
201 | "\\q" { | |
202 | meta = true; | |
203 | if (YY_START == INITIAL) BEGIN(SC_Quadruple); | |
204 | else BEGIN(SC_Quadruple_Set); | |
205 | return KW_BS_q; | |
206 | } | |
207 | ||
208 | /* escaped special characters: ? * \ [ ] - ^ | ( ) # + { } */ | |
209 | \\[][?*\\^|()#+{}-] { | |
210 | yylval.c = yytext[1]; | |
211 | return TOK_Char; /* not meta */ | |
212 | } | |
213 | ||
214 | /* invalid escape sequences */ | |
215 | "\\"(.|"\n") { | |
216 | if (isprint((unsigned char)yytext[1])) | |
217 | TTCN_pattern_warning("Use of unrecognized escape sequence `\\%c' is " | |
218 | "deprecated.", yytext[1]); | |
219 | else TTCN_pattern_warning("Use of unrecognized escape sequence `\\' + " | |
220 | "character code %u (0x%02X) is deprecated.", (unsigned char)yytext[1], | |
221 | (unsigned char)yytext[1]); | |
222 | yylval.c = yytext[1]; | |
223 | return TOK_Char; | |
224 | } | |
225 | ||
226 | /* single backslash (at the end) */ | |
227 | \\ { | |
228 | TTCN_pattern_error("Invalid single backslash (`\\') character at the end " | |
229 | "of the pattern."); | |
230 | } | |
231 | ||
232 | .|"\n" { | |
233 | yylval.c = yytext[0]; | |
234 | return TOK_Char; | |
235 | } | |
236 | ||
237 | } /* INITIAL, SC_Set */ | |
238 | ||
239 | /* erroneous characters */ | |
240 | ||
241 | <SC_Hash>.|\n { | |
242 | if (isprint((unsigned char)yytext[0])) | |
243 | TTCN_pattern_error("A digit or `(' was expected after `#' instead of " | |
244 | "character `%c'.", yytext[0]); | |
245 | else TTCN_pattern_error("A digit or `(' was expected after `#' instead of " | |
246 | "character with code %u (0x%02X).", (unsigned char)yytext[0], | |
247 | (unsigned char)yytext[0]); | |
248 | } | |
249 | ||
250 | <SC_HashParen>. { | |
251 | if (isprint((unsigned char)yytext[0])) | |
252 | TTCN_pattern_error("A number, `,' or `)' was expected after `#(' instead " | |
253 | "of character `%c'.", yytext[0]); | |
254 | else TTCN_pattern_error("A number, `,' or `)' was expected after `#(' " | |
255 | "instead of character with code %u (0x%02X).", (unsigned char)yytext[0], | |
256 | (unsigned char)yytext[0]); | |
257 | } | |
258 | ||
259 | <SC_Quadruple,SC_Quadruple_Set>. { | |
260 | if (isprint((unsigned char)yytext[0])) | |
261 | TTCN_pattern_error("A number, `,' or `}' was expected after `\\q{' " | |
262 | "instead of character `%c'.", yytext[0]); | |
263 | else TTCN_pattern_error("A number, `,' or `}' was expected after `\\q{' " | |
264 | "instead of character with code %u (0x%02X).", (unsigned char)yytext[0], | |
265 | (unsigned char)yytext[0]); | |
266 | } | |
267 | ||
268 | %% | |
269 | ||
270 | unsigned int get_nof_parentheses() | |
271 | { | |
272 | return nof_parentheses; | |
273 | } | |
274 | ||
275 | bool has_meta() | |
276 | { | |
277 | return meta; | |
278 | } | |
279 | ||
280 | void init_pattern_yylex(YYSTYPE *sema_val) | |
281 | { | |
282 | BEGIN(INITIAL); | |
283 | yylval_ptr = sema_val; | |
284 | nof_parentheses = 0; | |
285 | meta = false; | |
286 | } |