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  }