brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.5 KiB · 1e7618c Raw
200 lines · c
1//===-- ResourceScriptParser.h ----------------------------------*- C++-*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===---------------------------------------------------------------------===//8//9// This defines the RC scripts parser. It takes a sequence of RC tokens10// and then provides the method to parse the resources one by one.11//12//===---------------------------------------------------------------------===//13 14#ifndef LLVM_TOOLS_LLVMRC_RESOURCESCRIPTPARSER_H15#define LLVM_TOOLS_LLVMRC_RESOURCESCRIPTPARSER_H16 17#include "ResourceScriptStmt.h"18#include "ResourceScriptToken.h"19 20#include "llvm/Support/Compiler.h"21#include "llvm/Support/StringSaver.h"22#include "llvm/Support/raw_ostream.h"23 24#include <system_error>25#include <vector>26 27namespace llvm {28namespace rc {29 30class RCParser {31public:32  using LocIter = std::vector<RCToken>::iterator;33  using ParseType = Expected<std::unique_ptr<RCResource>>;34  using ParseOptionType = Expected<std::unique_ptr<OptionalStmt>>;35 36  // Class describing a single failure of parser.37  class ParserError : public ErrorInfo<ParserError> {38  public:39    ParserError(const Twine &Expected, const LocIter CurLoc, const LocIter End);40 41    void log(raw_ostream &OS) const override { OS << CurMessage; }42    std::error_code convertToErrorCode() const override {43      return std::make_error_code(std::errc::invalid_argument);44    }45    const std::string &getMessage() const { return CurMessage; }46 47    static char ID; // Keep llvm::Error happy.48 49  private:50    std::string CurMessage;51    LocIter ErrorLoc, FileEnd;52  };53 54  explicit RCParser(std::vector<RCToken> TokenList);55 56  // Reads and returns a single resource definition, or error message if any57  // occurred.58  ParseType parseSingleResource();59 60  bool isEof() const;61 62private:63  using Kind = RCToken::Kind;64 65  // Checks if the current parser state points to the token of type TokenKind.66  bool isNextTokenKind(Kind TokenKind) const;67 68  // These methods assume that the parser is not in EOF state.69 70  // Take a look at the current token. Do not fetch it.71  const RCToken &look() const;72  // Read the current token and advance the state by one token.73  const RCToken &read();74  // Advance the state by one token, discarding the current token.75  void consume();76 77  // The following methods try to read a single token, check if it has the78  // correct type and then parse it.79  // Each integer can be written as an arithmetic expression producing an80  // unsigned 32-bit integer.81  Expected<RCInt> readInt();               // Parse an integer.82  Expected<StringRef> readString();        // Parse a string.83  Expected<StringRef> readIdentifier();    // Parse an identifier.84  Expected<StringRef> readFilename();      // Parse a filename.85  Expected<IntOrString> readIntOrString(); // Parse an integer or a string.86  Expected<IntOrString> readTypeOrName();  // Parse an integer or an identifier.87 88  // Helper integer expression parsing methods.89  Expected<IntWithNotMask> parseIntExpr1();90  Expected<IntWithNotMask> parseIntExpr2();91  Expected<IntWithNotMask> parseIntExpr3();92 93  // Advance the state by one, discarding the current token.94  // If the discarded token had an incorrect type, fail.95  Error consumeType(Kind TokenKind);96 97  // Check the current token type. If it's TokenKind, discard it.98  // Return true if the parser consumed this token successfully.99  bool consumeOptionalType(Kind TokenKind);100 101  // Read at least MinCount, and at most MaxCount integers separated by102  // commas. The parser stops reading after fetching MaxCount integers103  // or after an error occurs. Whenever the parser reads a comma, it104  // expects an integer to follow.105  Expected<SmallVector<RCInt, 8>> readIntsWithCommas(size_t MinCount,106                                                     size_t MaxCount);107 108  // Read an unknown number of flags preceded by commas. Each correct flag109  // has an entry in FlagDesc array of length NumFlags. In case i-th110  // flag (0-based) has been read, the result is OR-ed with FlagValues[i].111  // As long as parser has a comma to read, it expects to be fed with112  // a correct flag afterwards.113  Expected<uint32_t> parseFlags(ArrayRef<StringRef> FlagDesc,114                                ArrayRef<uint32_t> FlagValues);115 116  // Reads a set of optional statements. These can change the behavior of117  // a number of resource types (e.g. STRINGTABLE, MENU or DIALOG) if provided118  // before the main block with the contents of the resource.119  // Usually, resources use a basic set of optional statements:120  //    CHARACTERISTICS, LANGUAGE, VERSION121  // However, DIALOG and DIALOGEX extend this list by the following items:122  //    CAPTION, CLASS, EXSTYLE, FONT, MENU, STYLE123  // UseExtendedStatements flag (off by default) allows the parser to read124  // the additional types of statements.125  //126  // Ref (to the list of all optional statements):127  //    msdn.microsoft.com/en-us/library/windows/desktop/aa381002(v=vs.85).aspx128  enum class OptStmtType { BasicStmt, DialogStmt, DialogExStmt };129 130  uint16_t parseMemoryFlags(uint16_t DefaultFlags);131 132  Expected<OptionalStmtList>133  parseOptionalStatements(OptStmtType StmtsType = OptStmtType::BasicStmt);134 135  // Read a single optional statement.136  Expected<std::unique_ptr<OptionalStmt>>137  parseSingleOptionalStatement(OptStmtType StmtsType = OptStmtType::BasicStmt);138 139  // Top-level resource parsers.140  ParseType parseLanguageResource();141  ParseType parseAcceleratorsResource();142  ParseType parseBitmapResource();143  ParseType parseCursorResource();144  ParseType parseDialogResource(bool IsExtended);145  ParseType parseIconResource();146  ParseType parseHTMLResource();147  ParseType parseMenuResource();148  ParseType parseMenuExResource();149  ParseType parseStringTableResource();150  ParseType parseUserDefinedResource(IntOrString Type);151  ParseType parseVersionInfoResource();152 153  // Helper DIALOG parser - a single control.154  Expected<Control> parseControl();155 156  // Helper MENU parser.157  Expected<MenuDefinitionList> parseMenuItemsList();158 159  // Helper MENUEX parser.160  Expected<MenuDefinitionList> parseMenuExItemsList();161 162  // Helper VERSIONINFO parser - read the contents of a single BLOCK statement,163  // from BEGIN to END.164  Expected<std::unique_ptr<VersionInfoBlock>>165  parseVersionInfoBlockContents(StringRef BlockName);166  // Helper VERSIONINFO parser - read either VALUE or BLOCK statement.167  Expected<std::unique_ptr<VersionInfoStmt>> parseVersionInfoStmt();168  // Helper VERSIONINFO parser - read fixed VERSIONINFO statements.169  Expected<VersionInfoResource::VersionInfoFixed> parseVersionInfoFixed();170 171  // Optional statement parsers.172  ParseOptionType parseLanguageStmt();173  ParseOptionType parseCharacteristicsStmt();174  ParseOptionType parseVersionStmt();175  ParseOptionType parseCaptionStmt();176  ParseOptionType parseClassStmt();177  ParseOptionType parseExStyleStmt();178  ParseOptionType parseFontStmt(OptStmtType DialogType);179  ParseOptionType parseStyleStmt();180  ParseOptionType parseMenuStmt();181 182  // Raises an error. If IsAlreadyRead = false (default), this complains about183  // the token that couldn't be parsed. If the flag is on, this complains about184  // the correctly read token that makes no sense (that is, the current parser185  // state is beyond the erroneous token.)186  Error getExpectedError(const Twine &Message, bool IsAlreadyRead = false);187 188  std::vector<RCToken> Tokens;189  LocIter CurLoc;190  const LocIter End;191 192  BumpPtrAllocator Alloc;193  StringSaver Saver{Alloc};194};195 196} // namespace rc197} // namespace llvm198 199#endif200