1*0b57cec5SDimitry Andric //===-- StringLexer.cpp ---------------------------------------------------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric 
9*0b57cec5SDimitry Andric #include "lldb/Utility/StringLexer.h"
10*0b57cec5SDimitry Andric 
11*0b57cec5SDimitry Andric #include <algorithm>
12*0b57cec5SDimitry Andric #include <cassert>
13*0b57cec5SDimitry Andric #include <utility>
14*0b57cec5SDimitry Andric 
15*0b57cec5SDimitry Andric using namespace lldb_private;
16*0b57cec5SDimitry Andric 
StringLexer(std::string s)17*0b57cec5SDimitry Andric StringLexer::StringLexer(std::string s) : m_data(std::move(s)), m_position(0) {}
18*0b57cec5SDimitry Andric 
Peek()19*0b57cec5SDimitry Andric StringLexer::Character StringLexer::Peek() { return m_data[m_position]; }
20*0b57cec5SDimitry Andric 
NextIf(Character c)21*0b57cec5SDimitry Andric bool StringLexer::NextIf(Character c) {
22*0b57cec5SDimitry Andric   auto val = Peek();
23*0b57cec5SDimitry Andric   if (val == c) {
24*0b57cec5SDimitry Andric     Next();
25*0b57cec5SDimitry Andric     return true;
26*0b57cec5SDimitry Andric   }
27*0b57cec5SDimitry Andric   return false;
28*0b57cec5SDimitry Andric }
29*0b57cec5SDimitry Andric 
30*0b57cec5SDimitry Andric std::pair<bool, StringLexer::Character>
NextIf(std::initializer_list<Character> cs)31*0b57cec5SDimitry Andric StringLexer::NextIf(std::initializer_list<Character> cs) {
32*0b57cec5SDimitry Andric   auto val = Peek();
33*0b57cec5SDimitry Andric   for (auto c : cs) {
34*0b57cec5SDimitry Andric     if (val == c) {
35*0b57cec5SDimitry Andric       Next();
36*0b57cec5SDimitry Andric       return {true, c};
37*0b57cec5SDimitry Andric     }
38*0b57cec5SDimitry Andric   }
39*0b57cec5SDimitry Andric   return {false, 0};
40*0b57cec5SDimitry Andric }
41*0b57cec5SDimitry Andric 
AdvanceIf(const std::string & token)42*0b57cec5SDimitry Andric bool StringLexer::AdvanceIf(const std::string &token) {
43*0b57cec5SDimitry Andric   auto pos = m_position;
44*0b57cec5SDimitry Andric   bool matches = true;
45*0b57cec5SDimitry Andric   for (auto c : token) {
46*0b57cec5SDimitry Andric     if (!NextIf(c)) {
47*0b57cec5SDimitry Andric       matches = false;
48*0b57cec5SDimitry Andric       break;
49*0b57cec5SDimitry Andric     }
50*0b57cec5SDimitry Andric   }
51*0b57cec5SDimitry Andric   if (!matches) {
52*0b57cec5SDimitry Andric     m_position = pos;
53*0b57cec5SDimitry Andric     return false;
54*0b57cec5SDimitry Andric   }
55*0b57cec5SDimitry Andric   return true;
56*0b57cec5SDimitry Andric }
57*0b57cec5SDimitry Andric 
Next()58*0b57cec5SDimitry Andric StringLexer::Character StringLexer::Next() {
59*0b57cec5SDimitry Andric   auto val = Peek();
60*0b57cec5SDimitry Andric   Consume();
61*0b57cec5SDimitry Andric   return val;
62*0b57cec5SDimitry Andric }
63*0b57cec5SDimitry Andric 
HasAtLeast(Size s)64*0b57cec5SDimitry Andric bool StringLexer::HasAtLeast(Size s) {
65*0b57cec5SDimitry Andric   return (m_data.size() - m_position) >= s;
66*0b57cec5SDimitry Andric }
67*0b57cec5SDimitry Andric 
PutBack(Size s)68*0b57cec5SDimitry Andric void StringLexer::PutBack(Size s) {
69*0b57cec5SDimitry Andric   assert(m_position >= s);
70*0b57cec5SDimitry Andric   m_position -= s;
71*0b57cec5SDimitry Andric }
72*0b57cec5SDimitry Andric 
GetUnlexed()73*0b57cec5SDimitry Andric std::string StringLexer::GetUnlexed() {
74*0b57cec5SDimitry Andric   return std::string(m_data, m_position);
75*0b57cec5SDimitry Andric }
76*0b57cec5SDimitry Andric 
Consume()77*0b57cec5SDimitry Andric void StringLexer::Consume() { m_position++; }
78*0b57cec5SDimitry Andric 
operator =(const StringLexer & rhs)79*0b57cec5SDimitry Andric StringLexer &StringLexer::operator=(const StringLexer &rhs) {
80*0b57cec5SDimitry Andric   if (this != &rhs) {
81*0b57cec5SDimitry Andric     m_data = rhs.m_data;
82*0b57cec5SDimitry Andric     m_position = rhs.m_position;
83*0b57cec5SDimitry Andric   }
84*0b57cec5SDimitry Andric   return *this;
85 }
86