Source code

Revision control

Copy as Markdown

Other Tools

/*
* Copyright 2016 WebAssembly Community Group participants
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef WABT_WAST_PARSER_H_
#define WABT_WAST_PARSER_H_
#include <array>
#include <memory>
#include <unordered_map>
#include "wabt/circular-array.h"
#include "wabt/error.h"
#include "wabt/feature.h"
#include "wabt/intrusive-list.h"
#include "wabt/ir.h"
#include "wabt/wast-lexer.h"
namespace wabt {
struct WastParseOptions {
WastParseOptions(const Features& features) : features(features) {}
Features features;
bool debug_parsing = false;
};
using TokenTypePair = std::array<TokenType, 2>;
class WastParser {
public:
WastParser(WastLexer*, Errors*, WastParseOptions*);
void WABT_PRINTF_FORMAT(3, 4) Error(Location, const char* format, ...);
Result ParseModule(std::unique_ptr<Module>* out_module);
Result ParseScript(std::unique_ptr<Script>* out_script);
std::unique_ptr<Script> ReleaseScript();
private:
enum class ConstType {
Normal,
Expectation,
};
void ErrorUnlessOpcodeEnabled(const Token&);
// Print an error message listing the expected tokens, as well as an example
// of expected input.
Result ErrorExpected(const std::vector<std::string>& expected,
const char* example = nullptr);
// Print an error message, and and return Result::Error if the next token is
// '('. This is commonly used after parsing a sequence of s-expressions -- if
// no more can be parsed, we know that a following '(' is invalid. This
// function consumes the '(' so a better error message can be provided
// (assuming the following token was unexpected).
Result ErrorIfLpar(const std::vector<std::string>& expected,
const char* example = nullptr);
// Returns the next token without consuming it.
Token GetToken();
// Returns the location of the next token.
Location GetLocation();
// Returns the type of the next token.
TokenType Peek(size_t n = 0);
// Returns the types of the next two tokens.
TokenTypePair PeekPair();
// Returns true if the next token's type is equal to the parameter.
bool PeekMatch(TokenType, size_t n = 0);
// Returns true if the next token's type is '(' and the following token is
// equal to the parameter.
bool PeekMatchLpar(TokenType);
// Returns true if the next two tokens can start an Expr. This allows for
// folded expressions, plain instructions and block instructions.
bool PeekMatchExpr();
// Returns true if the next two tokens are form reference type - (ref $t)
bool PeekMatchRefType();
// Returns true if the next token's type is equal to the parameter. If so,
// then the token is consumed.
bool Match(TokenType);
// Returns true if the next token's type is equal to '(' and the following
// token is equal to the parameter. If so, then the token is consumed.
bool MatchLpar(TokenType);
// Like Match(), but prints an error message if the token doesn't match, and
// returns Result::Error.
Result Expect(TokenType);
// Consume one token and return it.
Token Consume();
// Give the Match() function a clearer name when used to optionally consume a
// token (used for printing better error messages).
void ConsumeIfLpar() { Match(TokenType::Lpar); }
using SynchronizeFunc = bool(*)(TokenTypePair pair);
// Attempt to synchronize the token stream by dropping tokens until the
// SynchronizeFunc returns true, or until a token limit is reached. This
// function returns Result::Error if the stream was not able to be
// synchronized.
Result Synchronize(SynchronizeFunc);
bool ParseBindVarOpt(std::string* name);
Result ParseVar(Var* out_var);
bool ParseVarOpt(Var* out_var, Var default_var = Var());
Result ParseOffsetExpr(ExprList* out_expr_list);
bool ParseOffsetExprOpt(ExprList* out_expr_list);
Result ParseTextList(std::vector<uint8_t>* out_data);
bool ParseTextListOpt(std::vector<uint8_t>* out_data);
Result ParseVarList(VarVector* out_var_list);
bool ParseElemExprOpt(ExprList* out_elem_expr);
bool ParseElemExprListOpt(ExprListVector* out_list);
bool ParseElemExprVarListOpt(ExprListVector* out_list);
Result ParseValueType(Var* out_type);
Result ParseValueTypeList(
TypeVector* out_type_list,
std::unordered_map<uint32_t, std::string>* type_names);
Result ParseRefKind(Type* out_type);
Result ParseRefType(Type* out_type);
bool ParseRefTypeOpt(Type* out_type);
Result ParseQuotedText(std::string* text, bool check_utf8 = true);
bool ParseOffsetOpt(Address* offset);
bool ParseAlignOpt(Address* align);
Result ParseMemidx(Location loc, Var* memidx);
Result ParseLimitsIndex(Limits*);
Result ParseLimits(Limits*);
Result ParseNat(uint64_t*, bool is_64);
Result ParseModuleFieldList(Module*);
Result ParseModuleField(Module*);
Result ParseDataModuleField(Module*);
Result ParseElemModuleField(Module*);
Result ParseTagModuleField(Module*);
Result ParseExportModuleField(Module*);
Result ParseFuncModuleField(Module*);
Result ParseTypeModuleField(Module*);
Result ParseGlobalModuleField(Module*);
Result ParseImportModuleField(Module*);
Result ParseMemoryModuleField(Module*);
Result ParseStartModuleField(Module*);
Result ParseTableModuleField(Module*);
Result ParseExportDesc(Export*);
Result ParseInlineExports(ModuleFieldList*, ExternalKind);
Result ParseInlineImport(Import*);
Result ParseTypeUseOpt(FuncDeclaration*);
Result ParseFuncSignature(FuncSignature*, BindingHash* param_bindings);
Result ParseUnboundFuncSignature(FuncSignature*);
Result ParseBoundValueTypeList(TokenType,
TypeVector*,
BindingHash*,
std::unordered_map<uint32_t, std::string>*,
Index binding_index_offset = 0);
Result ParseUnboundValueTypeList(TokenType,
TypeVector*,
std::unordered_map<uint32_t, std::string>*);
Result ParseResultList(TypeVector*,
std::unordered_map<uint32_t, std::string>*);
Result ParseInstrList(ExprList*);
Result ParseTerminatingInstrList(ExprList*);
Result ParseInstr(ExprList*);
Result ParseCodeMetadataAnnotation(ExprList*);
Result ParsePlainInstr(std::unique_ptr<Expr>*);
Result ParseF32(Const*, ConstType type);
Result ParseF64(Const*, ConstType type);
Result ParseConst(Const*, ConstType type);
Result ParseExpectedValues(ExpectationPtr*);
Result ParseEither(ConstVector*);
Result ParseExternref(Const*);
Result ParseExpectedNan(ExpectedNan* expected);
Result ParseConstList(ConstVector*, ConstType type);
Result ParseBlockInstr(std::unique_ptr<Expr>*);
Result ParseLabelOpt(std::string*);
Result ParseEndLabelOpt(const std::string&);
Result ParseBlockDeclaration(BlockDeclaration*);
Result ParseBlock(Block*);
Result ParseExprList(ExprList*);
Result ParseExpr(ExprList*);
Result ParseCatchInstrList(CatchVector* catches);
Result ParseCatchExprList(CatchVector* catches);
Result ParseGlobalType(Global*);
Result ParseField(Field*);
Result ParseFieldList(std::vector<Field>*);
template <typename T>
Result ParsePlainInstrVar(Location, std::unique_ptr<Expr>*);
template <typename T>
Result ParseMemoryInstrVar(Location, std::unique_ptr<Expr>*);
template <typename T>
Result ParseLoadStoreInstr(Location, Token, std::unique_ptr<Expr>*);
template <typename T>
Result ParseSIMDLoadStoreInstr(Location loc,
Token token,
std::unique_ptr<Expr>* out_expr);
template <typename T>
Result ParseMemoryExpr(Location, std::unique_ptr<Expr>*);
template <typename T>
Result ParseMemoryBinaryExpr(Location, std::unique_ptr<Expr>*);
Result ParseSimdLane(Location, uint64_t*);
Result ParseCommandList(Script*, CommandPtrVector*);
Result ParseCommand(Script*, CommandPtr*);
Result ParseAssertExceptionCommand(CommandPtr*);
Result ParseAssertExhaustionCommand(CommandPtr*);
Result ParseAssertInvalidCommand(CommandPtr*);
Result ParseAssertMalformedCommand(CommandPtr*);
Result ParseAssertReturnCommand(CommandPtr*);
Result ParseAssertReturnFuncCommand(CommandPtr*);
Result ParseAssertTrapCommand(CommandPtr*);
Result ParseAssertUnlinkableCommand(CommandPtr*);
Result ParseActionCommand(CommandPtr*);
Result ParseModuleCommand(Script*, CommandPtr*);
Result ParseRegisterCommand(CommandPtr*);
Result ParseInputCommand(CommandPtr*);
Result ParseOutputCommand(CommandPtr*);
Result ParseAction(ActionPtr*);
Result ParseScriptModule(std::unique_ptr<ScriptModule>*);
template <typename T>
Result ParseActionCommand(TokenType, CommandPtr*);
template <typename T>
Result ParseAssertActionCommand(TokenType, CommandPtr*);
template <typename T>
Result ParseAssertActionTextCommand(TokenType, CommandPtr*);
template <typename T>
Result ParseAssertScriptModuleCommand(TokenType, CommandPtr*);
Result ParseSimdV128Const(Const*, TokenType, ConstType);
void CheckImportOrdering(Module*);
WastLexer* lexer_;
Index last_module_index_ = kInvalidIndex;
Errors* errors_;
WastParseOptions* options_;
CircularArray<Token, 2> tokens_;
};
Result ParseWatModule(WastLexer* lexer,
std::unique_ptr<Module>* out_module,
Errors*,
WastParseOptions* options);
Result ParseWastScript(WastLexer* lexer,
std::unique_ptr<Script>* out_script,
Errors*,
WastParseOptions* options);
} // namespace wabt
#endif /* WABT_WAST_PARSER_H_ */