VapourSynth-llvmexpr
Loading...
Searching...
No Matches
Tokenizer.cpp File Reference
#include "Tokenizer.hpp"
#include "../utils/FixedString.hpp"
#include <algorithm>
#include <array>
#include <charconv>
#include <cmath>
#include <cstdlib>
#include <format>
#include <limits>
#include <locale>
#include <optional>
#include <ranges>
#include <sstream>
#include <stdexcept>
#include <string>
#include <string_view>
#include <vector>
#include <ctre.hpp>
Include dependency graph for Tokenizer.cpp:

Go to the source code of this file.

Functions

std::vector< Tokentokenize (const std::string &expr, int num_inputs, ExprMode mode, int num_intermediate_inputs)
TokenBehavior get_token_behavior (const Token &token)

Function Documentation

◆ get_token_behavior()

TokenBehavior get_token_behavior ( const Token & token)

Definition at line 1054 of file Tokenizer.cpp.

1054 {
1055 constexpr auto TOKEN_DEFS = get_token_definitions();
1056
1057 const auto* it = std::ranges::find_if(
1058 TOKEN_DEFS, [&](const auto& def) { return def.type == token.type; });
1059
1060 return std::visit(
1061 [&token](auto&& arg) -> TokenBehavior {
1062 using T = std::decay_t<decltype(arg)>;
1063 if constexpr (std::is_same_v<T, TokenBehavior>) {
1064 return arg;
1065 } else if constexpr (std::is_same_v<T, DynamicBehaviorFn>) {
1066 return arg(token);
1067 }
1068 },
1069 it->behavior);
1070}
TokenType type

References Token::type.

Referenced by infix2postfix::compute_postfix_stack_effect(), analysis::BlockAnalysisPass::run(), analysis::ConstPropPass::run(), and analysis::StaticArrayOptPass::run().

◆ tokenize()

std::vector< Token > tokenize ( const std::string & expr,
int num_inputs,
ExprMode mode,
int num_intermediate_inputs )

Definition at line 969 of file Tokenizer.cpp.

970 {
971 std::vector<Token> tokens;
972 int idx = 0;
973
974 auto is_space = [](char c) { return std::isspace(c); };
975 auto to_string_view = [](auto r) {
976 return std::string_view(r.begin(), r.end());
977 };
978
979 constexpr auto TOKEN_DEFS = get_token_definitions();
980
981 for (const auto str_token_view :
982 expr | std::views::chunk_by([=](char a, char b) {
983 return is_space(a) == is_space(b);
984 }) | std::views::filter([=](auto r) { return !is_space(r.front()); }) |
985 std::views::transform(to_string_view)) {
986 std::optional<Token> parsed_token;
987
988 for (const auto& definition : TOKEN_DEFS) {
989 // Check mode restrictions
990 if (!supports_mode(definition.availability, mode)) {
991 continue;
992 }
993
994 if ((parsed_token = definition.parser(str_token_view))) {
995 break;
996 }
997 }
998
999 if (!parsed_token) {
1000 throw std::runtime_error(std::format("Invalid token: {} (idx {})",
1001 std::string(str_token_view),
1002 idx));
1003 }
1004
1005 // Post-parse validation for clip indices
1006 if (parsed_token->type == TokenType::ClipRel ||
1007 parsed_token->type == TokenType::ClipAbs ||
1008 parsed_token->type == TokenType::ClipCur) {
1009 if (std::get<TokenPayloadClipAccess>(parsed_token->payload)
1010 .clip_idx < 0 ||
1011 std::get<TokenPayloadClipAccess>(parsed_token->payload)
1012 .clip_idx >= num_inputs) {
1013 throw std::runtime_error(
1014 std::format("Invalid clip index in token: {} (idx {})",
1015 std::string(str_token_view), idx));
1016 }
1017 } else if (parsed_token->type == TokenType::PropAccess) {
1018 if (std::get<TokenPayloadPropAccess>(parsed_token->payload)
1019 .clip_idx < 0 ||
1020 std::get<TokenPayloadPropAccess>(parsed_token->payload)
1021 .clip_idx >= num_inputs) {
1022 throw std::runtime_error(
1023 std::format("Invalid clip index in token: {} (idx {})",
1024 std::string(str_token_view), idx));
1025 }
1026 } else if (parsed_token->type == TokenType::ClipAbsPlane) {
1027 if (std::get<TokenPayloadClipAccessPlane>(parsed_token->payload)
1028 .clip_idx < 0 ||
1029 std::get<TokenPayloadClipAccessPlane>(parsed_token->payload)
1030 .clip_idx >= num_inputs) {
1031 throw std::runtime_error(
1032 std::format("Invalid clip index in token: {} (idx {})",
1033 std::string(str_token_view), idx));
1034 }
1035 } else if (parsed_token->type == TokenType::BufferRel ||
1036 parsed_token->type == TokenType::BufferAbs ||
1037 parsed_token->type == TokenType::BufferCur) {
1038 if (std::get<TokenPayloadBufferAccess>(parsed_token->payload)
1039 .buffer_idx < 0 ||
1040 std::get<TokenPayloadBufferAccess>(parsed_token->payload)
1041 .buffer_idx >= num_intermediate_inputs) {
1042 throw std::runtime_error(
1043 std::format("Invalid buffer index in token: {} (idx {})",
1044 std::string(str_token_view), idx));
1045 }
1046 }
1047
1048 tokens.push_back(*parsed_token);
1049 idx++;
1050 }
1051 return tokens;
1052}

References BufferAbs, BufferCur, BufferRel, ClipAbs, ClipAbsPlane, ClipCur, ClipRel, and PropAccess.

Referenced by infix2postfix::compute_postfix_stack_effect().