1b1994897Sopenharmony_ci/**
2b1994897Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3b1994897Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4b1994897Sopenharmony_ci * you may not use this file except in compliance with the License.
5b1994897Sopenharmony_ci * You may obtain a copy of the License at
6b1994897Sopenharmony_ci *
7b1994897Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8b1994897Sopenharmony_ci *
9b1994897Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10b1994897Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11b1994897Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12b1994897Sopenharmony_ci * See the License for the specific language governing permissions and
13b1994897Sopenharmony_ci * limitations under the License.
14b1994897Sopenharmony_ci */
15b1994897Sopenharmony_ci
16b1994897Sopenharmony_ci#include "lexer.h"
17b1994897Sopenharmony_ci
18b1994897Sopenharmony_cinamespace panda::pandasm {
19b1994897Sopenharmony_ci
20b1994897Sopenharmony_ci/*-------------------------------*/
21b1994897Sopenharmony_ci
22b1994897Sopenharmony_ci/* Is this a delimiter ? */
23b1994897Sopenharmony_ciToken::Type FindDelim(char c)
24b1994897Sopenharmony_ci{
25b1994897Sopenharmony_ci    /* The map of delimiters */
26b1994897Sopenharmony_ci    static const std::unordered_map<char, Token::Type> DELIM = {{',', Token::Type::DEL_COMMA},
27b1994897Sopenharmony_ci                                                                {':', Token::Type::DEL_COLON},
28b1994897Sopenharmony_ci                                                                {'{', Token::Type::DEL_BRACE_L},
29b1994897Sopenharmony_ci                                                                {'}', Token::Type::DEL_BRACE_R},
30b1994897Sopenharmony_ci                                                                {'(', Token::Type::DEL_BRACKET_L},
31b1994897Sopenharmony_ci                                                                {')', Token::Type::DEL_BRACKET_R},
32b1994897Sopenharmony_ci                                                                {'<', Token::Type::DEL_LT},
33b1994897Sopenharmony_ci                                                                {'>', Token::Type::DEL_GT},
34b1994897Sopenharmony_ci                                                                {'=', Token::Type::DEL_EQ},
35b1994897Sopenharmony_ci                                                                {'[', Token::Type::DEL_SQUARE_BRACKET_L},
36b1994897Sopenharmony_ci                                                                {']', Token::Type::DEL_SQUARE_BRACKET_R}};
37b1994897Sopenharmony_ci
38b1994897Sopenharmony_ci    auto iter = DELIM.find(c);
39b1994897Sopenharmony_ci
40b1994897Sopenharmony_ci    if (iter == DELIM.end()) {
41b1994897Sopenharmony_ci        return Token::Type::ID_BAD;
42b1994897Sopenharmony_ci    }
43b1994897Sopenharmony_ci
44b1994897Sopenharmony_ci    return DELIM.at(c);
45b1994897Sopenharmony_ci}
46b1994897Sopenharmony_ci
47b1994897Sopenharmony_ciToken::Type FindOperation(std::string_view s)
48b1994897Sopenharmony_ci{
49b1994897Sopenharmony_ci    /* Generate the map of OPERATIONS from ISA: */
50b1994897Sopenharmony_ci    static const std::unordered_map<std::string_view, Token::Type> OPERATIONS = {
51b1994897Sopenharmony_ci// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
52b1994897Sopenharmony_ci#define OPLIST(inst_code, name, optype, width, flags, dst_idx, use_idxs) \
53b1994897Sopenharmony_ci    {std::string_view(name), Token::Type::ID_OP_##inst_code},
54b1994897Sopenharmony_ci        PANDA_INSTRUCTION_LIST(OPLIST)
55b1994897Sopenharmony_ci#undef OPLIST
56b1994897Sopenharmony_ci    };
57b1994897Sopenharmony_ci
58b1994897Sopenharmony_ci    auto iter = OPERATIONS.find(s);
59b1994897Sopenharmony_ci
60b1994897Sopenharmony_ci    if (iter == OPERATIONS.end()) {
61b1994897Sopenharmony_ci        return Token::Type::ID_BAD;
62b1994897Sopenharmony_ci    }
63b1994897Sopenharmony_ci
64b1994897Sopenharmony_ci    return OPERATIONS.at(s);
65b1994897Sopenharmony_ci}
66b1994897Sopenharmony_ci
67b1994897Sopenharmony_ciToken::Type Findkeyword(std::string_view s)
68b1994897Sopenharmony_ci{
69b1994897Sopenharmony_ci    /* Generate the map of KEYWORDS: */
70b1994897Sopenharmony_ci    static const std::unordered_map<std::string_view, Token::Type> KEYWORDS = {
71b1994897Sopenharmony_ci// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
72b1994897Sopenharmony_ci#define KEYWORDS(name, inst_code) {std::string_view(name), Token::Type::ID_##inst_code},
73b1994897Sopenharmony_ci        KEYWORDS_LIST(KEYWORDS)
74b1994897Sopenharmony_ci#undef KEYWORDS
75b1994897Sopenharmony_ci    };
76b1994897Sopenharmony_ci
77b1994897Sopenharmony_ci    auto iter = KEYWORDS.find(s);
78b1994897Sopenharmony_ci
79b1994897Sopenharmony_ci    if (iter == KEYWORDS.end()) {
80b1994897Sopenharmony_ci        return Token::Type::ID_BAD;
81b1994897Sopenharmony_ci    }
82b1994897Sopenharmony_ci
83b1994897Sopenharmony_ci    return KEYWORDS.at(s);
84b1994897Sopenharmony_ci}
85b1994897Sopenharmony_ci
86b1994897Sopenharmony_cistd::string_view TokenTypeWhat(Token::Type t)
87b1994897Sopenharmony_ci{
88b1994897Sopenharmony_ci    if (t >= Token::Type::OPERATION && t < Token::Type::KEYWORD) {
89b1994897Sopenharmony_ci        return "OPERATION";
90b1994897Sopenharmony_ci    }
91b1994897Sopenharmony_ci
92b1994897Sopenharmony_ci    if (t >= Token::Type::KEYWORD) {
93b1994897Sopenharmony_ci        return "KEYWORD";
94b1994897Sopenharmony_ci    }
95b1994897Sopenharmony_ci
96b1994897Sopenharmony_ci    switch (t) {
97b1994897Sopenharmony_ci        case Token::Type::ID_BAD: {
98b1994897Sopenharmony_ci            return "ID_BAD";
99b1994897Sopenharmony_ci        }
100b1994897Sopenharmony_ci        case Token::Type::DEL_COMMA: {
101b1994897Sopenharmony_ci            return "DEL_COMMA";
102b1994897Sopenharmony_ci        }
103b1994897Sopenharmony_ci        case Token::Type::DEL_COLON: {
104b1994897Sopenharmony_ci            return "DEL_COLON";
105b1994897Sopenharmony_ci        }
106b1994897Sopenharmony_ci        case Token::Type::DEL_BRACE_L: {
107b1994897Sopenharmony_ci            return "DEL_BRACE_L";
108b1994897Sopenharmony_ci        }
109b1994897Sopenharmony_ci        case Token::Type::DEL_BRACE_R: {
110b1994897Sopenharmony_ci            return "DEL_BRACE_R";
111b1994897Sopenharmony_ci        }
112b1994897Sopenharmony_ci        case Token::Type::DEL_BRACKET_L: {
113b1994897Sopenharmony_ci            return "DEL_BRACKET_L";
114b1994897Sopenharmony_ci        }
115b1994897Sopenharmony_ci        case Token::Type::DEL_BRACKET_R: {
116b1994897Sopenharmony_ci            return "DEL_BRACKET_R";
117b1994897Sopenharmony_ci        }
118b1994897Sopenharmony_ci        case Token::Type::DEL_SQUARE_BRACKET_L: {
119b1994897Sopenharmony_ci            return "DEL_SQUARE_BRACKET_L";
120b1994897Sopenharmony_ci        }
121b1994897Sopenharmony_ci        case Token::Type::DEL_SQUARE_BRACKET_R: {
122b1994897Sopenharmony_ci            return "DEL_SQUARE_BRACKET_R";
123b1994897Sopenharmony_ci        }
124b1994897Sopenharmony_ci        case Token::Type::DEL_GT: {
125b1994897Sopenharmony_ci            return "DEL_GT";
126b1994897Sopenharmony_ci        }
127b1994897Sopenharmony_ci        case Token::Type::DEL_LT: {
128b1994897Sopenharmony_ci            return "DEL_LT";
129b1994897Sopenharmony_ci        }
130b1994897Sopenharmony_ci        case Token::Type::DEL_EQ: {
131b1994897Sopenharmony_ci            return "DEL_EQ";
132b1994897Sopenharmony_ci        }
133b1994897Sopenharmony_ci        case Token::Type::DEL_DOT: {
134b1994897Sopenharmony_ci            return "DEL_DOT";
135b1994897Sopenharmony_ci        }
136b1994897Sopenharmony_ci        case Token::Type::ID: {
137b1994897Sopenharmony_ci            return "ID";
138b1994897Sopenharmony_ci        }
139b1994897Sopenharmony_ci        case Token::Type::ID_STRING: {
140b1994897Sopenharmony_ci            return "ID_STRING";
141b1994897Sopenharmony_ci        }
142b1994897Sopenharmony_ci        default:
143b1994897Sopenharmony_ci            return "NONE";
144b1994897Sopenharmony_ci    }
145b1994897Sopenharmony_ci}
146b1994897Sopenharmony_ci
147b1994897Sopenharmony_cistatic bool IsQuote(char c)
148b1994897Sopenharmony_ci{
149b1994897Sopenharmony_ci    return c == '"';
150b1994897Sopenharmony_ci}
151b1994897Sopenharmony_ci
152b1994897Sopenharmony_ciLexer::Lexer() : curr_line_(nullptr)
153b1994897Sopenharmony_ci{
154b1994897Sopenharmony_ci    LOG(DEBUG, ASSEMBLER) << "element of class Lexer initialized";
155b1994897Sopenharmony_ci}
156b1994897Sopenharmony_ci
157b1994897Sopenharmony_ciLexer::~Lexer()
158b1994897Sopenharmony_ci{
159b1994897Sopenharmony_ci    LOG(DEBUG, ASSEMBLER) << "element of class Lexer destructed";
160b1994897Sopenharmony_ci}
161b1994897Sopenharmony_ci
162b1994897Sopenharmony_ciTokens Lexer::TokenizeString(const std::string &source_str)
163b1994897Sopenharmony_ci{
164b1994897Sopenharmony_ci    LOG(DEBUG, ASSEMBLER) << "started tokenizing of line " << lines_.size() + 1 << ": ";
165b1994897Sopenharmony_ci
166b1994897Sopenharmony_ci    lines_.emplace_back(source_str);
167b1994897Sopenharmony_ci
168b1994897Sopenharmony_ci    curr_line_ = &lines_.back();
169b1994897Sopenharmony_ci
170b1994897Sopenharmony_ci    LOG(DEBUG, ASSEMBLER) << std::string_view(&*(curr_line_->buffer.begin() + curr_line_->pos),
171b1994897Sopenharmony_ci                                              curr_line_->end - curr_line_->pos);
172b1994897Sopenharmony_ci
173b1994897Sopenharmony_ci    AnalyzeLine();
174b1994897Sopenharmony_ci
175b1994897Sopenharmony_ci    LOG(DEBUG, ASSEMBLER) << "tokenization of line " << lines_.size() << " is successful";
176b1994897Sopenharmony_ci    LOG(DEBUG, ASSEMBLER) << "         tokens identified: ";
177b1994897Sopenharmony_ci
178b1994897Sopenharmony_ci    for (const auto &f_i : lines_.back().tokens) {
179b1994897Sopenharmony_ci        LOG(DEBUG, ASSEMBLER) << "\n                           "
180b1994897Sopenharmony_ci                              << std::string_view(&*(f_i.whole_line.begin() + f_i.bound_left),
181b1994897Sopenharmony_ci                                                  f_i.bound_right - f_i.bound_left)
182b1994897Sopenharmony_ci                              << " (type: " << TokenTypeWhat(f_i.type) << ")";
183b1994897Sopenharmony_ci
184b1994897Sopenharmony_ci        LOG(DEBUG, ASSEMBLER);
185b1994897Sopenharmony_ci        LOG(DEBUG, ASSEMBLER);
186b1994897Sopenharmony_ci    }
187b1994897Sopenharmony_ci    return std::pair<std::vector<Token>, Error>(lines_.back().tokens, err_);
188b1994897Sopenharmony_ci}
189b1994897Sopenharmony_ci
190b1994897Sopenharmony_ci/* End of line? */
191b1994897Sopenharmony_cibool Lexer::Eol() const
192b1994897Sopenharmony_ci{
193b1994897Sopenharmony_ci    return curr_line_->pos == curr_line_->end;
194b1994897Sopenharmony_ci}
195b1994897Sopenharmony_ci
196b1994897Sopenharmony_ci/* Return the type of token */
197b1994897Sopenharmony_ciToken::Type Lexer::LexGetType(size_t beg, size_t end) const
198b1994897Sopenharmony_ci{
199b1994897Sopenharmony_ci    if (FindDelim(curr_line_->buffer[beg]) != Token::Type::ID_BAD) { /* delimiter */
200b1994897Sopenharmony_ci        return FindDelim(curr_line_->buffer[beg]);
201b1994897Sopenharmony_ci    }
202b1994897Sopenharmony_ci
203b1994897Sopenharmony_ci    std::string_view p(&*(curr_line_->buffer.begin() + beg), end - beg);
204b1994897Sopenharmony_ci
205b1994897Sopenharmony_ci    Token::Type type = Findkeyword(p);
206b1994897Sopenharmony_ci
207b1994897Sopenharmony_ci    if (type != Token::Type::ID_BAD) {
208b1994897Sopenharmony_ci        return type;
209b1994897Sopenharmony_ci    }
210b1994897Sopenharmony_ci
211b1994897Sopenharmony_ci    type = FindOperation(p);
212b1994897Sopenharmony_ci
213b1994897Sopenharmony_ci    if (type != Token::Type::ID_BAD) {
214b1994897Sopenharmony_ci        return type;
215b1994897Sopenharmony_ci    }
216b1994897Sopenharmony_ci
217b1994897Sopenharmony_ci    if (IsQuote(curr_line_->buffer[beg])) {
218b1994897Sopenharmony_ci        return Token::Type::ID_STRING;
219b1994897Sopenharmony_ci    }
220b1994897Sopenharmony_ci
221b1994897Sopenharmony_ci    return Token::Type::ID; /* other */
222b1994897Sopenharmony_ci}
223b1994897Sopenharmony_ci
224b1994897Sopenharmony_ci/* Handle string literal */
225b1994897Sopenharmony_cibool Lexer::LexString()
226b1994897Sopenharmony_ci{
227b1994897Sopenharmony_ci    bool is_escape_seq = false;
228b1994897Sopenharmony_ci    char quote = curr_line_->buffer[curr_line_->pos];
229b1994897Sopenharmony_ci    size_t begin = curr_line_->pos;
230b1994897Sopenharmony_ci    while (!Eol()) {
231b1994897Sopenharmony_ci        ++(curr_line_->pos);
232b1994897Sopenharmony_ci
233b1994897Sopenharmony_ci        char c = curr_line_->buffer[curr_line_->pos];
234b1994897Sopenharmony_ci
235b1994897Sopenharmony_ci        if (is_escape_seq) {
236b1994897Sopenharmony_ci            is_escape_seq = false;
237b1994897Sopenharmony_ci            continue;
238b1994897Sopenharmony_ci        }
239b1994897Sopenharmony_ci
240b1994897Sopenharmony_ci        if (c == '\\') {
241b1994897Sopenharmony_ci            is_escape_seq = true;
242b1994897Sopenharmony_ci        }
243b1994897Sopenharmony_ci
244b1994897Sopenharmony_ci        if (c == quote) {
245b1994897Sopenharmony_ci            break;
246b1994897Sopenharmony_ci        }
247b1994897Sopenharmony_ci    }
248b1994897Sopenharmony_ci
249b1994897Sopenharmony_ci    if (curr_line_->buffer[curr_line_->pos] != quote) {
250b1994897Sopenharmony_ci        err_ = Error(std::string("Missing terminating ") + quote + " character", 0,
251b1994897Sopenharmony_ci                     Error::ErrorType::ERR_STRING_MISSING_TERMINATING_CHARACTER, "", begin, curr_line_->pos,
252b1994897Sopenharmony_ci                     curr_line_->buffer);
253b1994897Sopenharmony_ci        return false;
254b1994897Sopenharmony_ci    }
255b1994897Sopenharmony_ci
256b1994897Sopenharmony_ci    ++(curr_line_->pos);
257b1994897Sopenharmony_ci
258b1994897Sopenharmony_ci    return true;
259b1994897Sopenharmony_ci}
260b1994897Sopenharmony_ci
261b1994897Sopenharmony_ci/*
262b1994897Sopenharmony_ci * Tokens handling: set a corresponding
263b1994897Sopenharmony_ci * elements bound_left and bound_right of the array tokens
264b1994897Sopenharmony_ci * to the first and last characters of a corresponding token.
265b1994897Sopenharmony_ci *
266b1994897Sopenharmony_ci *                                                  bound_r1   bound_r2    bound_r3
267b1994897Sopenharmony_ci *                                                  |          |           |
268b1994897Sopenharmony_ci *                                                  v          v           v
269b1994897Sopenharmony_ci *       token1 token2 token3 ...             token1     token2      token3 ...
270b1994897Sopenharmony_ci *                                       =>   ^          ^           ^
271b1994897Sopenharmony_ci *                                            |          |           |
272b1994897Sopenharmony_ci *    bound1    bound2    bound3 ...          bound_l1   bound_l2    bound_l3 ...
273b1994897Sopenharmony_ci *
274b1994897Sopenharmony_ci */
275b1994897Sopenharmony_civoid Lexer::LexTokens()
276b1994897Sopenharmony_ci{
277b1994897Sopenharmony_ci    if (Eol()) {
278b1994897Sopenharmony_ci        return;
279b1994897Sopenharmony_ci    }
280b1994897Sopenharmony_ci
281b1994897Sopenharmony_ci    LOG(DEBUG, ASSEMBLER) << "token search started (line " << lines_.size() << "): "
282b1994897Sopenharmony_ci                          << std::string_view(&*(curr_line_->buffer.begin() + curr_line_->pos),
283b1994897Sopenharmony_ci                                              curr_line_->end - curr_line_->pos);
284b1994897Sopenharmony_ci
285b1994897Sopenharmony_ci    while (curr_line_->end > curr_line_->pos && isspace(curr_line_->buffer[curr_line_->end - 1]) != 0) {
286b1994897Sopenharmony_ci        --(curr_line_->end);
287b1994897Sopenharmony_ci    }
288b1994897Sopenharmony_ci
289b1994897Sopenharmony_ci    while (isspace(curr_line_->buffer[curr_line_->pos]) != 0 && !Eol()) {
290b1994897Sopenharmony_ci        ++(curr_line_->pos);
291b1994897Sopenharmony_ci    }
292b1994897Sopenharmony_ci
293b1994897Sopenharmony_ci    size_t bound_right;
294b1994897Sopenharmony_ci
295b1994897Sopenharmony_ci    size_t bound_left;
296b1994897Sopenharmony_ci
297b1994897Sopenharmony_ci    for (int i = 0; !Eol(); ++i) {
298b1994897Sopenharmony_ci        bound_left = curr_line_->pos;
299b1994897Sopenharmony_ci
300b1994897Sopenharmony_ci        if (FindDelim(curr_line_->buffer[curr_line_->pos]) != Token::Type::ID_BAD) {
301b1994897Sopenharmony_ci            ++(curr_line_->pos);
302b1994897Sopenharmony_ci        } else if (IsQuote(curr_line_->buffer[curr_line_->pos])) {
303b1994897Sopenharmony_ci            if (!LexString()) {
304b1994897Sopenharmony_ci                return;
305b1994897Sopenharmony_ci            }
306b1994897Sopenharmony_ci        } else {
307b1994897Sopenharmony_ci            while (!Eol() && FindDelim(curr_line_->buffer[curr_line_->pos]) == Token::Type::ID_BAD &&
308b1994897Sopenharmony_ci                   isspace(curr_line_->buffer[curr_line_->pos]) == 0) {
309b1994897Sopenharmony_ci                ++(curr_line_->pos);
310b1994897Sopenharmony_ci            }
311b1994897Sopenharmony_ci        }
312b1994897Sopenharmony_ci
313b1994897Sopenharmony_ci        bound_right = curr_line_->pos;
314b1994897Sopenharmony_ci
315b1994897Sopenharmony_ci        LOG(DEBUG, ASSEMBLER) << "token identified (line " << lines_.size() << ", "
316b1994897Sopenharmony_ci                              << "token " << curr_line_->tokens.size() + 1 << "): "
317b1994897Sopenharmony_ci                              << std::string_view(&*(curr_line_->buffer.begin() + bound_left), bound_right - bound_left)
318b1994897Sopenharmony_ci                              << " ("
319b1994897Sopenharmony_ci                              << "type: " << TokenTypeWhat(LexGetType(bound_left, bound_right)) << ")";
320b1994897Sopenharmony_ci
321b1994897Sopenharmony_ci        curr_line_->tokens.emplace_back(bound_left, bound_right, LexGetType(bound_left, bound_right),
322b1994897Sopenharmony_ci                                        curr_line_->buffer);
323b1994897Sopenharmony_ci
324b1994897Sopenharmony_ci        while (isspace(curr_line_->buffer[curr_line_->pos]) != 0 && !Eol()) {
325b1994897Sopenharmony_ci            ++(curr_line_->pos);
326b1994897Sopenharmony_ci        }
327b1994897Sopenharmony_ci    }
328b1994897Sopenharmony_ci
329b1994897Sopenharmony_ci    LOG(DEBUG, ASSEMBLER) << "all tokens identified (line " << lines_.size() << ")";
330b1994897Sopenharmony_ci}
331b1994897Sopenharmony_ci
332b1994897Sopenharmony_ci/*
333b1994897Sopenharmony_ci * Ignore comments:
334b1994897Sopenharmony_ci * find PARSE_COMMENT_MARKER and move line->end
335b1994897Sopenharmony_ci * to another position (next after the last character of the last
336b1994897Sopenharmony_ci * significant (this is no a comment) element in a current
337b1994897Sopenharmony_ci * line: line->buffer).
338b1994897Sopenharmony_ci *
339b1994897Sopenharmony_ci * Ex:
340b1994897Sopenharmony_ci *   [Label:] operation operand[,operand] [# comment]
341b1994897Sopenharmony_ci *
342b1994897Sopenharmony_ci *   L1: mov v0, v1 # moving!        L1: mov v0, v1 # moving!
343b1994897Sopenharmony_ci *                          ^   =>                 ^
344b1994897Sopenharmony_ci *                          |                      |
345b1994897Sopenharmony_ci *                         end                    end
346b1994897Sopenharmony_ci */
347b1994897Sopenharmony_civoid Lexer::LexPreprocess()
348b1994897Sopenharmony_ci{
349b1994897Sopenharmony_ci    LOG(DEBUG, ASSEMBLER) << "started removing comments (line " << lines_.size() << "): "
350b1994897Sopenharmony_ci                          << std::string_view(&*(curr_line_->buffer.begin() + curr_line_->pos),
351b1994897Sopenharmony_ci                                              curr_line_->end - curr_line_->pos);
352b1994897Sopenharmony_ci
353b1994897Sopenharmony_ci    // Searching for comment marker located outside of string literals.
354b1994897Sopenharmony_ci    bool inside_str_lit = curr_line_->buffer.size() > 0 && curr_line_->buffer[0] == '\"';
355b1994897Sopenharmony_ci    size_t cmt_pos = curr_line_->buffer.find_first_of("\"#", 0);
356b1994897Sopenharmony_ci    if (cmt_pos != std::string::npos) {
357b1994897Sopenharmony_ci        do {
358b1994897Sopenharmony_ci            if (cmt_pos != 0 && curr_line_->buffer[cmt_pos - 1] != '\\' && curr_line_->buffer[cmt_pos] == '\"') {
359b1994897Sopenharmony_ci                inside_str_lit = !inside_str_lit;
360b1994897Sopenharmony_ci            } else if (curr_line_->buffer[cmt_pos] == PARSE_COMMENT_MARKER && !inside_str_lit) {
361b1994897Sopenharmony_ci                break;
362b1994897Sopenharmony_ci            }
363b1994897Sopenharmony_ci        } while ((cmt_pos = curr_line_->buffer.find_first_of("\"#", cmt_pos + 1)) != std::string::npos);
364b1994897Sopenharmony_ci    }
365b1994897Sopenharmony_ci
366b1994897Sopenharmony_ci    if (cmt_pos != std::string::npos) {
367b1994897Sopenharmony_ci        curr_line_->end = cmt_pos;
368b1994897Sopenharmony_ci    }
369b1994897Sopenharmony_ci
370b1994897Sopenharmony_ci    while (curr_line_->end > curr_line_->pos && isspace(curr_line_->buffer[curr_line_->end - 1]) != 0) {
371b1994897Sopenharmony_ci        --(curr_line_->end);
372b1994897Sopenharmony_ci    }
373b1994897Sopenharmony_ci
374b1994897Sopenharmony_ci    LOG(DEBUG, ASSEMBLER) << "comments removed (line " << lines_.size() << "): "
375b1994897Sopenharmony_ci                          << std::string_view(&*(curr_line_->buffer.begin() + curr_line_->pos),
376b1994897Sopenharmony_ci                                              curr_line_->end - curr_line_->pos);
377b1994897Sopenharmony_ci}
378b1994897Sopenharmony_ci
379b1994897Sopenharmony_civoid Lexer::SkipSpace()
380b1994897Sopenharmony_ci{
381b1994897Sopenharmony_ci    while (!Eol() && isspace(curr_line_->buffer[curr_line_->pos]) != 0) {
382b1994897Sopenharmony_ci        ++(curr_line_->pos);
383b1994897Sopenharmony_ci    }
384b1994897Sopenharmony_ci}
385b1994897Sopenharmony_ci
386b1994897Sopenharmony_civoid Lexer::AnalyzeLine()
387b1994897Sopenharmony_ci{
388b1994897Sopenharmony_ci    LexPreprocess();
389b1994897Sopenharmony_ci
390b1994897Sopenharmony_ci    SkipSpace();
391b1994897Sopenharmony_ci
392b1994897Sopenharmony_ci    LexTokens();
393b1994897Sopenharmony_ci}
394b1994897Sopenharmony_ci
395b1994897Sopenharmony_ci/*-------------------------------*/
396b1994897Sopenharmony_ci
397b1994897Sopenharmony_ci}  // namespace panda::pandasm
398