Sync with 5.1.0
[deliverable/titan.core.git] / compiler2 / ttcn3 / comptype_attrib_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="comptype_attrib_"
12
13 %{
14 #include <ctype.h>
15 #include "../Identifier.hh"
16 #include "../Setting.hh"
17 #include "../CompilerError.hh"
18 #include "Attributes.hh"
19 #include "AST_ttcn3.hh"
20 #include "../CompType.hh"
21
22 extern void parseExtendsCompTypeRefList(Ttcn::AttributeSpec *attrib,
23 Common::CompTypeRefList*& attr_comp_refs);
24
25 /** states of the extension attribute parser */
26 enum extension_attr_parser_state_t {
27 INITIAL_STATE, /**< state at the beginning, valid on return */
28 EXTENDS_STATE, /**< INITIAL_STATE + "extends" or REFID[2]_STATE + "," ,
29 invalid on return */
30 REFID_STATE, /**< EXTENDS_STATE + IDENTIFIER , valid on return */
31 IDDOT_STATE, /**< REFID_STATE + "." , invalid on return */
32 REFID2_STATE /**< IDDOT_STATE + IDENTIFIER , valid on return */
33 };
34
35 #define YY_DECL static int yylex(Common::CompTypeRefList*& attr_comp_refs, \
36 int current_line, int current_column, const char *current_file)
37
38 #define FATAL_ERROR_INVALID_STATE \
39 FATAL_ERROR("comptype_attr.l: invalid parser state");
40
41 #define ERROR_UNEXPECTED_EOF \
42 do { \
43 Common::Location loc(current_file, current_line, current_column, \
44 current_line, current_column+1); \
45 loc.error("Unexpected end of extension attribute"); \
46 } while (0)
47
48 #define ERROR_UNEXPECTED_TOKEN \
49 do { \
50 Common::Location loc(current_file, current_line, current_column, \
51 current_line, current_column+yyleng); \
52 loc.error("Syntax error in extension attribute, unexpected token `%s'", \
53 yytext); \
54 } while (0)
55
56 #define ADD_REFID \
57 do { \
58 if (!id) FATAL_ERROR("ADD_REFID"); \
59 Ttcn::Reference *ref = new Ttcn::Reference(id); \
60 ref->set_location(current_file, id_loc); \
61 if (!attr_comp_refs) attr_comp_refs = new Common::CompTypeRefList(); \
62 attr_comp_refs->add_ref(ref); \
63 id = 0; \
64 } while (0)
65
66 /** return from yylex with cleanup */
67 #define YYLEX_RETURN \
68 do { \
69 if (id) ADD_REFID; \
70 return EOF; \
71 } while (0)
72
73 %}
74
75 WHITESPACE [ \t\v\f]
76 NEWLINE \r|\n|\r\n
77 IDENTIFIER [A-Za-z][A-Za-z0-9_]*
78 LINECOMMENT "//"[^\r\n]*{NEWLINE}
79
80 %x SC_blockcomment
81
82 %%
83 Common::Identifier *id=0;
84 YYLTYPE id_loc;
85 int start_line = 0;
86 int start_column = 0;
87 extension_attr_parser_state_t parser_state = INITIAL_STATE;
88 BEGIN(INITIAL);
89
90 "/*" {
91 start_line = current_line;
92 start_column = current_column;
93 current_column+=yyleng;
94 BEGIN(SC_blockcomment);
95 }
96
97 <SC_blockcomment>
98 {
99 "*/" { current_column+=yyleng; BEGIN(INITIAL); }
100 {NEWLINE} { current_line++; current_column=0; }
101 . current_column++;
102 <<EOF>> {
103 Common::Location loc(current_file, start_line, start_column,
104 current_line, current_column);
105 loc.error("Unterminated block comment in extension attribute");
106 YYLEX_RETURN;
107 }
108 }
109
110 {LINECOMMENT} { current_line++; current_column=0; }
111 {WHITESPACE} current_column+=yyleng;
112 {NEWLINE} { current_line++; current_column=0; }
113
114 "extends" {
115 switch (parser_state) {
116 case INITIAL_STATE:
117 parser_state = EXTENDS_STATE;
118 break;
119 case EXTENDS_STATE:
120 case REFID_STATE:
121 case IDDOT_STATE:
122 case REFID2_STATE:
123 ERROR_UNEXPECTED_TOKEN;
124 break;
125 default:
126 FATAL_ERROR_INVALID_STATE;
127 }
128 current_column+=yyleng;
129 }
130
131 {IDENTIFIER} {
132 switch (parser_state) {
133 case INITIAL_STATE:
134 YYLEX_RETURN;
135 case EXTENDS_STATE:
136 id = new Common::Identifier(Common::Identifier::ID_TTCN, string(yytext));
137 id_loc.first_line = id_loc.last_line = current_line;
138 id_loc.first_column = current_column;
139 id_loc.last_column = current_column + yyleng;
140 parser_state = REFID_STATE;
141 break;
142 case IDDOT_STATE: {
143 Common::Identifier *id2 =
144 new Common::Identifier(Common::Identifier::ID_TTCN, string(yytext));
145 if (!id || !id2) FATAL_ERROR("ADD_REFID2");
146 Ttcn::Reference *ref = new Ttcn::Reference(id, id2);
147 ref->set_location(current_file, id_loc.first_line, id_loc.first_column,
148 current_line, current_column+yyleng);
149 if (!attr_comp_refs) attr_comp_refs = new Common::CompTypeRefList();
150 attr_comp_refs->add_ref(ref);
151 id = 0;
152 parser_state = REFID2_STATE;
153 }
154 break;
155 case REFID_STATE:
156 case REFID2_STATE:
157 ERROR_UNEXPECTED_TOKEN;
158 break;
159 default:
160 FATAL_ERROR_INVALID_STATE;
161 }
162 current_column+=yyleng;
163 }
164
165 \. {
166 switch (parser_state) {
167 case INITIAL_STATE:
168 YYLEX_RETURN;
169 break;
170 case REFID_STATE:
171 parser_state = IDDOT_STATE;
172 break;
173 case EXTENDS_STATE:
174 case IDDOT_STATE:
175 case REFID2_STATE:
176 ERROR_UNEXPECTED_TOKEN;
177 break;
178 default:
179 FATAL_ERROR_INVALID_STATE;
180 }
181 current_column+=yyleng;
182 }
183
184 "," {
185 switch (parser_state) {
186 case INITIAL_STATE:
187 YYLEX_RETURN;
188 break;
189 case REFID_STATE:
190 ADD_REFID;
191 case REFID2_STATE:
192 parser_state = EXTENDS_STATE;
193 break;
194 case EXTENDS_STATE:
195 case IDDOT_STATE:
196 ERROR_UNEXPECTED_TOKEN;
197 break;
198 default:
199 FATAL_ERROR_INVALID_STATE;
200 }
201 current_column+=yyleng;
202 }
203
204 . {
205 int c = (unsigned char)yytext[0];
206 Common::Location loc(current_file, current_line, current_column,
207 current_line, current_column+yyleng);
208 loc.error("Invalid character `%c' (0x%02X) in extension attribute",
209 isprint(c) ? c : '?', c);
210 current_column+=yyleng;
211 }
212
213 <<EOF>> {
214 switch (parser_state) {
215 /* valid return states */
216 case INITIAL_STATE:
217 case REFID_STATE:
218 case REFID2_STATE:
219 break;
220 /* invalid return states */
221 case EXTENDS_STATE:
222 case IDDOT_STATE:
223 ERROR_UNEXPECTED_EOF;
224 break;
225 default:
226 FATAL_ERROR_INVALID_STATE;
227 }
228 YYLEX_RETURN;
229 }
230
231 %%
232
233 void parseExtendsCompTypeRefList(Ttcn::AttributeSpec const& attrib,
234 Common::CompTypeRefList*& attr_comp_refs)
235 {
236 const string& s = attrib.get_spec();
237 struct yy_buffer_state *flex_buffer = yy_scan_bytes(s.c_str(), s.size());
238 if (!flex_buffer)
239 FATAL_ERROR("parseExtendsCompTypeRefList(): flex buffer creation failed");
240 yylex(attr_comp_refs, attrib.get_first_line(),
241 attrib.get_first_column() + 1, attrib.get_filename() );
242 yylex_destroy();
243 }
This page took 0.03529 seconds and 5 git commands to generate.