LibreOffice Module unoidl (master) 1
sourceprovider-scanner.l
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
9
10%option bison-bridge
11%option bison-locations
12%option extra-type="unoidl::detail::SourceProviderScannerData *"
13%option never-interactive
14%option nounistd
15%option noyywrap
16%option noinput
17%option nounput
18%option reentrant
19%option warn
20%option yylineno
21
22%top {
23
24#include "sal/config.h"
25
26#include <algorithm>
27#include <cassert>
28#include <cstddef>
29#include <cstring>
30
31}
32
33%{
34
35#include <rtl/math.h>
36#include <rtl/string.hxx>
37#include <rtl/ustring.hxx>
38#include <rtl/textenc.h>
39#include <sal/types.h>
40#include <unoidl/unoidl.hxx>
41
43#include <sourceprovider-parser.hxx>
45
46namespace unoidl::detail {
47
48static std::size_t sourceProviderScannerInput(
49 SourceProviderScannerData * data, char * buffer, std::size_t size)
50{
51 assert(data != nullptr);
52 if (data->sourcePosition == data->sourceEnd) {
53 return YY_NULL;
54 }
55 assert(data->sourcePosition < data->sourceEnd);
56 size = std::min<std::size_t>(size, data->sourceEnd - data->sourcePosition);
57 std::memcpy(buffer, data->sourcePosition, size);
58 data->sourcePosition += size;
59 return size;
60}
61
62}
63
64#define YY_INPUT(buf, result, max_size) ((result) = \
65 ::unoidl::detail::sourceProviderScannerInput(yyextra, (buf), (max_size)))
66
67namespace {
68
69int nonZeroIntegerLiteral(
70 char const * text, std::size_t length, sal_Int16 radix, sal_uInt64 * value,
72{
73 assert(text != nullptr);
74 assert(length != 0);
75 assert(value != nullptr);
76 assert(data != nullptr);
77 std::size_t n = length;
78 switch (text[length - 1]) {
79 case 'L':
80 case 'U':
81 case 'l':
82 case 'u':
83 --n;
84 break;
85 default:
86 break;
87 }
88 *value = OString(text, n).toUInt64(radix);
89 if (*value == 0) {
90 data->errorMessage = "out-of-range integer literal "
91 + OUString(text, length, RTL_TEXTENCODING_ASCII_US);
92 return TOK_ERROR;
93 }
94 return TOK_INTEGER;
95}
96
97}
98
Any value
sal_Int64 n
#define YY_NULL
def text(shape, orig_st)
size
static std::size_t sourceProviderScannerInput(SourceProviderScannerData *data, char *buffer, std::size_t size)
99%}
100
101%x comment1 comment2 doc docdepr
102
103DIGIT [0-9]
104UPPER [A-Z]
105LOWER [a-z]
106ALPHA {UPPER}|{LOWER}
107ALNUM {DIGIT}|{ALPHA}
108
110
111[ \t\r]
112\n *yylloc = yylineno;
113
114"//" BEGIN comment1;
BEGIN
115"#" BEGIN comment1; //TODO: only at start of line
116<comment1>.
117<comment1>\n *yylloc = yylineno; BEGIN INITIAL;
#define INITIAL
118
119"/*" BEGIN comment2;
120"/**" BEGIN doc;
121"/***" BEGIN comment2;
122
123<comment2,doc>"*/" BEGIN INITIAL;
124<docdepr>"*/" BEGIN INITIAL; return TOK_DEPRECATED;
125
126<comment2,docdepr>.
127<comment2,doc,docdepr>\n *yylloc = yylineno;
128<comment2,doc,docdepr><<EOF>> {
129 yyextra->errorMessage = "unterminated comment";
130 return TOK_ERROR;
131}
132
133<doc>[ \t\r]
134<doc>"@deprecated" BEGIN docdepr;
135<doc>"*"
136<doc>[^ \t\r\n*]+
137
138[%&()*+,\-/:;<=>[\]^{|}~] return yytext[0];
139
140"..." return TOK_ELLIPSIS;
141"::" return TOK_COLONS;
142"<<" return TOK_LEFTSHIFT;
143">>" return TOK_RIGHTSHIFT;
144
145"FALSE" return TOK_FALSE;
146"False" return TOK_FALSE;
147"TRUE" return TOK_TRUE;
148"True" return TOK_TRUE;
149"any" return TOK_ANY;
150"attribute" return TOK_ATTRIBUTE;
151"boolean" return TOK_BOOLEAN;
152"bound" return TOK_BOUND;
153"byte" return TOK_BYTE;
154"char" return TOK_CHAR;
155"const" return TOK_CONST;
156"constants" return TOK_CONSTANTS;
157"constrained" return TOK_CONSTRAINED;
158"double" return TOK_DOUBLE;
159"enum" return TOK_ENUM;
160"exception" return TOK_EXCEPTION;
161"float" return TOK_FLOAT;
162"get" return TOK_GET;
163"hyper" return TOK_HYPER;
164"in" return TOK_IN;
165"inout" return TOK_INOUT;
166"interface" return TOK_INTERFACE;
167"long" return TOK_LONG;
168"maybeambiguous" return TOK_MAYBEAMBIGUOUS;
169"maybedefault" return TOK_MAYBEDEFAULT;
170"maybevoid" return TOK_MAYBEVOID;
171"module" return TOK_MODULE;
172"optional" return TOK_OPTIONAL;
173"out" return TOK_OUT;
174"property" return TOK_PROPERTY;
175"published" return TOK_PUBLISHED;
176"raises" return TOK_RAISES;
177"readonly" return TOK_READONLY;
178"removable" return TOK_REMOVABLE;
179"sequence" return TOK_SEQUENCE;
180"service" return TOK_SERVICE;
181"set" return TOK_SET;
182"short" return TOK_SHORT;
183"singleton" return TOK_SINGLETON;
184"string" return TOK_STRING;
185"struct" return TOK_STRUCT;
186"transient" return TOK_TRANSIENT;
187"type" return TOK_TYPE;
188"typedef" return TOK_TYPEDEF;
189"unsigned" return TOK_UNSIGNED;
190"void" return TOK_VOID;
191
192{UPPER}("_"?{ALNUM})*|{LOWER}{ALNUM}* {
193 yylval->sval = new OString(yytext);
194 return TOK_IDENTIFIER;
195}
YYSTYPE yylval
196
197({ALPHA}|"_")({ALNUM}|"_")* {
198 yyextra->errorMessage = "illegal identifier "
199 + OUString(yytext, yyleng, RTL_TEXTENCODING_ASCII_US);
200 return TOK_ERROR;
201}
202
2030+[LUlu]? |
2040[Xx]0+[LUlu]? {
205 yylval->ival = 0;
206 return TOK_INTEGER;
207}
208
2090[0-7]+[LUlu]? {
210 return nonZeroIntegerLiteral(yytext, yyleng, 8, &yylval->ival, yyextra);
211}
212
213[1-9]{DIGIT}*[LUlu]? {
214 return nonZeroIntegerLiteral(yytext, yyleng, 10, &yylval->ival, yyextra);
215}
216
2170[Xx][0-9A-Fa-f]+[LUlu]? {
218 return nonZeroIntegerLiteral(
219 yytext + 2, yyleng - 2, 16, &yylval->ival, yyextra);
220}
221
222{DIGIT}+[Ee][+\-]?{DIGIT}+[Ff]? |
223{DIGIT}*"."{DIGIT}+([Ee][+\-]?{DIGIT}+)?[Ff]? {
224 rtl_math_ConversionStatus s;
225 yylval->fval = rtl_math_stringToDouble(
226 yytext, yytext + yyleng, '.', 0, &s, nullptr);
227 if (s == rtl_math_ConversionStatus_OutOfRange) {
228 yyextra->errorMessage = "out-of-range floating-point literal "
229 + OUString(yytext, yyleng, RTL_TEXTENCODING_ASCII_US);
230 return TOK_ERROR;
231 }
232 return TOK_FLOATING;
233}
234
235{DIGIT}({ALNUM}|"_")* {
236 yyextra->errorMessage = "illegal numeric literal "
237 + OUString(yytext, yyleng, RTL_TEXTENCODING_ASCII_US);
238 return TOK_ERROR;
239}
240
241. {
242 char c = yytext[0];
243 yyextra->errorMessage = c >= ' ' && c <= '~'
244 ? OUString("invalid character \"" + OUStringChar(c) + "\"")
245 : OUString(
246 "invalid byte x"
247 + OUString::number(static_cast<unsigned char>(c), 16).toAsciiUpperCase());
248 return TOK_ERROR;
249}
250
251%%
252
253/* vim:set shiftwidth=4 softtabstop=4 expandtab: */