X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=lib%2Fconfig%2Fconfig_lexer.ll;h=15efe4b1078c96a2c1e40ae5589a09f10355613a;hb=e03e143177178f4d41e36a90e6306785002987c4;hp=28906277c0d66a122d658ef12666182fa3d102b8;hpb=4c04c2665c4418ade3d9af39027fb9c1ec568f11;p=icinga2 diff --git a/lib/config/config_lexer.ll b/lib/config/config_lexer.ll index 28906277c..15efe4b10 100644 --- a/lib/config/config_lexer.ll +++ b/lib/config/config_lexer.ll @@ -1,7 +1,7 @@ %{ /****************************************************************************** * Icinga 2 * - * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) * + * Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * @@ -18,15 +18,17 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * ******************************************************************************/ -#include "config/configcompiler.h" -#include "config/expression.h" -#include "config/typerule.h" -#include "config/configcompilercontext.h" -#include "config/config_parser.h" -#include +#include "config/configcompiler.hpp" +#include "config/typerule.hpp" +#include "config/expression.hpp" using namespace icinga; +#include "config/config_parser.hh" +#include + +#define YYLTYPE icinga::CompilerDebugInfo + #define YY_EXTRA_TYPE ConfigCompiler * #define YY_USER_ACTION \ do { \ @@ -42,82 +44,41 @@ do { \ do { \ result = yyextra->ReadInput(buf, max_size); \ } while (0) - -struct lex_buf { - char *buf; - size_t size; -}; - -static void lb_init(lex_buf *lb) -{ - lb->buf = NULL; - lb->size = 0; -} - -static void lb_cleanup(lex_buf *lb) -{ - free(lb->buf); -} - -static void lb_append_char(lex_buf *lb, char new_char) -{ - const size_t block_size = 64; - - size_t old_blocks = (lb->size + (block_size - 1)) / block_size; - size_t new_blocks = ((lb->size + 1) + (block_size - 1)) / block_size; - - if (old_blocks != new_blocks) { - char *new_buf = (char *)realloc(lb->buf, new_blocks * block_size); - - if (new_buf == NULL && new_blocks > 0) - throw std::bad_alloc(); - - lb->buf = new_buf; - } - - lb->size++; - lb->buf[lb->size - 1] = new_char; -} - -static char *lb_steal(lex_buf *lb) -{ - lb_append_char(lb, '\0'); - - char *buf = lb->buf; - lb->buf = NULL; - lb->size = 0; - return buf; -} %} %option reentrant noyywrap yylineno %option bison-bridge bison-locations %option never-interactive nounistd +%option noinput nounput %x C_COMMENT %x STRING %x HEREDOC %% - lex_buf string_buf; +\" { + yyextra->m_LexBuffer.str(""); + yyextra->m_LexBuffer.clear(); + + yyextra->m_LocationBegin = *yylloc; -\" { lb_init(&string_buf); BEGIN(STRING); } + BEGIN(STRING); + } \" { BEGIN(INITIAL); - lb_append_char(&string_buf, '\0'); + yylloc->FirstLine = yyextra->m_LocationBegin.FirstLine; + yylloc->FirstColumn = yyextra->m_LocationBegin.FirstColumn; - yylval->text = lb_steal(&string_buf); + std::string str = yyextra->m_LexBuffer.str(); + yylval->text = strdup(str.c_str()); return T_STRING; } \n { - std::ostringstream msgbuf; - msgbuf << "Unterminated string found: " << *yylloc; - ConfigCompilerContext::GetContext()->AddError(false, msgbuf.str()); - BEGIN(INITIAL); + BOOST_THROW_EXCEPTION(ScriptError("Unterminated string literal", DebugInfoRange(yyextra->m_LocationBegin, *yylloc))); } \\[0-7]{1,3} { @@ -128,50 +89,62 @@ static char *lb_steal(lex_buf *lb) if (result > 0xff) { /* error, constant is out-of-bounds */ - std::ostringstream msgbuf; - msgbuf << "Constant is out-of-bounds: " << yytext << " " << *yylloc; - ConfigCompilerContext::GetContext()->AddError(false, msgbuf.str()); + BOOST_THROW_EXCEPTION(ScriptError("Constant is out of bounds: " + String(yytext), *yylloc)); } - lb_append_char(&string_buf, result); + yyextra->m_LexBuffer << static_cast(result); } \\[0-9]+ { /* generate error - bad escape sequence; something * like '\48' or '\0777777' */ - std::ostringstream msgbuf; - msgbuf << "Bad escape sequence found: " << yytext << " " << *yylloc; - ConfigCompilerContext::GetContext()->AddError(false, msgbuf.str()); + BOOST_THROW_EXCEPTION(ScriptError("Bad escape sequence found: " + String(yytext), *yylloc)); } -\\n { lb_append_char(&string_buf, '\n'); } -\\t { lb_append_char(&string_buf, '\t'); } -\\r { lb_append_char(&string_buf, '\r'); } -\\b { lb_append_char(&string_buf, '\b'); } -\\f { lb_append_char(&string_buf, '\f'); } -\\(.|\n) { lb_append_char(&string_buf, yytext[1]); } +\\n { yyextra->m_LexBuffer << "\n"; } +\\t { yyextra->m_LexBuffer << "\t"; } +\\r { yyextra->m_LexBuffer << "\r"; } +\\b { yyextra->m_LexBuffer << "\b"; } +\\f { yyextra->m_LexBuffer << "\f"; } +\\\n { yyextra->m_LexBuffer << yytext[1]; } +\\. { + BOOST_THROW_EXCEPTION(ScriptError("Bad escape sequence found: " + String(yytext), *yylloc)); + } [^\\\n\"]+ { char *yptr = yytext; while (*yptr) - lb_append_char(&string_buf, *yptr++); + yyextra->m_LexBuffer << *yptr++; } -\{\{\{ { lb_init(&string_buf); BEGIN(HEREDOC); } +<> { + BOOST_THROW_EXCEPTION(ScriptError("End-of-file while in string literal", DebugInfoRange(yyextra->m_LocationBegin, *yylloc))); + } + +\{\{\{ { + yyextra->m_LexBuffer.str(""); + yyextra->m_LexBuffer.clear(); + + yyextra->m_LocationBegin = *yylloc; + + BEGIN(HEREDOC); + } \}\}\} { BEGIN(INITIAL); - lb_append_char(&string_buf, '\0'); + yylloc->FirstLine = yyextra->m_LocationBegin.FirstLine; + yylloc->FirstColumn = yyextra->m_LocationBegin.FirstColumn; - yylval->text = lb_steal(&string_buf); + std::string str = yyextra->m_LexBuffer.str(); + yylval->text = strdup(str.c_str()); return T_STRING; } -(.|\n) { lb_append_char(&string_buf, yytext[0]); } +(.|\n) { yyextra->m_LexBuffer << yytext[0]; } { "/*" BEGIN(C_COMMENT); @@ -183,45 +156,94 @@ static char *lb_steal(lex_buf *lb) "*" /* ignore star */ } +<> { + BOOST_THROW_EXCEPTION(ScriptError("End-of-file while in comment", *yylloc)); + } + + \/\/[^\n]* /* ignore C++-style comments */ -[ \t\r\n] /* ignore whitespace */ +#[^\n]* /* ignore shell-style comments */ +[ \t] /* ignore whitespace */ { -type return T_TYPE; -dictionary { yylval->type = TypeDictionary; return T_TYPE_DICTIONARY; } -array { yylval->type = TypeArray; return T_TYPE_ARRAY; } -number { yylval->type = TypeNumber; return T_TYPE_NUMBER; } -string { yylval->type = TypeString; return T_TYPE_STRING; } -scalar { yylval->type = TypeScalar; return T_TYPE_SCALAR; } -any { yylval->type = TypeAny; return T_TYPE_ANY; } +%type return T_TYPE; +%dictionary { yylval->type = TypeDictionary; return T_TYPE_DICTIONARY; } +%array { yylval->type = TypeArray; return T_TYPE_ARRAY; } +%number { yylval->type = TypeNumber; return T_TYPE_NUMBER; } +%string { yylval->type = TypeString; return T_TYPE_STRING; } +%scalar { yylval->type = TypeScalar; return T_TYPE_SCALAR; } +%any { yylval->type = TypeAny; return T_TYPE_ANY; } +%name { yylval->type = TypeName; return T_TYPE_NAME; } %validator { return T_VALIDATOR; } %require { return T_REQUIRE; } %attribute { return T_ATTRIBUTE; } -abstract return T_ABSTRACT; -local return T_LOCAL; +%inherits return T_INHERITS; object return T_OBJECT; template return T_TEMPLATE; include return T_INCLUDE; +include_recursive return T_INCLUDE_RECURSIVE; library return T_LIBRARY; -inherits return T_INHERITS; null return T_NULL; -partial return T_PARTIAL; -true { yylval->num = 1; return T_NUMBER; } -false { yylval->num = 0; return T_NUMBER; } -[a-zA-Z_\*][:a-zA-Z0-9\-_\*]* { yylval->text = strdup(yytext); return T_IDENTIFIER; } +true { yylval->boolean = 1; return T_BOOLEAN; } +false { yylval->boolean = 0; return T_BOOLEAN; } +const return T_CONST; +var return T_VAR; +this return T_THIS; +use return T_USE; +apply return T_APPLY; +to return T_TO; +where return T_WHERE; +import return T_IMPORT; +assign return T_ASSIGN; +ignore return T_IGNORE; +function return T_FUNCTION; +return return T_RETURN; +for return T_FOR; +if return T_IF; +else return T_ELSE; +=\> return T_FOLLOWS; +\<\< return T_SHIFT_LEFT; +\>\> return T_SHIFT_RIGHT; +\<= return T_LESS_THAN_OR_EQUAL; +\>= return T_GREATER_THAN_OR_EQUAL; +== return T_EQUAL; +!= return T_NOT_EQUAL; +!in return T_NOT_IN; +in return T_IN; +&& return T_LOGICAL_AND; +\|\| return T_LOGICAL_OR; +[a-zA-Z_][a-zA-Z0-9\_]* { yylval->text = strdup(yytext); return T_IDENTIFIER; } +@[a-zA-Z_][a-zA-Z0-9\_]* { yylval->text = strdup(yytext + 1); return T_IDENTIFIER; } \<[^\>]*\> { yytext[yyleng-1] = '\0'; yylval->text = strdup(yytext + 1); return T_STRING_ANGLE; } --?[0-9]+(\.[0-9]+)?ms { yylval->num = strtod(yytext, NULL) / 1000; return T_NUMBER; } --?[0-9]+(\.[0-9]+)?h { yylval->num = strtod(yytext, NULL) * 60 * 60; return T_NUMBER; } --?[0-9]+(\.[0-9]+)?m { yylval->num = strtod(yytext, NULL) * 60; return T_NUMBER; } --?[0-9]+(\.[0-9]+)?s { yylval->num = strtod(yytext, NULL); return T_NUMBER; } --?[0-9]+(\.[0-9]+)? { yylval->num = strtod(yytext, NULL); return T_NUMBER; } -= { yylval->op = OperatorSet; return T_EQUAL; } -\+= { yylval->op = OperatorPlus; return T_PLUS_EQUAL; } --= { yylval->op = OperatorMinus; return T_MINUS_EQUAL; } -\*= { yylval->op = OperatorMultiply; return T_MULTIPLY_EQUAL; } -\/= { yylval->op = OperatorDivide; return T_DIVIDE_EQUAL; } +[0-9]+(\.[0-9]+)?ms { yylval->num = strtod(yytext, NULL) / 1000; return T_NUMBER; } +[0-9]+(\.[0-9]+)?d { yylval->num = strtod(yytext, NULL) * 60 * 60 * 24; return T_NUMBER; } +[0-9]+(\.[0-9]+)?h { yylval->num = strtod(yytext, NULL) * 60 * 60; return T_NUMBER; } +[0-9]+(\.[0-9]+)?m { yylval->num = strtod(yytext, NULL) * 60; return T_NUMBER; } +[0-9]+(\.[0-9]+)?s { yylval->num = strtod(yytext, NULL); return T_NUMBER; } +[0-9]+(\.[0-9]+)? { yylval->num = strtod(yytext, NULL); return T_NUMBER; } += { yylval->csop = OpSetLiteral; return T_SET; } +\+= { yylval->csop = OpSetAdd; return T_SET_ADD; } +-= { yylval->csop = OpSetSubtract; return T_SET_SUBTRACT; } +\*= { yylval->csop = OpSetMultiply; return T_SET_MULTIPLY; } +\/= { yylval->csop = OpSetDivide; return T_SET_DIVIDE; } +\%= { yylval->csop = OpSetModulo; return T_SET_MODULO; } +\^= { yylval->csop = OpSetXor; return T_SET_XOR; } +\&= { yylval->csop = OpSetBinaryAnd; return T_SET_BINARY_AND; } +\|= { yylval->csop = OpSetBinaryOr; return T_SET_BINARY_OR; } +\+ return T_PLUS; +\- return T_MINUS; +\* return T_MULTIPLY; +\/ return T_DIVIDE_OP; +\% return T_MODULO; +\^ return T_XOR; +\& return T_BINARY_AND; +\| return T_BINARY_OR; +\< return T_LESS_THAN; +\> return T_GREATER_THAN; } +[\r\n]+ { yycolumn -= strlen(yytext) - 1; if (!yyextra->m_IgnoreNewlines) return T_NEWLINE; } +<> { if (!yyextra->m_Eof) { yyextra->m_Eof = true; return T_NEWLINE; } else { yyterminate(); } } . return yytext[0]; %%