/* * Copyright (c) 2015 PLUMgrid, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #ifndef yyFlexLexerOnce #undef yyFlexLexer #define yyFlexLexer ebpfccFlexLexer #include #endif #undef YY_DECL #define YY_DECL int ebpf::cc::Lexer::yylex() #include // NOLINT #include #include "parser.yy.hh" namespace ebpf { namespace cc { typedef BisonParser::token::yytokentype Tok; class Lexer : public yyFlexLexer { public: explicit Lexer(std::istream* in) : yyFlexLexer(in), prev_tok_(Tok::TSEMI), lines_({""}), yylval_(NULL), yylloc_(NULL) { if (!in || !*in) fprintf(stderr, "Unable to open input stream\n"); } int yylex(BisonParser::semantic_type *lval, BisonParser::location_type *lloc) { yylval_ = lval; yylloc_ = lloc; return yylex(); } std::string text(const BisonParser::location_type& loc) const { return text(loc.begin, loc.end); } std::string text(const position& begin, const position& end) const { std::string result; for (auto i = begin.line; i <= end.line; ++i) { if (i == begin.line && i == end.line) { result += lines_.at(i - 1).substr(begin.column - 1, end.column - begin.column); } else if (i == begin.line && i < end.line) { result += lines_.at(i - 1).substr(begin.column - 1); } else if (i > begin.line && i == end.line) { result += lines_.at(i - 1).substr(0, end.column); } else if (i > begin.line && i == end.line) { result += lines_.at(i - 1); } } return result; } private: // true if a semicolon should be replaced here bool next_line() { lines_.push_back(""); yylloc_->lines(); yylloc_->step(); switch (prev_tok_) { case Tok::TIDENTIFIER: case Tok::TINTEGER: case Tok::THEXINTEGER: case Tok::TRBRACE: case Tok::TRPAREN: case Tok::TRBRACK: case Tok::TTRUE: case Tok::TFALSE: // uncomment to add implicit semicolons //return true; default: break; } return false; } Tok save(Tok tok, bool ignore_text = false) { if (!ignore_text) { save_text(); } switch (tok) { case Tok::TIDENTIFIER: case Tok::TINTEGER: case Tok::THEXINTEGER: yylval_->string = new std::string(yytext, yyleng); break; default: yylval_->token = tok; } prev_tok_ = tok; return tok; } /* std::string * alloc_string(const char *c, size_t len) { strings_.push_back(std::unique_ptr(new std::string(c, len))); return strings_.back().get(); } std::string * alloc_string(const std::string &s) { strings_.push_back(std::unique_ptr(new std::string(s))); return strings_.back().get(); } */ void save_text() { lines_.back().append(yytext, yyleng); yylloc_->columns(yyleng); } int yylex(); Tok prev_tok_; std::vector lines_; //std::list> strings_; BisonParser::semantic_type *yylval_; BisonParser::location_type *yylloc_; }; } // namespace cc } // namespace ebpf