1 /* 2 * Copyright (c) 2015 PLUMgrid, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #ifndef yyFlexLexerOnce 20 #undef yyFlexLexer 21 #define yyFlexLexer ebpfccFlexLexer 22 #include <FlexLexer.h> 23 #endif 24 25 #undef YY_DECL 26 #define YY_DECL int ebpf::cc::Lexer::yylex() 27 28 #include <iostream> // NOLINT 29 #include <list> 30 #include "parser.yy.hh" 31 32 namespace ebpf { 33 namespace cc { 34 35 typedef BisonParser::token::yytokentype Tok; 36 37 class Lexer : public yyFlexLexer { 38 public: Lexer(std::istream * in)39 explicit Lexer(std::istream* in) 40 : yyFlexLexer(in), prev_tok_(Tok::TSEMI), lines_({""}), yylval_(NULL), yylloc_(NULL) { 41 if (!in || !*in) 42 fprintf(stderr, "Unable to open input stream\n"); 43 } yylex(BisonParser::semantic_type * lval,BisonParser::location_type * lloc)44 int yylex(BisonParser::semantic_type *lval, BisonParser::location_type *lloc) { 45 yylval_ = lval; 46 yylloc_ = lloc; 47 return yylex(); 48 } text(const BisonParser::location_type & loc)49 std::string text(const BisonParser::location_type& loc) const { 50 return text(loc.begin, loc.end); 51 } text(const position & begin,const position & end)52 std::string text(const position& begin, const position& end) const { 53 std::string result; 54 for (size_t i = begin.line; i <= end.line; ++i) { 55 if (i == begin.line && i == end.line) { 56 result += lines_.at(i - 1).substr(begin.column - 1, end.column - begin.column); 57 } else if (i == begin.line && i < end.line) { 58 result += lines_.at(i - 1).substr(begin.column - 1); 59 } else if (i > begin.line && i == end.line) { 60 result += lines_.at(i - 1).substr(0, end.column); 61 } else if (i > begin.line && i == end.line) { 62 result += lines_.at(i - 1); 63 } 64 } 65 return result; 66 } 67 private: 68 69 // true if a semicolon should be replaced here next_line()70 bool next_line() { 71 lines_.push_back(""); 72 yylloc_->lines(); 73 yylloc_->step(); 74 switch (prev_tok_) { 75 case Tok::TIDENTIFIER: 76 case Tok::TINTEGER: 77 case Tok::THEXINTEGER: 78 case Tok::TRBRACE: 79 case Tok::TRPAREN: 80 case Tok::TRBRACK: 81 case Tok::TTRUE: 82 case Tok::TFALSE: 83 // uncomment to add implicit semicolons 84 //return true; 85 default: 86 break; 87 } 88 return false; 89 } 90 91 Tok save(Tok tok, bool ignore_text = false) { 92 if (!ignore_text) { 93 save_text(); 94 } 95 96 switch (tok) { 97 case Tok::TIDENTIFIER: 98 case Tok::TINTEGER: 99 case Tok::THEXINTEGER: 100 yylval_->string = new std::string(yytext, yyleng); 101 break; 102 default: 103 yylval_->token = tok; 104 } 105 prev_tok_ = tok; 106 return tok; 107 } 108 109 /* 110 std::string * alloc_string(const char *c, size_t len) { 111 strings_.push_back(std::unique_ptr<std::string>(new std::string(c, len))); 112 return strings_.back().get(); 113 } 114 115 std::string * alloc_string(const std::string &s) { 116 strings_.push_back(std::unique_ptr<std::string>(new std::string(s))); 117 return strings_.back().get(); 118 } 119 */ 120 save_text()121 void save_text() { 122 lines_.back().append(yytext, yyleng); 123 yylloc_->columns(yyleng); 124 } 125 126 int yylex(); 127 Tok prev_tok_; 128 std::vector<std::string> lines_; 129 //std::list<std::unique_ptr<std::string>> strings_; 130 BisonParser::semantic_type *yylval_; 131 BisonParser::location_type *yylloc_; 132 }; 133 134 } // namespace cc 135 } // namespace ebpf 136