diff options
Diffstat (limited to 'lib/config/config_lexer.ll')
-rw-r--r-- | lib/config/config_lexer.ll | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/lib/config/config_lexer.ll b/lib/config/config_lexer.ll new file mode 100644 index 0000000..abfdaff --- /dev/null +++ b/lib/config/config_lexer.ll @@ -0,0 +1,253 @@ +%{ +/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */ + +#include "config/configcompiler.hpp" +#include "config/expression.hpp" +#include "base/exception.hpp" +#include <utility> + +using namespace icinga; + +#include "config/config_parser.hh" +#include <sstream> + +#define YYLTYPE icinga::CompilerDebugInfo + +#define YY_EXTRA_TYPE ConfigCompiler * +#define YY_USER_ACTION \ +do { \ + yylloc->Path = yyextra->GetPath(); \ + yylloc->FirstLine = yylineno; \ + yylloc->FirstColumn = yycolumn; \ + yylloc->LastLine = yylineno; \ + yylloc->LastColumn = yycolumn + yyleng - 1; \ + yycolumn += yyleng; \ +} while (0); + +#define YY_INPUT(buf, result, max_size) \ +do { \ + result = yyextra->ReadInput(buf, max_size); \ +} while (0) +%} + +%option reentrant noyywrap yylineno +%option bison-bridge bison-locations +%option never-interactive nounistd +%option noinput nounput + +%x C_COMMENT +%x STRING +%x HEREDOC + +%% +\" { + yyextra->m_LexBuffer.Clear(); + + yyextra->m_LocationBegin = *yylloc; + + BEGIN(STRING); + } + +<STRING>\" { + BEGIN(INITIAL); + + yylloc->FirstLine = yyextra->m_LocationBegin.FirstLine; + yylloc->FirstColumn = yyextra->m_LocationBegin.FirstColumn; + + yylval->text = new String(std::move(yyextra->m_LexBuffer)); + + return T_STRING; + } + +<STRING>\n { + BOOST_THROW_EXCEPTION(ScriptError("Unterminated string literal", DebugInfoRange(yyextra->m_LocationBegin, *yylloc))); + } + +<STRING>\\[0-7]{1,3} { + /* octal escape sequence */ + int result; + + (void) sscanf(yytext + 1, "%o", &result); + + if (result > 0xff) { + /* error, constant is out-of-bounds */ + BOOST_THROW_EXCEPTION(ScriptError("Constant is out of bounds: " + String(yytext), *yylloc)); + } + + yyextra->m_LexBuffer += static_cast<char>(result); + } + +<STRING>\\[0-9]+ { + /* generate error - bad escape sequence; something + * like '\48' or '\0777777' + */ + BOOST_THROW_EXCEPTION(ScriptError("Bad escape sequence found: " + String(yytext), *yylloc)); + } +<STRING>\\n { yyextra->m_LexBuffer += '\n'; } +<STRING>\\\\ { yyextra->m_LexBuffer += '\\'; } +<STRING>\\\" { yyextra->m_LexBuffer += '"'; } +<STRING>\\t { yyextra->m_LexBuffer += '\t'; } +<STRING>\\r { yyextra->m_LexBuffer += '\r'; } +<STRING>\\b { yyextra->m_LexBuffer += '\b'; } +<STRING>\\f { yyextra->m_LexBuffer += '\f'; } +<STRING>\\\n { yyextra->m_LexBuffer += yytext[1]; } +<STRING>\\. { + BOOST_THROW_EXCEPTION(ScriptError("Bad escape sequence found: " + String(yytext), *yylloc)); + } + +<STRING>[^\\\n\"]+ { + char *yptr = yytext; + + while (*yptr) + yyextra->m_LexBuffer += *yptr++; + } + +<STRING><<EOF>> { + BOOST_THROW_EXCEPTION(ScriptError("End-of-file while in string literal", DebugInfoRange(yyextra->m_LocationBegin, *yylloc))); + } + +\{\{\{ { + yyextra->m_LexBuffer.Clear(); + + yyextra->m_LocationBegin = *yylloc; + + BEGIN(HEREDOC); + } + +<HEREDOC><<EOF>> { + BOOST_THROW_EXCEPTION(ScriptError("End-of-file while in string literal", DebugInfoRange(yyextra->m_LocationBegin, *yylloc))); + } + +<HEREDOC>\}\}\} { + BEGIN(INITIAL); + + yylloc->FirstLine = yyextra->m_LocationBegin.FirstLine; + yylloc->FirstColumn = yyextra->m_LocationBegin.FirstColumn; + + yylval->text = new String(std::move(yyextra->m_LexBuffer)); + + return T_STRING; + } + +<HEREDOC>(.|\n) { yyextra->m_LexBuffer += yytext[0]; } + +<INITIAL>{ +"/*" BEGIN(C_COMMENT); +} + +<C_COMMENT>{ +"*/" BEGIN(INITIAL); +[^*] /* ignore comment */ +"*" /* ignore star */ +} + +<C_COMMENT><<EOF>> { + BOOST_THROW_EXCEPTION(ScriptError("End-of-file while in comment", *yylloc)); + } + + +\/\/[^\n]* /* ignore C++-style comments */ +#[^\n]* /* ignore shell-style comments */ +[ \t] /* ignore whitespace */ + +<INITIAL>{ +object return T_OBJECT; +template return T_TEMPLATE; +include return T_INCLUDE; +include_recursive return T_INCLUDE_RECURSIVE; +include_zones return T_INCLUDE_ZONES; +library return T_LIBRARY; +null return T_NULL; +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; +globals return T_GLOBALS; +locals return T_LOCALS; +use return T_USE; +using return T_USING; +apply return T_APPLY; +default return T_DEFAULT; +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; +break return T_BREAK; +continue return T_CONTINUE; +for return T_FOR; +if return T_IF; +else return T_ELSE; +while return T_WHILE; +throw return T_THROW; +try return T_TRY; +except return T_EXCEPT; +ignore_on_error return T_IGNORE_ON_ERROR; +current_filename return T_CURRENT_FILENAME; +current_line return T_CURRENT_LINE; +debugger return T_DEBUGGER; +namespace return T_NAMESPACE; +=\> 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; +\{\{ return T_NULLARY_LAMBDA_BEGIN; +\}\} return T_NULLARY_LAMBDA_END; +[a-zA-Z_][a-zA-Z0-9\_]* { yylval->text = new String(yytext); return T_IDENTIFIER; } +@[a-zA-Z_][a-zA-Z0-9\_]* { yylval->text = new String(yytext + 1); return T_IDENTIFIER; } +\<[^ \>]*\> { yytext[yyleng-1] = '\0'; yylval->text = new String(yytext + 1); return T_STRING_ANGLE; } +[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; +} + +\( { yyextra->m_IgnoreNewlines.push(true); return '('; } +\) { yyextra->m_IgnoreNewlines.pop(); return ')'; } +[\r\n]+ { yycolumn -= strlen(yytext) - 1; if (!yyextra->m_IgnoreNewlines.top()) { return T_NEWLINE; } } +<<EOF>> { if (!yyextra->m_Eof) { yyextra->m_Eof = true; return T_NEWLINE; } else { yyterminate(); } } +. return yytext[0]; + +%% + +void ConfigCompiler::InitializeScanner() +{ + yylex_init(&m_Scanner); + yyset_extra(this, m_Scanner); +} + +void ConfigCompiler::DestroyScanner() +{ + yylex_destroy(m_Scanner); +} |