Sync with 5.3.0
[deliverable/titan.core.git] / compiler2 / ttcn3 / charstring_la.l
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 %option prefix="charstring_"
12
13 %{
14 // Scanner to transform string literals from external representation
15 // to internal representation.
16
17 #include "../../common/dbgnew.hh"
18 #include "../error.h"
19 #include "../string.hh"
20 #include "../Setting.hh"
21 #include "../CompilerError.hh"
22
23 using namespace Common;
24
25 #define INITIAL_BUFFER_SIZE 32
26
27 static void add_char(char*& string_ptr, size_t& string_len,
28 size_t& string_size, char c)
29 {
30 if (string_size <= string_len) {
31 string_size *= 2;
32 string_ptr = (char*)Realloc(string_ptr, string_size);
33 }
34 string_ptr[string_len++] = c;
35 }
36
37 #define ADD_CHAR(c) add_char(string_ptr, string_len, string_size, c)
38
39 #define YY_DECL static string *yylex(const char *current_file, \
40 int current_line, int current_column)
41
42 %}
43
44 NEWLINE \r|\n|\r\n
45 HEXDIGIT [0-9A-Fa-f]
46
47 %%
48 char *string_ptr = (char*)Malloc(INITIAL_BUFFER_SIZE);
49 size_t string_len = 0, string_size = INITIAL_BUFFER_SIZE;
50
51 /* Two consecutive doublequotes -> one doublequotequote */
52 ["]["] ADD_CHAR('"'); current_column += 2;
53
54 /* Backslash-escaped singlequote, doublequote, question mark or backslash */
55 \\[''""?\\] ADD_CHAR(yytext[1]); current_column += 2;
56
57 /* C-style backslash-escapes */
58 \\a ADD_CHAR('\a'); current_column += 2;
59 \\b ADD_CHAR('\b'); current_column += 2;
60 \\f ADD_CHAR('\f'); current_column += 2;
61 \\n ADD_CHAR('\n'); current_column += 2;
62 \\r ADD_CHAR('\r'); current_column += 2;
63 \\t ADD_CHAR('\t'); current_column += 2;
64 \\v ADD_CHAR('\v'); current_column += 2;
65
66 \\[0-7]{1,3} {
67 /* octal notation */
68 if (yyleng == 4 && yytext[1] > '3') {
69 Location loc(current_file, current_line, current_column, current_line,
70 current_column + 4);
71 loc.error("Invalid octal character code: `%s'", yytext);
72 ADD_CHAR('\377');
73 } else {
74 char c = yytext[1] - '0';
75 if (yyleng >= 3) c = c * 8 + yytext[2] - '0';
76 if (yyleng == 4) c = c * 8 + yytext[3] - '0';
77 ADD_CHAR(c);
78 }
79 current_column += yyleng;
80 }
81
82 \\x{HEXDIGIT}{1,2} {
83 /* hexadecimal notation */
84 char c;
85 if (yytext[2] >= 'A' && yytext[2] <= 'F') c = yytext[2] - 'A' + 10;
86 else if (yytext[2] >= 'a' && yytext[2] <= 'f') c = yytext[2] - 'a' + 10;
87 else c = yytext[2] - '0';
88 if (yyleng == 4) {
89 if (yytext[3] >= 'A' && yytext[3] <= 'F')
90 c = c * 16 + yytext[3] - 'A' + 10;
91 else if (yytext[3] >= 'a' && yytext[3] <= 'f')
92 c = c * 16 + yytext[3] - 'a' + 10;
93 else c = c * 16 + yytext[3] - '0';
94 }
95 ADD_CHAR(c);
96 current_column += yyleng;
97 }
98
99 \\{NEWLINE} {
100 /* escaped newline character */
101 current_line++;
102 current_column = 0;
103 }
104
105 \\[][dsw()|^*#+-] { /* '-' is non-special as last character, ']' as first */
106 /* temporary hack: these escape sequences are handled transparently
107 as they can appear in the second argument of regexp().
108 In effect, they are re-escaped (both backslash and the next char survive),
109 saving the user from having to double-escape them.
110 Unfortunately, we don't know yet whether this string is being used
111 as an argument to regexp(), so we can't suppress the warning. */
112 Location loc(current_file, current_line, current_column, current_line,
113 current_column + yyleng);
114 loc.warning("Unknown escape sequence `%s' was treated literally", yytext);
115 for (int i = 0; i < yyleng; i++) ADD_CHAR(yytext[i]);
116 current_column += 2;
117 }
118
119 \\(x[^\\""]|.) {
120 Location loc(current_file, current_line, current_column, current_line,
121 current_column + yyleng);
122 loc.error("Invalid escape sequence: `%s'", yytext);
123 current_column += yyleng;
124 }
125
126 {NEWLINE} {
127 Location loc(current_file, current_line, current_column, current_line + 1, 0);
128 loc.warning("Unescaped newline character");
129 for (int i = 0; i < yyleng; i++) ADD_CHAR(yytext[i]);
130 current_line++;
131 current_column = 0;
132 }
133
134 [""\\] FATAL_ERROR("charstring_lex(): invalid single `%s'", yytext);
135
136 . ADD_CHAR(yytext[0]); current_column++;
137
138 <<EOF>> {
139 string *ret_val = new string(string_len, string_ptr);
140 Free(string_ptr);
141 return ret_val;
142 }
143
144 %%
145
146 string *parse_charstring_value(const char *str, const Location& loc)
147 {
148 Error_Context cntxt(&loc, "In charstring value");
149 struct yy_buffer_state *flex_buffer = charstring__scan_string(str);
150 if (!flex_buffer) {
151 FATAL_ERROR("parse_charstring_value(): flex buffer creation failed");
152 return 0;
153 }
154 string *ret_val = yylex(loc.get_filename(), loc.get_first_line(),
155 loc.get_first_column() + 1);
156 charstring_lex_destroy();
157 return ret_val;
158 }
This page took 0.035005 seconds and 5 git commands to generate.