Commit | Line | Data |
---|---|---|
970ed795 EL |
1 | /****************************************************************************** |
2 | * Copyright (c) 2000-2014 Ericsson Telecom AB | |
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(); | |
175 | for (int i = 2; i < yyleng - 2; ) { | |
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); } | |
287 | ||
288 | <rawcodec>{ | |
289 | yes { yylval.enumval = XDEFYES; RETURN(XYes); } | |
290 | no { yylval.enumval = XDEFNO; RETURN(XNo); } | |
291 | reverse { yylval.enumval = XDEFREVERSE; RETURN (XReverse); } | |
292 | msb { yylval.enumval = XDEFMSB; RETURN(XMsb); } | |
293 | lsb { yylval.enumval = XDEFLSB; RETURN(XLsb); } | |
294 | bits { yylval.enumval = 1; RETURN(XBits); } | |
295 | bit { yylval.enumval = 1; RETURN(XBits); } | |
296 | octets { yylval.enumval = 8; RETURN(XOctets); } | |
297 | octet { yylval.enumval = 8; RETURN(XOctets); } | |
298 | nibble { yylval.enumval = 4; RETURN(XOctets); } | |
299 | word16 { yylval.enumval = 16; RETURN(XOctets); } | |
300 | dword32 { yylval.enumval = 32; RETURN(XOctets); } | |
301 | elements { yylval.enumval = -1; RETURN(XOctets); } | |
302 | variable { yylval.intval = 0; RETURN(XNumber);} | |
303 | IEEE754[ ]double { yylval.intval = 64; RETURN(XNumber);} | |
304 | IEEE754[ ]float { yylval.intval = 32; RETURN(XNumber);} | |
305 | left { yylval.enumval = XDEFLEFT; RETURN(XLeft); } | |
306 | right { yylval.enumval = XDEFRIGHT; RETURN(XRight); } | |
307 | nosign { yylval.enumval = XDEFUNSIGNED; RETURN(XUnsigned); } | |
308 | 2scompl { yylval.enumval = XDEFCOMPL; RETURN(XCompl); } | |
309 | signbit { yylval.enumval = XDEFSIGNBIT; RETURN(XSignbit); } | |
310 | first { yylval.enumval = XDEFFIRST; RETURN(XFirst); } | |
311 | last { yylval.enumval = XDEFLAST; RETURN(XLast); } | |
312 | low { yylval.enumval = XDEFLOW; RETURN(XLow); } | |
313 | high { yylval.enumval = XDEFHIGH; RETURN(XHigh); } | |
314 | OTHERWISE RETURN(XOtherwise); | |
315 | ||
316 | {RPAREN} {BEGIN(INITIAL);RETURN(*yytext);} | |
317 | ||
318 | } /* end <rawcodec> */ | |
319 | ||
320 | /* TEXT codec starters */ | |
321 | BEGIN { BEGIN(textcodec);RETURN(XBeginKeyword);} | |
322 | END { BEGIN(textcodec);RETURN(XEndKeyword);} | |
323 | SEPARATOR { BEGIN(textcodec);RETURN(XSeparatorKeyword);} | |
324 | TEXT_CODING { BEGIN(textcodec);RETURN(XCodingKeyword); } | |
325 | ||
326 | <INITIAL>{ | |
327 | ||
328 | /* XER attributes are not as well delimited like TEXT/RAW, | |
329 | * so no start condition for them (it would be difficult to determine | |
330 | * when to return to INITIAL) */ | |
331 | ||
332 | /* First, the "starter" attributes */ | |
333 | anyAttributes RETURN(XKWanyAttributes); | |
334 | anyElement RETURN(XKWanyElement); | |
335 | attribute RETURN(XKWattribute); | |
336 | attributeFormQualified RETURN(XKWattributeFormQualified); | |
337 | controlNamespace RETURN(XKWcontrolNamespace); | |
338 | defaultForEmpty RETURN(XKWdefaultForEmpty); | |
339 | element RETURN(XKWelement); | |
340 | elementFormQualified RETURN(XKWelementFormQualified); | |
341 | embedValues RETURN(XKWembedValues); | |
342 | form RETURN(XKWform); | |
343 | list RETURN(XKWlist); | |
344 | name RETURN(XKWname); | |
345 | namespace RETURN(XKWnamespace); | |
346 | /* pi-or-comment */ | |
347 | text RETURN(XKWtext); | |
348 | untagged RETURN(XKWuntagged); | |
349 | useNil RETURN(XKWuseNil); | |
350 | useNumber RETURN(XKWuseNumber); | |
351 | useOrder RETURN(XKWuseOrder); | |
352 | useType RETURN(XKWuseType); | |
353 | useUnion RETURN(XKWuseUnion); | |
354 | whiteSpace RETURN(XKWwhiteSpace); | |
355 | XSD RETURN(XSD); | |
356 | ||
357 | as RETURN(XKWas); | |
358 | all RETURN(XKWall); | |
359 | in RETURN(XKWin); | |
360 | /* name mangling */ | |
361 | capitalized RETURN(XKWcapitalized); | |
362 | uncapitalized RETURN(XKWuncapitalized); | |
363 | lowercased RETURN(XKWlowercased); | |
364 | uppercased RETURN(XKWuppercased); | |
365 | ||
366 | qualified RETURN(XKWqualified); | |
367 | unqualified RETURN(XKWunqualified); /* ASN uses ABSENT */ | |
368 | except RETURN(XKWexcept); | |
369 | from RETURN(XKWfrom); | |
370 | prefix RETURN(XKWprefix); | |
371 | /* whitespace actions */ | |
372 | preserve RETURN(XKWpreserve); | |
373 | collapse RETURN(XKWcollapse); | |
374 | replace RETURN(XKWreplace); | |
375 | ||
376 | /* XSD:something */ | |
377 | string RETURN(XSDstring); | |
378 | normalizedString RETURN(XSDnormalizedString); | |
379 | token RETURN(XSDtoken); | |
380 | Name RETURN(XSDName); | |
381 | NMTOKEN RETURN(XSDNMTOKEN); | |
382 | NCName RETURN(XSDNCName); | |
383 | ID RETURN(XSDID); | |
384 | IDREF RETURN(XSDIDREF); | |
385 | ENTITY RETURN(XSDENTITY); | |
386 | hexBinary RETURN(XSDhexBinary); | |
387 | base64Binary RETURN(XSDbase64Binary); | |
388 | anyURI RETURN(XSDanyURI); | |
389 | language RETURN(XSDlanguage); | |
390 | integer RETURN(XSDinteger); | |
391 | positiveInteger RETURN(XSDpositiveInteger); | |
392 | nonPositiveInteger RETURN(XSDnonPositiveInteger); | |
393 | negativeInteger RETURN(XSDnegativeInteger); | |
394 | nonNegativeInteger RETURN(XSDnonNegativeInteger); | |
395 | /* already taken by BER: long RETURN(XSDlong);*/ | |
396 | unsignedLong RETURN(XSDunsignedLong); | |
397 | int RETURN(XSDint); | |
398 | unsignedInt RETURN(XSDunsignedInt); | |
399 | /* already taken by BER: short RETURN(XSDshort);*/ | |
400 | unsignedShort RETURN(XSDunsignedShort); | |
401 | byte RETURN(XSDbyte); | |
402 | unsignedByte RETURN(XSDunsignedByte); | |
403 | decimal RETURN(XSDdecimal); | |
404 | float RETURN(XSDfloat); | |
405 | double RETURN(XSDdouble); | |
406 | duration RETURN(XSDduration); | |
407 | dateTime RETURN(XSDdateTime); | |
408 | time RETURN(XSDtime); | |
409 | date RETURN(XSDdate); | |
410 | gYearMonth RETURN(XSDgYearMonth); | |
411 | gYear RETURN(XSDgYear); | |
412 | gMonthDay RETURN(XSDgMonthDay); | |
413 | gDay RETURN(XSDgDay); | |
414 | gMonth RETURN(XSDgMonth); | |
415 | NMTOKENS RETURN(XSDNMTOKENS); | |
416 | IDREFS RETURN(XSDIDREFS); | |
417 | ENTITIES RETURN(XSDENTITIES); | |
418 | QName RETURN(XSDQName); | |
419 | boolean RETURN(XSDboolean); | |
420 | ||
421 | anySimpleType RETURN(XSDanySimpleType); | |
422 | anyType RETURN(XSDanyType); | |
423 | ||
424 | } /* end XER keywords in INITIAL */ | |
425 | ||
426 | ||
427 | JSON { BEGIN(jsoncodec); RETURN(XKWjson); } | |
428 | ||
429 | <jsoncodec>{ | |
430 | [: \t] RETURN(*yytext); | |
431 | omit RETURN(XKWomit); | |
432 | as RETURN(XKWas); | |
433 | null RETURN(XKWnull); | |
434 | name RETURN(XKWname); | |
435 | value RETURN(XKWvalue); | |
436 | default RETURN(XKWdefault); | |
437 | [(] { BEGIN(jsonvalue); RETURN(XJsonValueStart); } | |
438 | {IDENTIFIER} { yylval.str = mcopystr(yytext); RETURN(XAliasToken); } | |
439 | [^: \t] { rawAST_error("invalid JSON token"); } | |
440 | } | |
441 | ||
442 | <jsonvalue>{ | |
443 | [\\]. { | |
444 | if (yytext[1] == ')') yylval.str = mcopystr(")"); | |
445 | else yylval.str = mcopystr(yytext); | |
446 | RETURN(XJsonValueSegment); | |
447 | } | |
448 | [)] { BEGIN(jsoncodec); RETURN(XJsonValueEnd); } | |
449 | [\"][\"] { yylval.str = mcopystr("\\\""); RETURN(XJsonValueSegment); } | |
450 | [^\"\\)]+ { yylval.str = mcopystr(yytext); RETURN(XJsonValueSegment); } | |
451 | } | |
452 | ||
453 | <INITIAL>{ | |
454 | length RETURN(XKWlength); | |
455 | accept RETURN(XKWaccept); | |
456 | long RETURN(XKWlong); | |
457 | short RETURN(XKWshort); | |
458 | indefinite RETURN(XKWindefinite); | |
459 | definite RETURN(XKWdefinite); | |
460 | } | |
461 | ||
462 | <textcodec>{ | |
463 | \'{MATCH_CHAR}*\' { | |
464 | yylloc.first_line = current_line; | |
465 | yylloc.first_column = current_column; | |
466 | current_column++; | |
467 | bool backslash_flag = false; | |
468 | yylval.str = memptystr(); | |
469 | for (int i = 1; i < yyleng - 1; ) { | |
470 | if (!backslash_flag && (yytext[i] == '\'' || yytext[i] == '"') && | |
471 | yytext[i + 1] == yytext[i]) { | |
472 | /* transform '' -> \' and "" -> \" */ | |
473 | yylval.str = mputc(yylval.str, '\\'); | |
474 | yylval.str = mputc(yylval.str, yytext[i]); | |
475 | current_column += 2; | |
476 | i += 2; | |
477 | } else if (yytext[i] == '\r' && yytext[i + 1] == '\n') { | |
478 | /* handle the CR-LF sequence as a single newline */ | |
479 | yylval.str = mputstr(yylval.str, "\r\n"); | |
480 | current_line++; | |
481 | current_column = 0; | |
482 | backslash_flag = false; | |
483 | i += 2; | |
484 | } else { | |
485 | yylval.str = mputc(yylval.str, yytext[i]); | |
486 | if (yytext[i] == '\r' || yytext[i] == '\n') { | |
487 | current_line++; | |
488 | current_column = 0; | |
489 | } else current_column++; | |
490 | if (backslash_flag) backslash_flag = false; | |
491 | else if (yytext[i] == '\\') backslash_flag = true; | |
492 | i++; | |
493 | } | |
494 | } | |
495 | current_column++; | |
496 | yylloc.last_line = current_line; | |
497 | yylloc.last_column = current_column; | |
498 | return Xtoken; | |
499 | } | |
500 | ||
501 | length RETURN(XLengthToken); | |
502 | repeatable RETURN(XRepeatToken); | |
503 | convert RETURN(XConvertToken); | |
504 | lower_case RETURN(XLowerToken); | |
505 | upper_case RETURN(XUpperToken); | |
506 | just RETURN(XJustToken); | |
507 | left RETURN(XLeftToken); | |
508 | right RETURN(XRightToken); | |
509 | center RETURN(XCenterToken); | |
510 | leading0 RETURN(XLeadingToken); | |
511 | true RETURN(XTrueToken); | |
512 | false RETURN(XFalseToken); | |
513 | case_sensitive RETURN(XSensitivToken); | |
514 | case_insensitive RETURN(XInSensitivToken); | |
515 | {RPAREN} {BEGIN(INITIAL);RETURN(*yytext);} | |
516 | } /* end <textcodec> */ | |
517 | ||
518 | <INITIAL,textcodec,rawcodec>{ | |
519 | {IDENTIFIER} { | |
520 | yylval.identifier = new Identifier(Identifier::ID_TTCN, | |
521 | string(yyleng, yytext)); | |
522 | RETURN(XIdentifier); | |
523 | } | |
524 | . RETURN(*yytext); | |
525 | <<EOF>> { | |
526 | /* we must set the fake length 1 in order to report the single column | |
527 | * number of the unexpected EOF in error messages */ | |
528 | yyleng = 1; | |
529 | RETURN(EOF); | |
530 | } | |
531 | } | |
532 | ||
533 | %% | |
534 | ||
535 | void free_rawAST_field_list(rawAST_field_list *ptr) | |
536 | { | |
537 | if (ptr != NULL) { | |
538 | for (int i = 0; i < ptr->nElements; i++) delete ptr->names[i]; | |
539 | Free(ptr->names); | |
540 | Free(ptr); | |
541 | } | |
542 | } | |
543 | ||
544 | rawAST_single_tag* | |
545 | link_rawAST_single_tag(rawAST_single_tag* dst, rawAST_single_tag* src){ | |
546 | rawAST_single_tag* retv; | |
547 | if (src==NULL) return NULL; | |
548 | if (dst == src) return dst; | |
549 | // if (dst!=NULL) free_rawAST_single_tag(dst); | |
550 | ALLOCATE_IF_NULL(retv, dst, rawAST_single_tag); | |
551 | retv->fieldName=src->fieldName; | |
552 | retv->nElements=src->nElements; | |
553 | retv->keyList=src->keyList; | |
554 | return retv; | |
555 | } | |
556 | ||
557 | void | |
558 | free_rawAST_single_tag(rawAST_single_tag* spec){ | |
559 | int i; | |
560 | if(spec->fieldName) delete spec->fieldName; | |
561 | for (i=0; i<spec->nElements; i++) { | |
562 | free_rawAST_tag_field_value(&spec->keyList[i]); | |
563 | } | |
564 | if(spec->nElements) Free(spec->keyList); | |
565 | // init_rawAST_single_tag(spec); | |
566 | } | |
567 | ||
568 | void | |
569 | free_rawAST_tag_field_value(rawAST_tag_field_value* spec){ | |
570 | free_rawAST_field_list(spec->keyField); | |
571 | Free(spec->value); | |
572 | delete spec->v_value; | |
573 | // init_rawAST_tag_field_value(spec); | |
574 | } | |
575 | ||
576 | rawAST_tag_field_value* | |
577 | link_rawAST_tag_field_value(rawAST_tag_field_value* dst, rawAST_tag_field_value* src){ | |
578 | rawAST_tag_field_value* retv; | |
579 | if (src==NULL) return NULL; | |
580 | if (dst == src) return dst; | |
581 | ALLOCATE_IF_NULL(retv, dst, rawAST_tag_field_value); | |
582 | retv->keyField = src->keyField; | |
583 | retv->value = src->value; | |
584 | retv->v_value = src->v_value; | |
585 | return retv; | |
586 | } | |
587 | ||
588 | rawAST_tag_list* | |
589 | link_rawAST_tag_list(rawAST_tag_list* dst, rawAST_tag_list* src){ | |
590 | rawAST_tag_list* retv; | |
591 | if (src==NULL) return NULL; | |
592 | if (dst == src) return dst; | |
593 | ALLOCATE_IF_NULL(retv, dst, rawAST_tag_list); | |
594 | retv->nElements=src->nElements; | |
595 | retv->tag=src->tag; | |
596 | return retv; | |
597 | } | |
598 | ||
599 | rawAST_tag_field_value* | |
600 | init_rawAST_tag_field_value(rawAST_tag_field_value* spec){ | |
601 | rawAST_tag_field_value* retv; | |
602 | ALLOCATE_IF_NULL(retv, spec, rawAST_tag_field_value); | |
603 | retv->keyField=NULL; | |
604 | retv->value=NULL; | |
605 | retv->v_value=NULL; | |
606 | return retv; | |
607 | } | |
608 | ||
609 | void free_rawAST_tag_list(rawAST_tag_list* spec){ | |
610 | int i; | |
611 | if (spec==NULL) return; | |
612 | for (i=0; i<spec->nElements; i++) { | |
613 | free_rawAST_single_tag(&spec->tag[i]); | |
614 | } | |
615 | Free(spec->tag); | |
616 | // init_rawAST_tag_list(spec); | |
617 | } | |
618 | ||
619 | /* See RawAST.hh */ | |
620 | int parse_rawAST(RawAST *par, TextAST *textpar, XerAttributes *xerpar, | |
621 | BerAST* berpar, JsonAST* jsonpar, const Ttcn::AttributeSpec& attrib, | |
622 | int l_multip, const Common::Module* mod, bool &raw_found, bool &text_found, | |
623 | bool &xer_found, bool &ber_found, bool &json_found) | |
624 | { | |
625 | rawstruct=par; | |
626 | textstruct=textpar; | |
627 | xerstruct = xerpar; | |
628 | berstruct = berpar; | |
629 | jsonstruct = jsonpar; | |
630 | ||
631 | length_multiplier=l_multip; | |
632 | infile = attrib.get_filename(); | |
633 | current_line = attrib.get_first_line(); | |
634 | /* skip the leading " of the attribute value */ | |
635 | current_column = attrib.get_first_column() + 1; | |
636 | mymod=mod; | |
637 | raw_f =false; | |
638 | text_f=false; | |
639 | xer_f =false; | |
640 | ber_f =false; | |
641 | json_f = false; | |
642 | const string& s = attrib.get_spec(); | |
643 | #ifndef NDEBUG | |
644 | if (rawAST_debug) { | |
645 | fprintf(stderr, "*** raw=[%s]\n", s.c_str()); | |
646 | } | |
647 | #endif | |
648 | struct yy_buffer_state *flex_buffer = yy_scan_bytes(s.c_str(), s.size()); | |
649 | if (!flex_buffer) { | |
650 | FATAL_ERROR("parse_rawAST(): flex buffer creation failed"); | |
651 | } | |
652 | BEGIN(INITIAL); | |
653 | int retn=rawAST_parse(); | |
654 | yylex_destroy(); | |
655 | if(!raw_found) raw_found=raw_f || (!text_f && !xer_f && !ber_f && !json_f); | |
656 | // if none found, pretend some RAW attribute was found | |
657 | if(!text_found) text_found=text_f; | |
658 | if(!xer_found) xer_found=xer_f; | |
659 | if(!ber_found) ber_found=ber_f; | |
660 | if (!json_found) json_found = json_f; | |
661 | ||
662 | return retn; | |
663 | } | |
664 | ||
665 | void rawAST_error(const char *str) | |
666 | { | |
667 | Location loc(infile, yylloc); | |
668 | if (*yytext) { | |
669 | // the most recently parsed token is known | |
670 | loc.error("in variant attribute, at or before token `%s': %s", yytext, str); | |
671 | } else { | |
672 | // the most recently parsed token is unknown | |
673 | loc.error("in variant attribute: %s", str); | |
674 | } | |
675 | } | |
676 | ||
677 | /* | |
678 | Local Variables: | |
679 | mode: C | |
680 | indent-tabs-mode: nil | |
681 | c-basic-offset: 4 | |
682 | End: | |
683 | */ |