summaryrefslogtreecommitdiffstats
path: root/unoidl/source/sourceprovider-scanner.l
diff options
context:
space:
mode:
Diffstat (limited to 'unoidl/source/sourceprovider-scanner.l')
-rw-r--r--unoidl/source/sourceprovider-scanner.l253
1 files changed, 253 insertions, 0 deletions
diff --git a/unoidl/source/sourceprovider-scanner.l b/unoidl/source/sourceprovider-scanner.l
new file mode 100644
index 000000000..bdedfcffc
--- /dev/null
+++ b/unoidl/source/sourceprovider-scanner.l
@@ -0,0 +1,253 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+%option bison-bridge
+%option bison-locations
+%option extra-type="unoidl::detail::SourceProviderScannerData *"
+%option never-interactive
+%option nounistd
+%option noyywrap
+%option noinput
+%option nounput
+%option reentrant
+%option warn
+%option yylineno
+
+%top {
+
+#include "sal/config.h"
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstring>
+
+}
+
+%{
+
+#include <rtl/math.h>
+#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
+#include <rtl/textenc.h>
+#include <sal/types.h>
+#include <unoidl/unoidl.hxx>
+
+#include "sourceprovider-parser-requires.hxx"
+#include <sourceprovider-parser.hxx>
+#include "sourceprovider-scanner.hxx"
+
+namespace unoidl::detail {
+
+static std::size_t sourceProviderScannerInput(
+ SourceProviderScannerData * data, char * buffer, std::size_t size)
+{
+ assert(data != nullptr);
+ if (data->sourcePosition == data->sourceEnd) {
+ return YY_NULL;
+ }
+ assert(data->sourcePosition < data->sourceEnd);
+ size = std::min<std::size_t>(size, data->sourceEnd - data->sourcePosition);
+ std::memcpy(buffer, data->sourcePosition, size);
+ data->sourcePosition += size;
+ return size;
+}
+
+}
+
+#define YY_INPUT(buf, result, max_size) ((result) = \
+ ::unoidl::detail::sourceProviderScannerInput(yyextra, (buf), (max_size)))
+
+namespace {
+
+int nonZeroIntegerLiteral(
+ char const * text, std::size_t length, sal_Int16 radix, sal_uInt64 * value,
+ unoidl::detail::SourceProviderScannerData * data)
+{
+ assert(text != nullptr);
+ assert(length != 0);
+ assert(value != nullptr);
+ assert(data != nullptr);
+ std::size_t n = length;
+ switch (text[length - 1]) {
+ case 'L':
+ case 'U':
+ case 'l':
+ case 'u':
+ --n;
+ break;
+ default:
+ break;
+ }
+ *value = OString(text, n).toUInt64(radix);
+ if (*value == 0) {
+ data->errorMessage = "out-of-range integer literal "
+ + OUString(text, length, RTL_TEXTENCODING_ASCII_US);
+ return TOK_ERROR;
+ }
+ return TOK_INTEGER;
+}
+
+}
+
+%}
+
+%x comment1 comment2 doc docdepr
+
+DIGIT [0-9]
+UPPER [A-Z]
+LOWER [a-z]
+ALPHA {UPPER}|{LOWER}
+ALNUM {DIGIT}|{ALPHA}
+
+%%
+
+[ \t\r]
+\n *yylloc = yylineno;
+
+"//" BEGIN comment1;
+"#" BEGIN comment1; //TODO: only at start of line
+<comment1>.
+<comment1>\n *yylloc = yylineno; BEGIN INITIAL;
+
+"/*" BEGIN comment2;
+"/**" BEGIN doc;
+"/***" BEGIN comment2;
+
+<comment2,doc>"*/" BEGIN INITIAL;
+<docdepr>"*/" BEGIN INITIAL; return TOK_DEPRECATED;
+
+<comment2,docdepr>.
+<comment2,doc,docdepr>\n *yylloc = yylineno;
+<comment2,doc,docdepr><<EOF>> {
+ yyextra->errorMessage = "unterminated comment";
+ return TOK_ERROR;
+}
+
+<doc>[ \t\r]
+<doc>"@deprecated" BEGIN docdepr;
+<doc>"*"
+<doc>[^ \t\r\n*]+
+
+[%&()*+,\-/:;<=>[\]^{|}~] return yytext[0];
+
+"..." return TOK_ELLIPSIS;
+"::" return TOK_COLONS;
+"<<" return TOK_LEFTSHIFT;
+">>" return TOK_RIGHTSHIFT;
+
+"FALSE" return TOK_FALSE;
+"False" return TOK_FALSE;
+"TRUE" return TOK_TRUE;
+"True" return TOK_TRUE;
+"any" return TOK_ANY;
+"attribute" return TOK_ATTRIBUTE;
+"boolean" return TOK_BOOLEAN;
+"bound" return TOK_BOUND;
+"byte" return TOK_BYTE;
+"char" return TOK_CHAR;
+"const" return TOK_CONST;
+"constants" return TOK_CONSTANTS;
+"constrained" return TOK_CONSTRAINED;
+"double" return TOK_DOUBLE;
+"enum" return TOK_ENUM;
+"exception" return TOK_EXCEPTION;
+"float" return TOK_FLOAT;
+"get" return TOK_GET;
+"hyper" return TOK_HYPER;
+"in" return TOK_IN;
+"inout" return TOK_INOUT;
+"interface" return TOK_INTERFACE;
+"long" return TOK_LONG;
+"maybeambiguous" return TOK_MAYBEAMBIGUOUS;
+"maybedefault" return TOK_MAYBEDEFAULT;
+"maybevoid" return TOK_MAYBEVOID;
+"module" return TOK_MODULE;
+"optional" return TOK_OPTIONAL;
+"out" return TOK_OUT;
+"property" return TOK_PROPERTY;
+"published" return TOK_PUBLISHED;
+"raises" return TOK_RAISES;
+"readonly" return TOK_READONLY;
+"removable" return TOK_REMOVABLE;
+"sequence" return TOK_SEQUENCE;
+"service" return TOK_SERVICE;
+"set" return TOK_SET;
+"short" return TOK_SHORT;
+"singleton" return TOK_SINGLETON;
+"string" return TOK_STRING;
+"struct" return TOK_STRUCT;
+"transient" return TOK_TRANSIENT;
+"type" return TOK_TYPE;
+"typedef" return TOK_TYPEDEF;
+"unsigned" return TOK_UNSIGNED;
+"void" return TOK_VOID;
+
+{UPPER}("_"?{ALNUM})*|{LOWER}{ALNUM}* {
+ yylval->sval = new OString(yytext);
+ return TOK_IDENTIFIER;
+}
+
+({ALPHA}|"_")({ALNUM}|"_")* {
+ yyextra->errorMessage = "illegal identifier "
+ + OUString(yytext, yyleng, RTL_TEXTENCODING_ASCII_US);
+ return TOK_ERROR;
+}
+
+0+[LUlu]? |
+0[Xx]0+[LUlu]? {
+ yylval->ival = 0;
+ return TOK_INTEGER;
+}
+
+0[0-7]+[LUlu]? {
+ return nonZeroIntegerLiteral(yytext, yyleng, 8, &yylval->ival, yyextra);
+}
+
+[1-9]{DIGIT}*[LUlu]? {
+ return nonZeroIntegerLiteral(yytext, yyleng, 10, &yylval->ival, yyextra);
+}
+
+0[Xx][0-9A-Fa-f]+[LUlu]? {
+ return nonZeroIntegerLiteral(
+ yytext + 2, yyleng - 2, 16, &yylval->ival, yyextra);
+}
+
+{DIGIT}+[Ee][+\-]?{DIGIT}+[Ff]? |
+{DIGIT}*"."{DIGIT}+([Ee][+\-]?{DIGIT}+)?[Ff]? {
+ rtl_math_ConversionStatus s;
+ yylval->fval = rtl_math_stringToDouble(
+ yytext, yytext + yyleng, '.', 0, &s, nullptr);
+ if (s == rtl_math_ConversionStatus_OutOfRange) {
+ yyextra->errorMessage = "out-of-range floating-point literal "
+ + OUString(yytext, yyleng, RTL_TEXTENCODING_ASCII_US);
+ return TOK_ERROR;
+ }
+ return TOK_FLOATING;
+}
+
+{DIGIT}({ALNUM}|"_")* {
+ yyextra->errorMessage = "illegal numeric literal "
+ + OUString(yytext, yyleng, RTL_TEXTENCODING_ASCII_US);
+ return TOK_ERROR;
+}
+
+. {
+ char c = yytext[0];
+ yyextra->errorMessage = c >= ' ' && c <= '~'
+ ? OUString("invalid character \"" + OUStringChar(c) + "\"")
+ : OUString(
+ "invalid byte x"
+ + OUString::number(static_cast<unsigned char>(c), 16).toAsciiUpperCase());
+ return TOK_ERROR;
+}
+
+%%
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */