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#ifndef ASSEMBLER_ASSEMBLY_PARSER_H 17b1994897Sopenharmony_ci#define ASSEMBLER_ASSEMBLY_PARSER_H 18b1994897Sopenharmony_ci 19b1994897Sopenharmony_ci#include <iostream> 20b1994897Sopenharmony_ci#include <memory> 21b1994897Sopenharmony_ci#include <string> 22b1994897Sopenharmony_ci#include <string_view> 23b1994897Sopenharmony_ci 24b1994897Sopenharmony_ci#include "assembly-context.h" 25b1994897Sopenharmony_ci#include "assembly-emitter.h" 26b1994897Sopenharmony_ci#include "assembly-field.h" 27b1994897Sopenharmony_ci#include "assembly-function.h" 28b1994897Sopenharmony_ci#include "assembly-ins.h" 29b1994897Sopenharmony_ci#include "assembly-label.h" 30b1994897Sopenharmony_ci#include "assembly-program.h" 31b1994897Sopenharmony_ci#include "assembly-record.h" 32b1994897Sopenharmony_ci#include "assembly-type.h" 33b1994897Sopenharmony_ci#include "define.h" 34b1994897Sopenharmony_ci#include "error.h" 35b1994897Sopenharmony_ci#include "ide_helpers.h" 36b1994897Sopenharmony_ci#include "lexer.h" 37b1994897Sopenharmony_ci#include "meta.h" 38b1994897Sopenharmony_ci#include "utils/expected.h" 39b1994897Sopenharmony_ci 40b1994897Sopenharmony_cinamespace panda::pandasm { 41b1994897Sopenharmony_ci 42b1994897Sopenharmony_ciusing Instructions = std::pair<std::vector<Ins>, Error>; 43b1994897Sopenharmony_ci 44b1994897Sopenharmony_ciusing Functions = std::pair<std::unordered_map<std::string, Function>, std::unordered_map<std::string, Record>>; 45b1994897Sopenharmony_ci 46b1994897Sopenharmony_ciclass Parser { 47b1994897Sopenharmony_cipublic: 48b1994897Sopenharmony_ci Parser() = default; 49b1994897Sopenharmony_ci 50b1994897Sopenharmony_ci NO_MOVE_SEMANTIC(Parser); 51b1994897Sopenharmony_ci NO_COPY_SEMANTIC(Parser); 52b1994897Sopenharmony_ci 53b1994897Sopenharmony_ci ~Parser() = default; 54b1994897Sopenharmony_ci 55b1994897Sopenharmony_ci /* 56b1994897Sopenharmony_ci * The main function of parsing, which takes a vector of token vectors and a name of the source file. 57b1994897Sopenharmony_ci * Returns a program or an error value: Expected<Program, Error> 58b1994897Sopenharmony_ci * This function analyzes code containing several functions: 59b1994897Sopenharmony_ci * - Each function used must be declared. 60b1994897Sopenharmony_ci * - The correct function declaration looks like this: .function ret_type fun_name([param_type aN,]) [<metadata>] 61b1994897Sopenharmony_ci * ([data] shows that this 'data' is optional). 62b1994897Sopenharmony_ci * - N in function parameters must increase when number of parameters increases 63b1994897Sopenharmony_ci * (Possible: a0, a1,..., aN. Impossible: a1, a10, a13). 64b1994897Sopenharmony_ci * - Each function has its own label table. 65b1994897Sopenharmony_ci */ 66b1994897Sopenharmony_ci Expected<Program, Error> Parse(TokenSet &vectors_tokens, const std::string &file_name = ""); 67b1994897Sopenharmony_ci 68b1994897Sopenharmony_ci /* 69b1994897Sopenharmony_ci * The main function of parsing, which takes a string with source and a name of the source file. 70b1994897Sopenharmony_ci * Returns a program or an error value: Expected<Program, Error> 71b1994897Sopenharmony_ci */ 72b1994897Sopenharmony_ci Expected<Program, Error> Parse(const std::string &source, const std::string &file_name = ""); 73b1994897Sopenharmony_ci 74b1994897Sopenharmony_ci /* 75b1994897Sopenharmony_ci * Returns a set error 76b1994897Sopenharmony_ci */ 77b1994897Sopenharmony_ci Error ShowError() const 78b1994897Sopenharmony_ci { 79b1994897Sopenharmony_ci return err_; 80b1994897Sopenharmony_ci } 81b1994897Sopenharmony_ci 82b1994897Sopenharmony_ci ErrorList ShowWarnings() const 83b1994897Sopenharmony_ci { 84b1994897Sopenharmony_ci return war_; 85b1994897Sopenharmony_ci } 86b1994897Sopenharmony_ci 87b1994897Sopenharmony_ciprivate: 88b1994897Sopenharmony_ci panda::pandasm::Program program_; 89b1994897Sopenharmony_ci std::unordered_map<std::string, panda::pandasm::Label> *label_table_ = nullptr; 90b1994897Sopenharmony_ci Metadata *metadata_ = nullptr; 91b1994897Sopenharmony_ci Context context_; /* token iterator */ 92b1994897Sopenharmony_ci panda::pandasm::Record *curr_record_ = nullptr; 93b1994897Sopenharmony_ci panda::pandasm::LiteralArray *curr_array_ = nullptr; 94b1994897Sopenharmony_ci panda::pandasm::LiteralArray::Literal *curr_array_elem_ = nullptr; 95b1994897Sopenharmony_ci panda::pandasm::Function *curr_func_ = nullptr; 96b1994897Sopenharmony_ci panda::pandasm::Ins *curr_ins_ = nullptr; 97b1994897Sopenharmony_ci panda::pandasm::Field *curr_fld_ = nullptr; 98b1994897Sopenharmony_ci size_t line_stric_ = 0; 99b1994897Sopenharmony_ci panda::pandasm::Error err_; 100b1994897Sopenharmony_ci panda::pandasm::ErrorList war_; 101b1994897Sopenharmony_ci bool open_ = false; /* flag of being in a code section */ 102b1994897Sopenharmony_ci bool record_def_ = false; 103b1994897Sopenharmony_ci bool array_def_ = false; 104b1994897Sopenharmony_ci bool func_def_ = false; 105b1994897Sopenharmony_ci static constexpr uint32_t INTRO_CONST_ARRAY_LITERALS_NUMBER = 2; 106b1994897Sopenharmony_ci 107b1994897Sopenharmony_ci inline Error GetError(const std::string &mess = "", Error::ErrorType err = Error::ErrorType::ERR_NONE, 108b1994897Sopenharmony_ci int8_t shift = 0, int token_shift = 0, const std::string &add_mess = "") const 109b1994897Sopenharmony_ci { 110b1994897Sopenharmony_ci return Error(mess, line_stric_, err, add_mess, 111b1994897Sopenharmony_ci context_.tokens[static_cast<int>(context_.number) + token_shift - 1].bound_left + shift, 112b1994897Sopenharmony_ci context_.tokens[static_cast<int>(context_.number) + token_shift - 1].bound_right, 113b1994897Sopenharmony_ci context_.tokens[static_cast<int>(context_.number) + token_shift - 1].whole_line); 114b1994897Sopenharmony_ci } 115b1994897Sopenharmony_ci 116b1994897Sopenharmony_ci inline void GetWarning(const std::string &mess = "", Error::ErrorType err = Error::ErrorType::ERR_NONE, 117b1994897Sopenharmony_ci int8_t shift = 0, const std::string &add_mess = "") 118b1994897Sopenharmony_ci { 119b1994897Sopenharmony_ci war_.emplace_back(mess, line_stric_, err, add_mess, 120b1994897Sopenharmony_ci context_.tokens[context_.number - 1].bound_left + static_cast<size_t>(shift), 121b1994897Sopenharmony_ci context_.tokens[context_.number - 1].bound_right, 122b1994897Sopenharmony_ci context_.tokens[context_.number - 1].whole_line, Error::ErrorClass::WARNING); 123b1994897Sopenharmony_ci } 124b1994897Sopenharmony_ci 125b1994897Sopenharmony_ci SourcePosition GetCurrentPosition(bool left_bound) const 126b1994897Sopenharmony_ci { 127b1994897Sopenharmony_ci if (left_bound) { 128b1994897Sopenharmony_ci return SourcePosition {line_stric_, context_.tokens[context_.number - 1].bound_left}; 129b1994897Sopenharmony_ci } 130b1994897Sopenharmony_ci return SourcePosition {line_stric_, context_.tokens[context_.number - 1].bound_right}; 131b1994897Sopenharmony_ci } 132b1994897Sopenharmony_ci 133b1994897Sopenharmony_ci bool LabelValidName(); 134b1994897Sopenharmony_ci bool TypeValidName(); 135b1994897Sopenharmony_ci bool RegValidName(); 136b1994897Sopenharmony_ci bool ParamValidName(); 137b1994897Sopenharmony_ci bool FunctionValidName(); 138b1994897Sopenharmony_ci bool ParseFunctionName(); 139b1994897Sopenharmony_ci bool ParseLabel(); 140b1994897Sopenharmony_ci bool ParseOperation(); 141b1994897Sopenharmony_ci bool ParseOperands(); 142b1994897Sopenharmony_ci bool ParseFunctionCode(); 143b1994897Sopenharmony_ci bool ParseFunctionInstruction(); 144b1994897Sopenharmony_ci bool ParseFunctionFullSign(); 145b1994897Sopenharmony_ci bool UpdateFunctionName(); 146b1994897Sopenharmony_ci bool ParseFunctionReturn(); 147b1994897Sopenharmony_ci bool ParseFunctionArg(); 148b1994897Sopenharmony_ci bool ParseFunctionArgComma(bool &comma); 149b1994897Sopenharmony_ci bool ParseFunctionArgs(); 150b1994897Sopenharmony_ci bool ParseType(Type *type); 151b1994897Sopenharmony_ci bool PrefixedValidName(); 152b1994897Sopenharmony_ci bool ParseMetaListComma(bool &comma, bool eq); 153b1994897Sopenharmony_ci bool MeetExpMetaList(bool eq); 154b1994897Sopenharmony_ci bool BuildMetaListAttr(bool &eq, std::string &attribute_name, std::string &attribute_value); 155b1994897Sopenharmony_ci bool ParseMetaList(bool flag); 156b1994897Sopenharmony_ci bool ParseMetaDef(); 157b1994897Sopenharmony_ci bool ParseRecordFullSign(); 158b1994897Sopenharmony_ci bool ParseRecordFields(); 159b1994897Sopenharmony_ci bool ParseRecordField(); 160b1994897Sopenharmony_ci bool ParseRecordName(); 161b1994897Sopenharmony_ci bool RecordValidName(); 162b1994897Sopenharmony_ci bool ParseArrayFullSign(); 163b1994897Sopenharmony_ci bool IsConstArray(); 164b1994897Sopenharmony_ci bool ParseArrayName(); 165b1994897Sopenharmony_ci bool ArrayValidName(); 166b1994897Sopenharmony_ci bool ArrayElementsValidNumber(); 167b1994897Sopenharmony_ci bool ParseArrayElements(); 168b1994897Sopenharmony_ci bool ParseArrayElement(); 169b1994897Sopenharmony_ci bool ParseArrayElementType(); 170b1994897Sopenharmony_ci bool ParseArrayElementValue(); 171b1994897Sopenharmony_ci bool ParseArrayElementValueInteger(); 172b1994897Sopenharmony_ci bool ParseArrayElementValueFloat(); 173b1994897Sopenharmony_ci bool ParseArrayElementValueString(); 174b1994897Sopenharmony_ci bool ParseFieldName(); 175b1994897Sopenharmony_ci bool ParseFieldType(); 176b1994897Sopenharmony_ci std::optional<std::string> ParseStringLiteral(); 177b1994897Sopenharmony_ci int64_t MnemonicToBuiltinId(); 178b1994897Sopenharmony_ci 179b1994897Sopenharmony_ci bool ParseInteger(int64_t *value); 180b1994897Sopenharmony_ci bool ParseFloat(double *value, bool is_64bit); 181b1994897Sopenharmony_ci bool ParseOperandVreg(); 182b1994897Sopenharmony_ci bool ParseOperandComma(); 183b1994897Sopenharmony_ci bool ParseOperandInteger(); 184b1994897Sopenharmony_ci bool ParseOperandFloat(bool is_64bit); 185b1994897Sopenharmony_ci bool ParseOperandId(); 186b1994897Sopenharmony_ci bool ParseOperandLabel(); 187b1994897Sopenharmony_ci bool ParseOperandField(); 188b1994897Sopenharmony_ci bool ParseOperandType(Type::VerificationType ver_type); 189b1994897Sopenharmony_ci bool ParseOperandNone(); 190b1994897Sopenharmony_ci bool ParseOperandString(); 191b1994897Sopenharmony_ci bool ParseOperandLiteralArray(); 192b1994897Sopenharmony_ci bool ParseOperandCall(); 193b1994897Sopenharmony_ci bool ParseOperandSignature(std::string *sign); 194b1994897Sopenharmony_ci bool ParseOperandSignatureTypesList(std::string *sign); 195b1994897Sopenharmony_ci bool ParseOperandBuiltinMnemonic(); 196b1994897Sopenharmony_ci 197b1994897Sopenharmony_ci void SetFunctionInformation(); 198b1994897Sopenharmony_ci void SetRecordInformation(); 199b1994897Sopenharmony_ci void SetArrayInformation(); 200b1994897Sopenharmony_ci void SetOperationInformation(); 201b1994897Sopenharmony_ci void ParseAsCatchall(const std::vector<Token> &tokens); 202b1994897Sopenharmony_ci void ParseAsLanguage(const std::vector<Token> &tokens, bool &is_lang_parsed, bool &is_first_statement); 203b1994897Sopenharmony_ci void ParseAsRecord(const std::vector<Token> &tokens); 204b1994897Sopenharmony_ci void ParseAsArray(const std::vector<Token> &tokens); 205b1994897Sopenharmony_ci void ParseAsFunction(const std::vector<Token> &tokens); 206b1994897Sopenharmony_ci void ParseAsBraceRight(const std::vector<Token> &tokens); 207b1994897Sopenharmony_ci bool ParseAfterLine(bool &is_first_statement); 208b1994897Sopenharmony_ci Expected<Program, Error> ParseAfterMainLoop(const std::string &file_name); 209b1994897Sopenharmony_ci void ParseResetFunctionLabelsAndParams(); 210b1994897Sopenharmony_ci void ParseResetTables(); 211b1994897Sopenharmony_ci void ParseResetFunctionTable(); 212b1994897Sopenharmony_ci void ParseResetRecordTable(); 213b1994897Sopenharmony_ci void ParseResetArrayTable(); 214b1994897Sopenharmony_ci void ParseAsLanguageDirective(); 215b1994897Sopenharmony_ci Function::CatchBlock PrepareCatchBlock(bool is_catchall, size_t size, size_t catchall_tokens_num, 216b1994897Sopenharmony_ci size_t catch_tokens_num); 217b1994897Sopenharmony_ci void ParseAsCatchDirective(); 218b1994897Sopenharmony_ci void SetError(); 219b1994897Sopenharmony_ci void SetMetadataContextError(const Metadata::Error &err, bool has_value); 220b1994897Sopenharmony_ci 221b1994897Sopenharmony_ci Expected<char, Error> ParseOctalEscapeSequence(std::string_view s, size_t *i); 222b1994897Sopenharmony_ci Expected<char, Error> ParseHexEscapeSequence(std::string_view s, size_t *i); 223b1994897Sopenharmony_ci Expected<char, Error> ParseEscapeSequence(std::string_view s, size_t *i); 224b1994897Sopenharmony_ci 225b1994897Sopenharmony_ci template <class T> 226b1994897Sopenharmony_ci auto TryEmplaceInTable(bool flag, T &item) 227b1994897Sopenharmony_ci { 228b1994897Sopenharmony_ci return item.try_emplace(std::string(context_.GiveToken().data(), context_.GiveToken().length()), 229b1994897Sopenharmony_ci std::string(context_.GiveToken().data(), context_.GiveToken().length()), program_.lang, 230b1994897Sopenharmony_ci context_.tokens[context_.number - 1].bound_left, 231b1994897Sopenharmony_ci context_.tokens[context_.number - 1].bound_right, 232b1994897Sopenharmony_ci context_.tokens[context_.number - 1].whole_line, flag, line_stric_); 233b1994897Sopenharmony_ci } 234b1994897Sopenharmony_ci 235b1994897Sopenharmony_ci template <class T> 236b1994897Sopenharmony_ci bool AddObjectInTable(bool flag, T &item) 237b1994897Sopenharmony_ci { 238b1994897Sopenharmony_ci auto [iter, is_inserted] = TryEmplaceInTable(flag, item); 239b1994897Sopenharmony_ci 240b1994897Sopenharmony_ci if (is_inserted) { 241b1994897Sopenharmony_ci return true; 242b1994897Sopenharmony_ci } 243b1994897Sopenharmony_ci 244b1994897Sopenharmony_ci if (iter->second.file_location->is_defined && flag) { 245b1994897Sopenharmony_ci return false; 246b1994897Sopenharmony_ci } 247b1994897Sopenharmony_ci 248b1994897Sopenharmony_ci if (!iter->second.file_location->is_defined && flag) { 249b1994897Sopenharmony_ci iter->second.file_location->is_defined = true; 250b1994897Sopenharmony_ci return true; 251b1994897Sopenharmony_ci } 252b1994897Sopenharmony_ci 253b1994897Sopenharmony_ci if (!iter->second.file_location->is_defined) { 254b1994897Sopenharmony_ci iter->second.file_location->bound_left = context_.tokens[context_.number - 1].bound_left; 255b1994897Sopenharmony_ci iter->second.file_location->bound_right = context_.tokens[context_.number - 1].bound_right; 256b1994897Sopenharmony_ci iter->second.file_location->whole_line = context_.tokens[context_.number - 1].whole_line; 257b1994897Sopenharmony_ci iter->second.file_location->line_number = line_stric_; 258b1994897Sopenharmony_ci } 259b1994897Sopenharmony_ci 260b1994897Sopenharmony_ci return true; 261b1994897Sopenharmony_ci } 262b1994897Sopenharmony_ci}; 263b1994897Sopenharmony_ci 264b1994897Sopenharmony_citemplate <> 265b1994897Sopenharmony_ciinline auto Parser::TryEmplaceInTable(bool flag, std::unordered_map<std::string, panda::pandasm::Label> &item) 266b1994897Sopenharmony_ci{ 267b1994897Sopenharmony_ci return item.try_emplace(std::string(context_.GiveToken().data(), context_.GiveToken().length()), 268b1994897Sopenharmony_ci std::string(context_.GiveToken().data(), context_.GiveToken().length()), 269b1994897Sopenharmony_ci context_.tokens[context_.number - 1].bound_left, 270b1994897Sopenharmony_ci context_.tokens[context_.number - 1].bound_right, 271b1994897Sopenharmony_ci context_.tokens[context_.number - 1].whole_line, flag, line_stric_); 272b1994897Sopenharmony_ci} 273b1994897Sopenharmony_ci 274b1994897Sopenharmony_ci} // namespace panda::pandasm 275b1994897Sopenharmony_ci 276b1994897Sopenharmony_ci#endif // ASSEMBLER_ASSEMBLY_PARSER_H 277