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 | * Balasko, Jeno | |
10 | * Baranyi, Botond | |
11 | * Delic, Adam | |
12 | * Raduly, Csaba | |
13 | * Szabados, Kristof | |
14 | * Szabo, Janos Zoltan – initial implementation | |
15 | * | |
970ed795 EL |
16 | ******************************************************************************/ |
17 | %option noyywrap | |
18 | %option never-interactive | |
19 | %option nounput | |
20 | %option stack | |
21 | %option noyy_top_state | |
22 | %option prefix="coding_attrib_" | |
23 | ||
24 | %{ | |
25 | ||
26 | /* Lexer for "extension" attributes of functions, external functions and | |
27 | * port types related to message encoding. */ | |
28 | ||
29 | #include <ctype.h> | |
30 | ||
31 | #include "../string.hh" | |
32 | #include "../Identifier.hh" | |
33 | #include "Attributes.hh" | |
34 | #include "Ttcnstuff.hh" | |
35 | ||
36 | using namespace Ttcn; | |
37 | using namespace Common; | |
38 | ||
39 | #include "coding_attrib_p.hh" | |
40 | ||
41 | #define yylval coding_attrib_lval | |
42 | #define yylloc coding_attrib_lloc | |
43 | ||
44 | /** global variable indicating the location of the returned token to bison */ | |
45 | extern YYLTYPE yylloc; | |
46 | ||
47 | /** the name of the current input file */ | |
48 | const char *coding_attrib_infile; | |
49 | ||
50 | /** always points to the first character of the regexp to be recognized */ | |
51 | static int current_line, current_column; | |
52 | ||
53 | /** the actual size of state condition stack */ | |
54 | static size_t stack_size = 0; | |
55 | ||
56 | static void fill_location() | |
57 | { | |
58 | yylloc.first_line = current_line; | |
59 | yylloc.first_column = current_column; | |
60 | current_column += yyleng; | |
61 | yylloc.last_line = current_line; | |
62 | yylloc.last_column = current_column; | |
63 | } | |
64 | ||
65 | #define PUSH_STATE(new_state) yy_push_state(new_state); stack_size++ | |
66 | ||
67 | #define RETURN(ret_val) fill_location(); last_token = ret_val; return ret_val | |
68 | ||
69 | %} | |
70 | ||
71 | LINECOMMENT "//"[^\r\n]* | |
72 | WHITESPACE [ \t\v\f] | |
73 | NEWLINE \r|\n|\r\n | |
74 | IDENTIFIER [A-Za-z][A-Za-z0-9_]* | |
75 | NUMBER 0|[1-9][0-9]* | |
76 | ||
77 | %s SC_start | |
78 | %s SC_prototype SC_errorbehavior | |
79 | %s SC_encodingtype SC_encodingoptions | |
80 | %s SC_user SC_typemappinglist SC_mappingtype SC_functionmapping | |
81 | %s SC_printing | |
82 | ||
83 | %x SC_blockcomment | |
84 | ||
85 | %% | |
86 | /* local variables of yylex() */ | |
87 | static int last_token = EOF; | |
88 | int start_line = 0, start_column = 0; /**< used by block comments */ | |
89 | ||
90 | /* eat up whitespaces and line comments in all states */ | |
91 | ||
92 | <*>{ | |
93 | {WHITESPACE}+|{LINECOMMENT} current_column += yyleng; | |
94 | {WHITESPACE}*{NEWLINE} { | |
95 | current_line++; | |
96 | current_column = 0; | |
97 | } | |
98 | } | |
99 | ||
100 | "/*" { | |
101 | start_line = current_line; | |
102 | start_column = current_column; | |
103 | current_column += yyleng; | |
104 | PUSH_STATE(SC_blockcomment); | |
105 | } | |
106 | ||
107 | <SC_blockcomment>{ | |
108 | "*/" { | |
109 | current_column += yyleng; | |
110 | yy_pop_state(); | |
111 | stack_size--; | |
112 | } | |
113 | [^\r\n] current_column++; | |
114 | } | |
115 | ||
116 | <SC_errorbehavior>{IDENTIFIER} { | |
117 | yylval.str = new string(yyleng, yytext); | |
118 | RETURN(ErrorBehaviorString); | |
119 | } | |
120 | ||
121 | <SC_encodingoptions>[^ \t\r\n\(\)]+ { | |
122 | yylval.str = new string(yyleng, yytext); | |
123 | RETURN(EncodingOption); | |
124 | } | |
125 | ||
126 | <SC_printing>{ | |
127 | compact RETURN(CompactKeyword); | |
128 | pretty RETURN(PrettyKeyword); | |
129 | } | |
130 | ||
131 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | |
132 | * Initial start condition. Will switch to another start condition later, | |
133 | * when the opening paren '(' is encountered. | |
134 | */ | |
135 | <SC_start>{ | |
136 | prototype RETURN(PrototypeKeyword); | |
137 | ||
138 | address RETURN(AddressKeyword); | |
139 | /* porttype */ | |
140 | internal RETURN(InternalKeyword); | |
141 | provider RETURN(ProviderKeyword); | |
142 | user { | |
143 | BEGIN(SC_user); | |
144 | RETURN(UserKeyword); | |
145 | } | |
146 | anytype RETURN(AnyTypeKeyword); | |
147 | ||
148 | version RETURN(VersionKeyword); | |
149 | requires RETURN(RequiresKeyword); | |
150 | requiresTITAN RETURN(ReqTitanKeyword); | |
151 | ||
152 | transparent RETURN(TransparentKeyword); | |
153 | } | |
154 | ||
155 | /* TTCN-3 keywords are valid in all (non-exclusive) states */ | |
156 | ||
157 | bitstring RETURN(BitStringKeyword); | |
158 | boolean RETURN(BooleanKeyword); | |
159 | charstring RETURN(CharStringKeyword); | |
160 | default RETURN(DefaultKeyword); | |
161 | float RETURN(FloatKeyword); | |
162 | function RETURN(FunctionKeyword); | |
163 | hexstring RETURN(HexStringKeyword); | |
164 | in RETURN(InKeyword); | |
165 | integer RETURN(IntegerKeyword); | |
166 | objid RETURN(ObjectIdentifierKeyword); | |
167 | octetstring RETURN(OctetStringKeyword); | |
168 | out RETURN(OutKeyword); | |
169 | universal RETURN(UniversalKeyword); | |
170 | verdicttype RETURN(VerdictTypeKeyword); | |
171 | ||
172 | /* the rest of the keywords are context sensitive */ | |
173 | ||
174 | <SC_start,SC_mappingtype>{ | |
175 | decode RETURN(DecodeKeyword); | |
176 | encode RETURN(EncodeKeyword); | |
177 | errorbehavior RETURN(ErrorBehaviorKeyword); | |
178 | printing RETURN(PrintingKeyword); | |
179 | } | |
180 | ||
181 | <SC_mappingtype>{ | |
182 | discard RETURN(DiscardKeyword); | |
183 | simple RETURN(SimpleKeyword); | |
184 | } | |
185 | ||
186 | <SC_prototype>{ | |
187 | backtrack { | |
188 | yylval.prototype = Def_Function_Base::PROTOTYPE_BACKTRACK; | |
189 | RETURN(PrototypeSetting); | |
190 | } | |
191 | convert { | |
192 | yylval.prototype = Def_Function_Base::PROTOTYPE_CONVERT; | |
193 | RETURN(PrototypeSetting); | |
194 | } | |
195 | fast { | |
196 | yylval.prototype = Def_Function_Base::PROTOTYPE_FAST; | |
197 | RETURN(PrototypeSetting); | |
198 | } | |
199 | sliding { | |
200 | yylval.prototype = Def_Function_Base::PROTOTYPE_SLIDING; | |
201 | RETURN(PrototypeSetting); | |
202 | } | |
203 | } | |
204 | ||
205 | <SC_encodingtype>{ | |
206 | BER { | |
207 | yylval.encoding_type = Type::CT_BER; | |
208 | RETURN(EncodingType); | |
209 | } | |
210 | PER { | |
211 | yylval.encoding_type = Type::CT_PER; | |
212 | RETURN(EncodingType); | |
213 | } | |
214 | XER { | |
215 | yylval.encoding_type = Type::CT_XER; | |
216 | RETURN(EncodingType); | |
217 | } | |
218 | RAW { | |
219 | yylval.encoding_type = Type::CT_RAW; | |
220 | RETURN(EncodingType); | |
221 | } | |
222 | TEXT { | |
223 | yylval.encoding_type = Type::CT_TEXT; | |
224 | RETURN(EncodingType); | |
225 | } | |
226 | JSON { | |
227 | yylval.encoding_type = Type::CT_JSON; | |
228 | RETURN(EncodingType); | |
229 | } | |
3f84031e | 230 | {IDENTIFIER} { |
231 | yylval.str = new string(yyleng, yytext); | |
232 | RETURN(CustomEncoding); | |
233 | } | |
970ed795 EL |
234 | } |
235 | ||
236 | {IDENTIFIER} { | |
237 | yylval.id = new Identifier(Identifier::ID_TTCN, string(yyleng, yytext)); | |
238 | RETURN(IDentifier); | |
239 | } | |
240 | ||
241 | {NUMBER} { | |
242 | yylval.number = atoi(yytext); | |
243 | RETURN(Number); | |
244 | } | |
245 | ||
246 | ||
247 | "->" RETURN(RedirectSymbol); | |
248 | ||
249 | \( { | |
250 | switch (last_token) { | |
251 | case PrototypeKeyword: | |
252 | PUSH_STATE(SC_prototype); | |
253 | break; | |
254 | case EncodeKeyword: | |
255 | case DecodeKeyword: | |
256 | PUSH_STATE(SC_encodingtype); | |
257 | break; | |
258 | case ErrorBehaviorKeyword: | |
259 | PUSH_STATE(SC_errorbehavior); | |
260 | break; | |
261 | case InKeyword: | |
262 | case OutKeyword: | |
263 | PUSH_STATE(SC_typemappinglist); | |
264 | break; | |
265 | case FunctionKeyword: | |
266 | PUSH_STATE(SC_functionmapping); | |
267 | break; | |
268 | case PrintingKeyword: | |
269 | PUSH_STATE(SC_printing); | |
270 | break; | |
271 | default: | |
272 | PUSH_STATE(YY_START); /* Push the current state (duplicate) */ | |
273 | break; | |
274 | } | |
275 | if (YY_START == SC_encodingoptions) { | |
276 | yylval.str = new string(yyleng, yytext); | |
277 | RETURN(EncodingOption); | |
278 | } else { | |
279 | RETURN('('); | |
280 | } | |
281 | } | |
282 | ||
283 | \) { | |
284 | if (stack_size > 0) { | |
285 | yy_pop_state(); | |
286 | stack_size--; | |
287 | } | |
288 | if (YY_START == SC_encodingoptions) { | |
289 | yylval.str = new string(yyleng, yytext); | |
290 | RETURN(EncodingOption); | |
291 | } else { | |
292 | if (YY_START == SC_user) BEGIN(SC_start); | |
293 | RETURN(')'); | |
294 | } | |
295 | } | |
296 | ||
297 | : { | |
298 | switch (YY_START) /* current start condition is... */ { | |
299 | case SC_encodingtype: /* BER | RAW | ... */ | |
300 | BEGIN(SC_encodingoptions); | |
301 | break; | |
302 | case SC_typemappinglist: | |
303 | BEGIN(SC_mappingtype); | |
304 | break; | |
305 | } | |
306 | RETURN(':'); | |
307 | } | |
308 | ||
309 | \,|\; { | |
310 | if (YY_START == SC_mappingtype) BEGIN(SC_typemappinglist); | |
311 | RETURN(*yytext); | |
312 | } | |
313 | ||
314 | [-.<>/] RETURN(*yytext); | |
315 | ||
316 | <*>{ | |
317 | . { | |
318 | fill_location(); | |
319 | Location loc(coding_attrib_infile, yylloc); | |
320 | int c = (unsigned char)yytext[0]; | |
321 | loc.error("Character `%c' (0x%02X) cannot be used in extension attribute", | |
322 | isprint(c) ? c : '?', c); | |
323 | } | |
324 | <<EOF>> { | |
325 | if (YY_START == SC_blockcomment) { | |
326 | Location loc(coding_attrib_infile, start_line, start_column, | |
327 | current_line, current_column); | |
328 | loc.error("Unterminated block comment"); | |
329 | } | |
330 | /* we must set the fake length 1 in order to report the single column number | |
331 | * of the unexpected EOF in error messages */ | |
332 | yyleng = 1; | |
333 | RETURN(EOF); | |
334 | } | |
335 | } | |
336 | ||
337 | %% | |
338 | ||
339 | void init_coding_attrib_lex(/*char definition_type,*/ const AttributeSpec& attrib) | |
340 | { | |
341 | if (stack_size > 0) | |
342 | FATAL_ERROR("init_coding_attrib_lex(): stack is not empty"); | |
343 | coding_attrib_infile = attrib.get_filename(); | |
344 | current_line = attrib.get_first_line(); | |
345 | /* skip the leading " of the attribute value */ | |
346 | current_column = attrib.get_first_column() + 1; | |
347 | const string& s = attrib.get_spec(); | |
348 | yy_scan_bytes(s.c_str(), s.size()); | |
349 | BEGIN(SC_start); | |
350 | } | |
351 | ||
352 | void cleanup_coding_attrib_lex() | |
353 | { | |
354 | while (stack_size > 0) { | |
355 | yy_pop_state(); | |
356 | stack_size--; | |
357 | } | |
358 | coding_attrib_lex_destroy(); | |
359 | } |