| 43 | } |
| 44 | |
| 45 | std::unique_ptr<Record> MIParser::parse(FileSymbol *file) |
| 46 | { |
| 47 | m_lex = nullptr; |
| 48 | |
| 49 | TokenStream *tokenStream = m_lexer.tokenize(file); |
| 50 | if (!tokenStream) |
| 51 | return nullptr; |
| 52 | |
| 53 | m_lex = file->tokenStream = tokenStream; |
| 54 | |
| 55 | uint32_t token = 0; |
| 56 | if (m_lex->lookAhead() == Token_number_literal) { |
| 57 | token = QString::fromUtf8(m_lex->currentTokenText()).toUInt(); |
| 58 | m_lex->nextToken(); |
| 59 | } |
| 60 | |
| 61 | std::unique_ptr<Record> record; |
| 62 | |
| 63 | switch (m_lex->lookAhead()) { |
| 64 | case '~': |
| 65 | case '@': |
| 66 | case '&': |
| 67 | record = parseStreamRecord(); |
| 68 | break; |
| 69 | case '(': |
| 70 | record = parsePrompt(); |
| 71 | break; |
| 72 | case '^': |
| 73 | case '*': |
| 74 | case '=': |
| 75 | case '+': |
| 76 | record = parseResultOrAsyncRecord(); |
| 77 | break; |
| 78 | default: |
| 79 | break; |
| 80 | } |
| 81 | |
| 82 | if (record && record->kind == Record::Result) { |
| 83 | auto * result = static_cast<ResultRecord *>(record.get()); |
| 84 | result->token = token; |
| 85 | } else { |
| 86 | // NOTE: a non-zero value of the variable `token` is not necessarily an MI token at this point. |
| 87 | // For example, when LLDB-MI resolves a pending breakpoint in a shared library, it sends an invalid |
| 88 | // message like "1 location added to breakpoint 2", in which we incorrectly parse "1" as a token. |
| 89 | } |
| 90 | |
| 91 | return record; |
| 92 | } |
| 93 | |
| 94 | std::unique_ptr<Record> MIParser::parsePrompt() |
| 95 | { |