kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/cxx/verifier/assertions.lex (about) 1 %{ 2 /* 3 * Copyright 2014 The Kythe Authors. All rights reserved. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 // Started from the calc++ example code as part of the Bison-3.0 distribution. 18 #include "kythe/cxx/verifier/assertions.h" 19 #include "kythe/cxx/verifier/parser.yy.hh" 20 #include <assert.h> 21 22 // The offset of the current token (as byte offset). 23 static size_t loc_ofs; 24 %} 25 %option noyywrap nounput batch debug noinput bison-bridge 26 id [%#]?[_a-zA-Z/][a-zA-Z_0-9/]* 27 int [0-9]+ 28 blank [ \t] 29 30 %{ 31 // Code run each time a pattern is matched. 32 #define YY_USER_ACTION yylloc->columns(yyleng); loc_ofs += yyleng; 33 %} 34 35 /* The lexer has the following states: 36 * INITIAL: We aren't sure whether this line is relevant to parsing 37 * rules; check after every character whether to switch states. 38 * IGNORED: This line is definitely not one that contains input for our 39 * parser. While still updating the file location, wait until 40 * an endline. 41 * NORMAL: This line contains input that must be passed on to the parser. */ 42 %s IGNORED NORMAL 43 %% 44 45 %{ 46 // Code run each time yylex is called. 47 yylloc->step(); 48 %} 49 50 <INITIAL>{ 51 \n { 52 yylloc->lines(yyleng); 53 yylloc->end.column = 1; 54 yylloc->step(); 55 context.ResetLine(); 56 } 57 "-" --loc_ofs; yylloc->columns(-1); BEGIN(NORMAL); 58 "." --loc_ofs; yylloc->columns(-1); BEGIN(IGNORED); 59 } /* INITIAL state */ 60 61 <IGNORED>{ 62 \n { 63 // Resolve locations after the first endline. 64 if (!context.ResolveLocations(*yylloc, loc_ofs, false)) { 65 context.Error(*yylloc, "could not resolve all locations"); 66 } 67 yylloc->lines(yyleng); 68 yylloc->end.column = 1; 69 yylloc->step(); 70 BEGIN(INITIAL); 71 } 72 [^\n]* context.AppendToLine(yytext); 73 } /* IGNORED state */ 74 75 <NORMAL>{ 76 {blank}+ yylloc->step(); 77 \n { 78 yylloc->lines(yyleng); 79 yylloc->end.column = 1; 80 yylloc->step(); 81 context.ResetLine(); 82 BEGIN(INITIAL); 83 } 84 "//"[^\n]* yylloc->step(); 85 "(" return yy::AssertionParserImpl::token::LPAREN; 86 ")" return yy::AssertionParserImpl::token::RPAREN; 87 "," return yy::AssertionParserImpl::token::COMMA; 88 "_" return yy::AssertionParserImpl::token::DONTCARE; 89 "'" return yy::AssertionParserImpl::token::APOSTROPHE; 90 "@^" return yy::AssertionParserImpl::token::AT_HAT; 91 "@$" return yy::AssertionParserImpl::token::AT_CASH; 92 "@" return yy::AssertionParserImpl::token::AT; 93 "." return yy::AssertionParserImpl::token::DOT; 94 "?" return yy::AssertionParserImpl::token::WHAT; 95 "=" return yy::AssertionParserImpl::token::EQUALS; 96 "{" return yy::AssertionParserImpl::token::LBRACE; 97 "}" return yy::AssertionParserImpl::token::RBRACE; 98 "!" return yy::AssertionParserImpl::token::BANG; 99 ":" return yy::AssertionParserImpl::token::COLON; 100 "+" return yy::AssertionParserImpl::token::PLUS; 101 "#"{blank}*{int} { 102 yylval->string = yytext; return yy::AssertionParserImpl::token::HASH_NUMBER; 103 } 104 {int} yylval->string = yytext; return yy::AssertionParserImpl::token::NUMBER; 105 {id} yylval->string = yytext; return yy::AssertionParserImpl::token::IDENTIFIER; 106 \"(\\.|[^\\"])*\" { 107 std::string out; 108 if (!context.Unescape(yytext, &out)) { 109 context.Error(*yylloc, "invalid literal string"); 110 } 111 yylval->string = out; 112 return yy::AssertionParserImpl::token::STRING; 113 } 114 . context.Error(*yylloc, "invalid character"); 115 } /* NORMAL state */ 116 117 <<EOF>> { 118 context.save_eof(*yylloc, loc_ofs); 119 return yy::AssertionParserImpl::token::END; 120 } 121 %% 122 123 namespace kythe { 124 namespace verifier { 125 126 static YY_BUFFER_STATE string_buffer_state = nullptr; 127 128 void AssertionParser::SetScanBuffer(const std::string& scan_buffer, 129 bool trace_scanning) { 130 BEGIN(INITIAL); 131 loc_ofs = 0; 132 yy_flex_debug = trace_scanning; 133 CHECK(string_buffer_state == nullptr); 134 // yy_scan_bytes makes a copy of its buffer. 135 string_buffer_state = yy_scan_bytes(scan_buffer.c_str(), scan_buffer.size()); 136 } 137 138 void AssertionParser::ScanEnd(const yy::location &eof_loc, 139 size_t eof_loc_ofs) { 140 // Imagine that all files end with an endline. 141 if (!ResolveLocations(eof_loc, eof_loc_ofs + 1, true)) { 142 Error(eof_loc, "could not resolve all locations at end of file"); 143 } 144 yy_delete_buffer(string_buffer_state); 145 string_buffer_state = nullptr; 146 } 147 148 } 149 }