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