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 | * Forstner, Matyas | |
13 | * Raduly, Csaba | |
14 | * Szabados, Kristof | |
15 | * Szabo, Janos Zoltan – initial implementation | |
16 | * Szalai, Gabor | |
17 | * Zalanyi, Balazs Andor | |
18 | * | |
970ed795 EL |
19 | ******************************************************************************/ |
20 | %option noyywrap | |
21 | %option never-interactive | |
22 | %option nounput | |
23 | ||
24 | %{ | |
25 | ||
26 | #include "../../common/memory.h" | |
27 | #include "../Int.hh" | |
28 | #include "../Real.hh" | |
29 | #include "../Setting.hh" | |
30 | #include "../Value.hh" | |
31 | #include "../main.hh" | |
32 | #include "RawAST.hh" | |
33 | #include "../XerAttributes.hh" | |
34 | #include "rawASTspec.h" | |
35 | // the next one is the header generated from the .y | |
36 | #include "rawAST.tab.hh" | |
37 | #include "AST_ttcn3.hh" | |
38 | #include "Attributes.hh" | |
39 | #include "BerAST.hh" | |
40 | ||
41 | using namespace Common; | |
42 | ||
43 | #define ALLOCATE_IF_NULL(retv, oldptr, ptype) \ | |
44 | if((oldptr)==NULL){\ | |
45 | retv = (ptype*)Malloc(sizeof(ptype)); \ | |
46 | } else \ | |
47 | retv = oldptr; | |
48 | ||
49 | const Common::Module *mymod; | |
50 | RawAST *rawstruct; | |
51 | TextAST *textstruct; | |
52 | XerAttributes *xerstruct; | |
53 | BerAST *berstruct; | |
54 | JsonAST *jsonstruct; | |
55 | bool raw_f; | |
56 | bool text_f; | |
57 | bool xer_f; | |
58 | bool ber_f; | |
59 | bool json_f; | |
60 | int length_multiplier; | |
61 | ||
62 | extern void rawAST_error(const char *str); /* defined in this file */ | |
63 | extern int rawAST_parse(); /* in rawAST.tab.cc, generated from rawAST.y */ | |
64 | ||
65 | //rawAST_full_spec rawAST_result; | |
66 | //rawAST_encoding_spec rawAST_partial_result; | |
67 | ||
68 | extern int rawAST_debug; | |
69 | ||
70 | #define yylval rawAST_lval | |
71 | #define yylloc rawAST_lloc | |
72 | ||
73 | extern YYLTYPE yylloc; | |
74 | ||
75 | /* always points to the first character of the regexp to be recognized */ | |
76 | static int current_line, current_column; | |
77 | ||
78 | static void update_lloc() | |
79 | { | |
80 | yylloc.first_line = current_line; | |
81 | yylloc.first_column = current_column; | |
82 | current_column += yyleng; | |
83 | yylloc.last_line = current_line; | |
84 | yylloc.last_column = current_column; | |
85 | } | |
86 | ||
87 | #define RETURN(retv) update_lloc(); return retv | |
88 | ||
89 | %} | |
90 | ||
91 | /* definitions */ | |
92 | ||
93 | LINECOMMENT "//"[^\r\n]* | |
94 | WHITESPACE [ \t\v\f]+ | |
95 | NEWLINE \r|\n|\r\n | |
96 | ||
97 | BIN 0|1 | |
98 | HEX [0-9A-Fa-f] | |
99 | OCT {HEX}{HEX} | |
100 | FLOAT ({NUMBER}\.[0-9]+)|((({NUMBER}(\.[0-9]+)?)|(\.[0-9]+))[Ee][+-]?{NUMBER}) | |
101 | NUMBER 0|([1-9][0-9]*) | |
102 | IDENTIFIER [A-Za-z][A-Za-z0-9_]* | |
103 | DQUOTE (\"|\\)\" | |
104 | CHAR [^\"\\]|\\[^\"]|{DQUOTE}{DQUOTE} | |
105 | MATCH_CHAR [^'\\]|"''"|\\(.|\n) | |
106 | RPAREN [)] | |
107 | ||
108 | /* start conditions (x: exclusive) */ | |
109 | ||
110 | %x ccomment | |
111 | %x textcodec | |
112 | %x rawcodec | |
113 | %x jsoncodec | |
114 | %x jsonvalue | |
115 | ||
116 | %% | |
117 | int comment_caller = INITIAL; | |
118 | ||
119 | <INITIAL,textcodec,rawcodec>{ /* all but ccomment */ | |
120 | "/*" { | |
121 | yylloc.first_line = current_line; | |
122 | yylloc.first_column = current_column; | |
123 | current_column += yyleng; | |
124 | comment_caller = YY_START; | |
125 | BEGIN(ccomment); | |
126 | } | |
127 | ||
128 | {WHITESPACE}|{LINECOMMENT} current_column += yyleng; | |
129 | ||
130 | } /* end <all but ccomment> */ | |
131 | ||
132 | <*>{NEWLINE} current_line++; current_column = 0; | |
133 | ||
134 | <ccomment>{ | |
135 | "*/" current_column += yyleng; BEGIN(comment_caller); | |
136 | . current_column++; | |
137 | <<EOF>> { | |
138 | yylloc.last_line = current_line; | |
139 | yylloc.last_column = current_column; | |
140 | Location loc(infile, yylloc); | |
141 | loc.error("Unterminated block comment in variant attribute"); | |
142 | RETURN(EOF); | |
143 | } | |
144 | } /* ccomment end */ | |
145 | ||
146 | <INITIAL,textcodec,rawcodec>{NUMBER} { | |
147 | update_lloc(); | |
148 | Location loc(infile, yylloc); | |
149 | yylval.intval = string2Int(yytext, loc); | |
150 | return XNumber; | |
151 | } | |
152 | ||
153 | <rawcodec,INITIAL>{ | |
154 | ||
155 | {FLOAT} { | |
156 | update_lloc(); | |
157 | Location loc(infile, yylloc); | |
158 | yylval.floatval = string2Real(yytext, loc); | |
159 | return XFloatValue; | |
160 | } | |
161 | true { yylval.boolval = true; | |
162 | RETURN(XBooleanConst);} | |
163 | false { yylval.boolval = false; | |
164 | RETURN(XBooleanConst);} | |
165 | none { yylval.verdictval = Value::Verdict_NONE; | |
166 | RETURN(XVerdictConst);} | |
167 | pass { yylval.verdictval = Value::Verdict_PASS; | |
168 | RETURN(XVerdictConst);} | |
169 | inconc { yylval.verdictval = Value::Verdict_INCONC; | |
170 | RETURN(XVerdictConst);} | |
171 | fail { yylval.verdictval = Value::Verdict_FAIL; | |
172 | RETURN(XVerdictConst);} | |
173 | error { yylval.verdictval = Value::Verdict_ERROR; | |
174 | RETURN(XVerdictConst);} | |
175 | null RETURN(XNullKeyword); | |
176 | NULL RETURN(XNULLKeyword); | |
177 | omit RETURN(XOmitKeyword); | |
178 | ||
179 | {DQUOTE}{CHAR}*{DQUOTE} { | |
180 | yylloc.first_line = current_line; | |
181 | /* we have to cheat because parse_charstring_value() expects one quotation | |
182 | * mark character as delimiter, but {DQUOTE} matches two characters */ | |
183 | yylloc.first_column = current_column + 1; | |
184 | current_column += 2; | |
185 | bool backslash_flag = false; | |
186 | yylval.str = memptystr(); | |
3abe9331 | 187 | for (size_t i = 2; i < yyleng - 2; ) { |
970ed795 EL |
188 | if (!backslash_flag && (yytext[i] == '\\' || yytext[i] == '"') && |
189 | yytext[i + 1] == '"' && | |
190 | (yytext[i + 2] == '\\' || yytext[i + 2] == '"') && | |
191 | yytext[i + 3] == '"') { | |
192 | /* transform embedded escaped quotes: \"\" or """" -> "" */ | |
193 | /* we must use the octal notation to keep the column numbers in synch */ | |
194 | yylval.str = mputstr(yylval.str, "\\042"); | |
195 | current_column += 4; | |
196 | i += 4; | |
197 | } else if (yytext[i] == '\r' && yytext[i + 1] == '\n') { | |
198 | /* handle the CR-LF sequence as a single newline */ | |
199 | yylval.str = mputstr(yylval.str, "\r\n"); | |
200 | current_line++; | |
201 | current_column = 0; | |
202 | backslash_flag = false; | |
203 | i += 2; | |
204 | } else { | |
205 | yylval.str = mputc(yylval.str, yytext[i]); | |
206 | if (yytext[i] == '\r' || yytext[i] == '\n') { | |
207 | current_line++; | |
208 | current_column = 0; | |
209 | } else current_column++; | |
210 | if (backslash_flag) backslash_flag = false; | |
211 | else if (yytext[i] == '\\') backslash_flag = true; | |
212 | i++; | |
213 | } | |
214 | } | |
215 | current_column += 2; | |
216 | yylloc.last_line = current_line; | |
217 | yylloc.last_column = current_column - 1; | |
218 | return XCstring; | |
219 | } | |
220 | ||
221 | '{BIN}*'B { | |
222 | yytext[yyleng - 2] = '\0'; | |
223 | yylval.str = mcopystr(yytext + 1); | |
224 | RETURN(XBstring); | |
225 | } | |
226 | ||
227 | '[^\']*'B { /* a properly delimited bit string with incorrect content */ | |
228 | /* the backslash in the character class is redundant, but helps editors | |
229 | * get the syntax highlighting right */ | |
230 | update_lloc(); | |
231 | rawAST_error("invalid bitstring value"); | |
232 | yylval.str = memptystr(); | |
233 | return XBstring; | |
234 | } | |
235 | ||
236 | '{HEX}*'H { | |
237 | yytext[yyleng - 2] = '\0'; | |
238 | yylval.str = mcopystr(yytext + 1); | |
239 | RETURN(XHstring); | |
240 | } | |
241 | ||
242 | '[^\']*'H { /* a properly delimited hex string with incorrect content */ | |
243 | update_lloc(); | |
244 | rawAST_error("invalid hexstring value"); | |
245 | yylval.str = memptystr(); | |
246 | return XHstring; | |
247 | } | |
248 | ||
249 | '{OCT}*'O { | |
250 | yytext[yyleng - 2] = '\0'; | |
251 | yylval.str = mcopystr(yytext + 1); | |
252 | RETURN(XOstring); | |
253 | } | |
254 | ||
255 | '[^\']*'O { /* a properly delimited octet string with incorrect content */ | |
256 | update_lloc(); | |
257 | rawAST_error("invalid octetstring value"); | |
258 | yylval.str = memptystr(); | |
259 | return XOstring; | |
260 | } | |
261 | ||
262 | ||
263 | '[^\']*' { /* A string delimited by a pair of ' */ | |
264 | yytext[yyleng - 1] = '\0'; | |
265 | yylval.str = mcopystr(yytext + 1); | |
266 | RETURN(Xstring); | |
267 | } | |
268 | ||
269 | } /* end <rawcodec,INITIAL> */ | |
270 | ||
271 | /* RAW encoder keywords */ | |
272 | PADDING { BEGIN(rawcodec); RETURN(XPaddingKeyword); } | |
273 | PREPADDING { BEGIN(rawcodec); RETURN(XPrePaddingKeyword); } | |
274 | PADDING_PATTERN { BEGIN(rawcodec); RETURN(XPaddingPatternKeyword); } | |
275 | PADDALL RETURN(XPaddAllKeyword); | |
276 | FIELDORDER { BEGIN(rawcodec); RETURN(XFieldOrderKeyword); } | |
277 | EXTENSION_BIT { BEGIN(rawcodec); RETURN(XExtensionBitKeyword); } | |
278 | EXTENSION_BIT_GROUP { BEGIN(rawcodec); RETURN(XExtensionBitGroupKeyword); } | |
279 | LENGTHTO { BEGIN(rawcodec); RETURN(XLengthToKeyword); } | |
280 | POINTERTO { BEGIN(rawcodec); RETURN(XPointerToKeyword); } | |
281 | UNIT { BEGIN(rawcodec); RETURN(XUnitKeyword); } | |
282 | PTRUNIT { BEGIN(rawcodec); RETURN(XPtrUnitKeyword); } | |
283 | REPEATABLE { BEGIN(rawcodec); RETURN(XRepeatableKeyword); } | |
284 | PTROFFSET { BEGIN(rawcodec); RETURN(XPtrOffsetKeyword); } | |
285 | LENGTHINDEX { BEGIN(rawcodec); RETURN(XLengthIndexKeyword); } | |
286 | TAG { BEGIN(rawcodec); RETURN(XTagKeyword); } | |
287 | CROSSTAG { BEGIN(rawcodec); RETURN(XCrossTagKeyword); } | |
288 | PRESENCE { BEGIN(rawcodec); RETURN(XPresenceKeyword); } | |
289 | FIELDLENGTH { BEGIN(rawcodec); RETURN(XFieldLengthKeyword); } | |
290 | FORMAT { BEGIN(rawcodec); RETURN(XFieldLengthKeyword); } | |
291 | ALIGN { BEGIN(rawcodec); RETURN(XAlignKeyword); } | |
292 | BYTEORDER { BEGIN(rawcodec); RETURN(XByteOrderKeyword); } | |
293 | COMP { BEGIN(rawcodec); RETURN(XCompKeyword); } | |
294 | BITORDER { BEGIN(rawcodec); RETURN(XBitOrderKeyword); } | |
295 | BITORDERINFIELD { BEGIN(rawcodec); RETURN(XBitOrderInFieldKeyword); } | |
296 | BITORDERINOCTET { BEGIN(rawcodec); RETURN(XBitOrderInOctetKeyword); } | |
297 | HEXORDER { BEGIN(rawcodec); RETURN(XHexOrderKeyword); } | |
298 | TOPLEVEL { BEGIN(rawcodec); RETURN(XToplevelKeyword); } | |
3abe9331 | 299 | IntX { RETURN(XIntXKeyword); } |
51fa56b9 | 300 | bit { RETURN(XBitKeyword); } |
301 | unsigned { RETURN(XUnsignedKeyword); } | |
970ed795 EL |
302 | |
303 | <rawcodec>{ | |
304 | yes { yylval.enumval = XDEFYES; RETURN(XYes); } | |
305 | no { yylval.enumval = XDEFNO; RETURN(XNo); } | |
306 | reverse { yylval.enumval = XDEFREVERSE; RETURN (XReverse); } | |
307 | msb { yylval.enumval = XDEFMSB; RETURN(XMsb); } | |
308 | lsb { yylval.enumval = XDEFLSB; RETURN(XLsb); } | |
309 | bits { yylval.enumval = 1; RETURN(XBits); } | |
310 | bit { yylval.enumval = 1; RETURN(XBits); } | |
311 | octets { yylval.enumval = 8; RETURN(XOctets); } | |
312 | octet { yylval.enumval = 8; RETURN(XOctets); } | |
313 | nibble { yylval.enumval = 4; RETURN(XOctets); } | |
314 | word16 { yylval.enumval = 16; RETURN(XOctets); } | |
315 | dword32 { yylval.enumval = 32; RETURN(XOctets); } | |
316 | elements { yylval.enumval = -1; RETURN(XOctets); } | |
317 | variable { yylval.intval = 0; RETURN(XNumber);} | |
318 | IEEE754[ ]double { yylval.intval = 64; RETURN(XNumber);} | |
319 | IEEE754[ ]float { yylval.intval = 32; RETURN(XNumber);} | |
320 | left { yylval.enumval = XDEFLEFT; RETURN(XLeft); } | |
321 | right { yylval.enumval = XDEFRIGHT; RETURN(XRight); } | |
322 | nosign { yylval.enumval = XDEFUNSIGNED; RETURN(XUnsigned); } | |
323 | 2scompl { yylval.enumval = XDEFCOMPL; RETURN(XCompl); } | |
324 | signbit { yylval.enumval = XDEFSIGNBIT; RETURN(XSignbit); } | |
325 | first { yylval.enumval = XDEFFIRST; RETURN(XFirst); } | |
326 | last { yylval.enumval = XDEFLAST; RETURN(XLast); } | |
327 | low { yylval.enumval = XDEFLOW; RETURN(XLow); } | |
328 | high { yylval.enumval = XDEFHIGH; RETURN(XHigh); } | |
329 | OTHERWISE RETURN(XOtherwise); | |
330 | ||
331 | {RPAREN} {BEGIN(INITIAL);RETURN(*yytext);} | |
332 | ||
333 | } /* end <rawcodec> */ | |
334 | ||
335 | /* TEXT codec starters */ | |
336 | BEGIN { BEGIN(textcodec);RETURN(XBeginKeyword);} | |
337 | END { BEGIN(textcodec);RETURN(XEndKeyword);} | |
338 | SEPARATOR { BEGIN(textcodec);RETURN(XSeparatorKeyword);} | |
339 | TEXT_CODING { BEGIN(textcodec);RETURN(XCodingKeyword); } | |
340 | ||
341 | <INITIAL>{ | |
342 | ||
343 | /* XER attributes are not as well delimited like TEXT/RAW, | |
344 | * so no start condition for them (it would be difficult to determine | |
345 | * when to return to INITIAL) */ | |
346 | ||
347 | /* First, the "starter" attributes */ | |
51fa56b9 | 348 | abstract RETURN(XKWabstract); |
970ed795 EL |
349 | anyAttributes RETURN(XKWanyAttributes); |
350 | anyElement RETURN(XKWanyElement); | |
351 | attribute RETURN(XKWattribute); | |
352 | attributeFormQualified RETURN(XKWattributeFormQualified); | |
51fa56b9 | 353 | block RETURN(XKWblock); |
970ed795 EL |
354 | controlNamespace RETURN(XKWcontrolNamespace); |
355 | defaultForEmpty RETURN(XKWdefaultForEmpty); | |
356 | element RETURN(XKWelement); | |
357 | elementFormQualified RETURN(XKWelementFormQualified); | |
358 | embedValues RETURN(XKWembedValues); | |
359 | form RETURN(XKWform); | |
360 | list RETURN(XKWlist); | |
361 | name RETURN(XKWname); | |
362 | namespace RETURN(XKWnamespace); | |
363 | /* pi-or-comment */ | |
364 | text RETURN(XKWtext); | |
365 | untagged RETURN(XKWuntagged); | |
366 | useNil RETURN(XKWuseNil); | |
367 | useNumber RETURN(XKWuseNumber); | |
368 | useOrder RETURN(XKWuseOrder); | |
369 | useType RETURN(XKWuseType); | |
370 | useUnion RETURN(XKWuseUnion); | |
371 | whiteSpace RETURN(XKWwhiteSpace); | |
372 | XSD RETURN(XSD); | |
373 | ||
374 | as RETURN(XKWas); | |
375 | all RETURN(XKWall); | |
376 | in RETURN(XKWin); | |
377 | /* name mangling */ | |
378 | capitalized RETURN(XKWcapitalized); | |
379 | uncapitalized RETURN(XKWuncapitalized); | |
380 | lowercased RETURN(XKWlowercased); | |
381 | uppercased RETURN(XKWuppercased); | |
382 | ||
383 | qualified RETURN(XKWqualified); | |
384 | unqualified RETURN(XKWunqualified); /* ASN uses ABSENT */ | |
385 | except RETURN(XKWexcept); | |
386 | from RETURN(XKWfrom); | |
387 | prefix RETURN(XKWprefix); | |
388 | /* whitespace actions */ | |
389 | preserve RETURN(XKWpreserve); | |
390 | collapse RETURN(XKWcollapse); | |
391 | replace RETURN(XKWreplace); | |
392 | ||
393 | /* XSD:something */ | |
394 | string RETURN(XSDstring); | |
395 | normalizedString RETURN(XSDnormalizedString); | |
396 | token RETURN(XSDtoken); | |
397 | Name RETURN(XSDName); | |
398 | NMTOKEN RETURN(XSDNMTOKEN); | |
399 | NCName RETURN(XSDNCName); | |
400 | ID RETURN(XSDID); | |
401 | IDREF RETURN(XSDIDREF); | |
402 | ENTITY RETURN(XSDENTITY); | |
403 | hexBinary RETURN(XSDhexBinary); | |
404 | base64Binary RETURN(XSDbase64Binary); | |
405 | anyURI RETURN(XSDanyURI); | |
406 | language RETURN(XSDlanguage); | |
407 | integer RETURN(XSDinteger); | |
408 | positiveInteger RETURN(XSDpositiveInteger); | |
409 | nonPositiveInteger RETURN(XSDnonPositiveInteger); | |
410 | negativeInteger RETURN(XSDnegativeInteger); | |
411 | nonNegativeInteger RETURN(XSDnonNegativeInteger); | |
412 | /* already taken by BER: long RETURN(XSDlong);*/ | |
413 | unsignedLong RETURN(XSDunsignedLong); | |
414 | int RETURN(XSDint); | |
415 | unsignedInt RETURN(XSDunsignedInt); | |
416 | /* already taken by BER: short RETURN(XSDshort);*/ | |
417 | unsignedShort RETURN(XSDunsignedShort); | |
418 | byte RETURN(XSDbyte); | |
419 | unsignedByte RETURN(XSDunsignedByte); | |
420 | decimal RETURN(XSDdecimal); | |
421 | float RETURN(XSDfloat); | |
422 | double RETURN(XSDdouble); | |
423 | duration RETURN(XSDduration); | |
424 | dateTime RETURN(XSDdateTime); | |
425 | time RETURN(XSDtime); | |
426 | date RETURN(XSDdate); | |
427 | gYearMonth RETURN(XSDgYearMonth); | |
428 | gYear RETURN(XSDgYear); | |
429 | gMonthDay RETURN(XSDgMonthDay); | |
430 | gDay RETURN(XSDgDay); | |
431 | gMonth RETURN(XSDgMonth); | |
432 | NMTOKENS RETURN(XSDNMTOKENS); | |
433 | IDREFS RETURN(XSDIDREFS); | |
434 | ENTITIES RETURN(XSDENTITIES); | |
435 | QName RETURN(XSDQName); | |
436 | boolean RETURN(XSDboolean); | |
437 | ||
438 | anySimpleType RETURN(XSDanySimpleType); | |
439 | anyType RETURN(XSDanyType); | |
440 | ||
441 | } /* end XER keywords in INITIAL */ | |
442 | ||
443 | ||
444 | JSON { BEGIN(jsoncodec); RETURN(XKWjson); } | |
445 | ||
446 | <jsoncodec>{ | |
447 | [: \t] RETURN(*yytext); | |
448 | omit RETURN(XKWomit); | |
449 | as RETURN(XKWas); | |
450 | null RETURN(XKWnull); | |
451 | name RETURN(XKWname); | |
452 | value RETURN(XKWvalue); | |
453 | default RETURN(XKWdefault); | |
3abe9331 | 454 | extend RETURN(XKWextend); |
455 | metainfo RETURN(XKWmetainfo); | |
456 | for RETURN(XKWfor); | |
457 | unbound RETURN(XKWunbound); | |
970ed795 EL |
458 | [(] { BEGIN(jsonvalue); RETURN(XJsonValueStart); } |
459 | {IDENTIFIER} { yylval.str = mcopystr(yytext); RETURN(XAliasToken); } | |
460 | [^: \t] { rawAST_error("invalid JSON token"); } | |
461 | } | |
462 | ||
463 | <jsonvalue>{ | |
3abe9331 | 464 | [\\][\\][)] { /* \\) -> \) would not work with the other rules */ |
465 | yylval.str = mcopystr("\\)"); | |
466 | RETURN(XJsonValueSegment); | |
467 | } | |
468 | [\\]. { /* \) -> ), all others are treated literally */ | |
970ed795 EL |
469 | if (yytext[1] == ')') yylval.str = mcopystr(")"); |
470 | else yylval.str = mcopystr(yytext); | |
3abe9331 | 471 | RETURN(XJsonValueSegment); |
970ed795 EL |
472 | } |
473 | [)] { BEGIN(jsoncodec); RETURN(XJsonValueEnd); } | |
474 | [\"][\"] { yylval.str = mcopystr("\\\""); RETURN(XJsonValueSegment); } | |
475 | [^\"\\)]+ { yylval.str = mcopystr(yytext); RETURN(XJsonValueSegment); } | |
476 | } | |
477 | ||
478 | <INITIAL>{ | |
479 | length RETURN(XKWlength); | |
480 | accept RETURN(XKWaccept); | |
481 | long RETURN(XKWlong); | |
482 | short RETURN(XKWshort); | |
483 | indefinite RETURN(XKWindefinite); | |
484 | definite RETURN(XKWdefinite); | |
485 | } | |
486 | ||
487 | <textcodec>{ | |
488 | \'{MATCH_CHAR}*\' { | |
489 | yylloc.first_line = current_line; | |
490 | yylloc.first_column = current_column; | |
491 | current_column++; | |
492 | bool backslash_flag = false; | |
493 | yylval.str = memptystr(); | |
3abe9331 | 494 | for (size_t i = 1; i < yyleng - 1; ) { |
970ed795 EL |
495 | if (!backslash_flag && (yytext[i] == '\'' || yytext[i] == '"') && |
496 | yytext[i + 1] == yytext[i]) { | |
497 | /* transform '' -> \' and "" -> \" */ | |
498 | yylval.str = mputc(yylval.str, '\\'); | |
499 | yylval.str = mputc(yylval.str, yytext[i]); | |
500 | current_column += 2; | |
501 | i += 2; | |
502 | } else if (yytext[i] == '\r' && yytext[i + 1] == '\n') { | |
503 | /* handle the CR-LF sequence as a single newline */ | |
504 | yylval.str = mputstr(yylval.str, "\r\n"); | |
505 | current_line++; | |
506 | current_column = 0; | |
507 | backslash_flag = false; | |
508 | i += 2; | |
509 | } else { | |
510 | yylval.str = mputc(yylval.str, yytext[i]); | |
511 | if (yytext[i] == '\r' || yytext[i] == '\n') { | |
512 | current_line++; | |
513 | current_column = 0; | |
514 | } else current_column++; | |
515 | if (backslash_flag) backslash_flag = false; | |
516 | else if (yytext[i] == '\\') backslash_flag = true; | |
517 | i++; | |
518 | } | |
519 | } | |
520 | current_column++; | |
521 | yylloc.last_line = current_line; | |
522 | yylloc.last_column = current_column; | |
523 | return Xtoken; | |
524 | } | |
525 | ||
526 | length RETURN(XLengthToken); | |
527 | repeatable RETURN(XRepeatToken); | |
528 | convert RETURN(XConvertToken); | |
529 | lower_case RETURN(XLowerToken); | |
530 | upper_case RETURN(XUpperToken); | |
531 | just RETURN(XJustToken); | |
532 | left RETURN(XLeftToken); | |
533 | right RETURN(XRightToken); | |
534 | center RETURN(XCenterToken); | |
535 | leading0 RETURN(XLeadingToken); | |
536 | true RETURN(XTrueToken); | |
537 | false RETURN(XFalseToken); | |
538 | case_sensitive RETURN(XSensitivToken); | |
539 | case_insensitive RETURN(XInSensitivToken); | |
540 | {RPAREN} {BEGIN(INITIAL);RETURN(*yytext);} | |
541 | } /* end <textcodec> */ | |
542 | ||
543 | <INITIAL,textcodec,rawcodec>{ | |
544 | {IDENTIFIER} { | |
545 | yylval.identifier = new Identifier(Identifier::ID_TTCN, | |
546 | string(yyleng, yytext)); | |
547 | RETURN(XIdentifier); | |
548 | } | |
549 | . RETURN(*yytext); | |
550 | <<EOF>> { | |
551 | /* we must set the fake length 1 in order to report the single column | |
552 | * number of the unexpected EOF in error messages */ | |
553 | yyleng = 1; | |
554 | RETURN(EOF); | |
555 | } | |
556 | } | |
557 | ||
558 | %% | |
559 | ||
560 | void free_rawAST_field_list(rawAST_field_list *ptr) | |
561 | { | |
562 | if (ptr != NULL) { | |
563 | for (int i = 0; i < ptr->nElements; i++) delete ptr->names[i]; | |
564 | Free(ptr->names); | |
565 | Free(ptr); | |
566 | } | |
567 | } | |
568 | ||
569 | rawAST_single_tag* | |
570 | link_rawAST_single_tag(rawAST_single_tag* dst, rawAST_single_tag* src){ | |
571 | rawAST_single_tag* retv; | |
572 | if (src==NULL) return NULL; | |
573 | if (dst == src) return dst; | |
574 | // if (dst!=NULL) free_rawAST_single_tag(dst); | |
575 | ALLOCATE_IF_NULL(retv, dst, rawAST_single_tag); | |
576 | retv->fieldName=src->fieldName; | |
577 | retv->nElements=src->nElements; | |
578 | retv->keyList=src->keyList; | |
579 | return retv; | |
580 | } | |
581 | ||
582 | void | |
583 | free_rawAST_single_tag(rawAST_single_tag* spec){ | |
584 | int i; | |
585 | if(spec->fieldName) delete spec->fieldName; | |
586 | for (i=0; i<spec->nElements; i++) { | |
587 | free_rawAST_tag_field_value(&spec->keyList[i]); | |
588 | } | |
589 | if(spec->nElements) Free(spec->keyList); | |
590 | // init_rawAST_single_tag(spec); | |
591 | } | |
592 | ||
593 | void | |
594 | free_rawAST_tag_field_value(rawAST_tag_field_value* spec){ | |
595 | free_rawAST_field_list(spec->keyField); | |
596 | Free(spec->value); | |
597 | delete spec->v_value; | |
598 | // init_rawAST_tag_field_value(spec); | |
599 | } | |
600 | ||
601 | rawAST_tag_field_value* | |
602 | link_rawAST_tag_field_value(rawAST_tag_field_value* dst, rawAST_tag_field_value* src){ | |
603 | rawAST_tag_field_value* retv; | |
604 | if (src==NULL) return NULL; | |
605 | if (dst == src) return dst; | |
606 | ALLOCATE_IF_NULL(retv, dst, rawAST_tag_field_value); | |
607 | retv->keyField = src->keyField; | |
608 | retv->value = src->value; | |
609 | retv->v_value = src->v_value; | |
610 | return retv; | |
611 | } | |
612 | ||
613 | rawAST_tag_list* | |
614 | link_rawAST_tag_list(rawAST_tag_list* dst, rawAST_tag_list* src){ | |
615 | rawAST_tag_list* retv; | |
616 | if (src==NULL) return NULL; | |
617 | if (dst == src) return dst; | |
618 | ALLOCATE_IF_NULL(retv, dst, rawAST_tag_list); | |
619 | retv->nElements=src->nElements; | |
620 | retv->tag=src->tag; | |
621 | return retv; | |
622 | } | |
623 | ||
624 | rawAST_tag_field_value* | |
625 | init_rawAST_tag_field_value(rawAST_tag_field_value* spec){ | |
626 | rawAST_tag_field_value* retv; | |
627 | ALLOCATE_IF_NULL(retv, spec, rawAST_tag_field_value); | |
628 | retv->keyField=NULL; | |
629 | retv->value=NULL; | |
630 | retv->v_value=NULL; | |
631 | return retv; | |
632 | } | |
633 | ||
634 | void free_rawAST_tag_list(rawAST_tag_list* spec){ | |
635 | int i; | |
636 | if (spec==NULL) return; | |
637 | for (i=0; i<spec->nElements; i++) { | |
638 | free_rawAST_single_tag(&spec->tag[i]); | |
639 | } | |
640 | Free(spec->tag); | |
641 | // init_rawAST_tag_list(spec); | |
642 | } | |
643 | ||
644 | /* See RawAST.hh */ | |
645 | int parse_rawAST(RawAST *par, TextAST *textpar, XerAttributes *xerpar, | |
646 | BerAST* berpar, JsonAST* jsonpar, const Ttcn::AttributeSpec& attrib, | |
647 | int l_multip, const Common::Module* mod, bool &raw_found, bool &text_found, | |
648 | bool &xer_found, bool &ber_found, bool &json_found) | |
649 | { | |
650 | rawstruct=par; | |
651 | textstruct=textpar; | |
652 | xerstruct = xerpar; | |
653 | berstruct = berpar; | |
654 | jsonstruct = jsonpar; | |
655 | ||
656 | length_multiplier=l_multip; | |
657 | infile = attrib.get_filename(); | |
658 | current_line = attrib.get_first_line(); | |
659 | /* skip the leading " of the attribute value */ | |
660 | current_column = attrib.get_first_column() + 1; | |
661 | mymod=mod; | |
662 | raw_f =false; | |
663 | text_f=false; | |
664 | xer_f =false; | |
665 | ber_f =false; | |
666 | json_f = false; | |
667 | const string& s = attrib.get_spec(); | |
668 | #ifndef NDEBUG | |
669 | if (rawAST_debug) { | |
670 | fprintf(stderr, "*** raw=[%s]\n", s.c_str()); | |
671 | } | |
672 | #endif | |
673 | struct yy_buffer_state *flex_buffer = yy_scan_bytes(s.c_str(), s.size()); | |
674 | if (!flex_buffer) { | |
675 | FATAL_ERROR("parse_rawAST(): flex buffer creation failed"); | |
676 | } | |
677 | BEGIN(INITIAL); | |
678 | int retn=rawAST_parse(); | |
679 | yylex_destroy(); | |
680 | if(!raw_found) raw_found=raw_f || (!text_f && !xer_f && !ber_f && !json_f); | |
681 | // if none found, pretend some RAW attribute was found | |
682 | if(!text_found) text_found=text_f; | |
683 | if(!xer_found) xer_found=xer_f; | |
684 | if(!ber_found) ber_found=ber_f; | |
685 | if (!json_found) json_found = json_f; | |
686 | ||
687 | return retn; | |
688 | } | |
689 | ||
690 | void rawAST_error(const char *str) | |
691 | { | |
692 | Location loc(infile, yylloc); | |
693 | if (*yytext) { | |
694 | // the most recently parsed token is known | |
feade998 | 695 | if (warnings_for_bad_variants) { |
696 | loc.warning("in variant attribute, at or before token `%s': %s", yytext, str); | |
697 | } else { | |
698 | loc.error("in variant attribute, at or before token `%s': %s", yytext, str); | |
699 | } | |
970ed795 EL |
700 | } else { |
701 | // the most recently parsed token is unknown | |
feade998 | 702 | if (warnings_for_bad_variants) { |
703 | loc.warning("in variant attribute: %s", str); | |
704 | } else { | |
705 | loc.error("in variant attribute: %s", str); | |
706 | } | |
970ed795 EL |
707 | } |
708 | } | |
709 | ||
710 | /* | |
711 | Local Variables: | |
712 | mode: C | |
713 | indent-tabs-mode: nil | |
714 | c-basic-offset: 4 | |
715 | End: | |
716 | */ |