Line data Source code
1 : /* Copyright (C) 2025 Robert Schiwon 2 : * 3 : * This file is part of libjdx. 4 : * 5 : * libjdx is free software: you can redistribute it and/or modify it under the 6 : * terms of the GNU Lesser General Public License as published by the Free 7 : * Software Foundation, either version 3 of the License, or (at your option) any 8 : * later version. 9 : * 10 : * libjdx is distributed in the hope that it will be useful, but WITHOUT ANY 11 : * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 12 : * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 13 : * details. 14 : * 15 : * You should have received a copy of the GNU Lesser General Public License 16 : * along with libjdx. If not, see <https://www.gnu.org/licenses/>. 17 : */ 18 : #include "util/PeakAssignmentsParser.hpp" 19 : #include "jdx/ParseException.hpp" 20 : #include "jdx/PeakAssignment.hpp" 21 : #include "util/LdrUtils.hpp" 22 : #include "util/StringUtils.hpp" 23 : 24 : #include <algorithm> 25 : #include <regex> 26 : 27 19 : libjdx::jdx::util::PeakAssignmentsParser::PeakAssignmentsParser( 28 19 : io::TextReader& reader, std::string variableList) 29 19 : : MultilineTuplesParser(reader, std::move(variableList), s_ldrName, " ") 30 : { 31 19 : } 32 : 33 : std::optional<libjdx::jdx::PeakAssignment> 34 43 : libjdx::jdx::util::PeakAssignmentsParser::next() 35 : { 36 43 : return TuplesParser::next<PeakAssignment>([this]() { return nextTuple(); }, 37 32 : [this]( 38 86 : const std::string& tuple) { return createPeakAssignment(tuple); }); 39 : } 40 : 41 : libjdx::jdx::PeakAssignment 42 32 : libjdx::jdx::util::PeakAssignmentsParser::createPeakAssignment( 43 : const std::string& tuple) const 44 : { 45 : // tokenize 46 : // token[0] is the full match so extract 1 + 5 tokens for 5 groups 47 60 : const auto tokens = extractTokens(tuple, m_regex, 1 + 5); 48 28 : const auto& varList = getVariableList(); 49 : 50 : // error conditions {varList, {error condition, error message}} 51 : const std::multimap<std::string, std::tuple<bool, std::string>> errorMap{ 52 28 : {s_varLists.at(0), 53 28 : {tokens.at(3) || tokens.at(4), 54 56 : std::string{"Illegal "} + s_ldrName + " entry for " 55 84 : + s_varLists.at(0) + ": " + tuple}}, 56 28 : {s_varLists.at(1), 57 84 : {tokens.at(4).has_value(), std::string{"Illegal "} + s_ldrName 58 84 : + " entry for " + s_varLists.at(1) 59 56 : + ": " + tuple}}, 60 28 : {s_varLists.at(1), 61 28 : {tokens.at(2) && !tokens.at(3), 62 56 : std::string{"Ambiguous "} + s_ldrName + " entry for " 63 84 : + s_varLists.at(1) + ": " + tuple}}, 64 28 : {s_varLists.at(2), 65 84 : {tokens.at(4).has_value(), std::string{"Illegal "} + s_ldrName 66 84 : + " entry for " + s_varLists.at(2) 67 56 : + ": " + tuple}}, 68 28 : {s_varLists.at(2), 69 28 : {tokens.at(2) && !tokens.at(3), 70 56 : std::string{"Ambiguous "} + s_ldrName + " entry for " 71 84 : + s_varLists.at(2) + ": " + tuple}}, 72 28 : {s_varLists.at(3), 73 54 : {!(tokens.at(2) && tokens.at(3) && tokens.at(4)) 74 54 : && (tokens.at(2) || tokens.at(3) || tokens.at(4)), 75 56 : std::string{"Ambiguous "} + s_ldrName + " entry for " 76 84 : + s_varLists.at(2) + ": " + tuple}}, 77 560 : }; 78 : 79 36 : checkForErrors(varList, errorMap, s_ldrName); 80 : 81 : // map 82 24 : PeakAssignment peakAssignment{}; 83 24 : peakAssignment.x = parseDoubleToken(tokens.at(1)); 84 24 : peakAssignment.a = tokens.at(5).value(); 85 24 : if (s_varLists.at(0) == varList && tokens.at(2)) 86 : { 87 : // 3 tokens 88 7 : peakAssignment.y = parseDoubleToken(tokens.at(2)); 89 : } 90 17 : else if (s_varLists.at(1) == varList && tokens.at(2) && tokens.at(3)) 91 : { 92 : // 4 tokens 93 5 : peakAssignment.y = parseDoubleToken(tokens.at(2)); 94 5 : peakAssignment.w = parseDoubleToken(tokens.at(3)); 95 : } 96 12 : else if (s_varLists.at(2) == varList && tokens.at(2) && tokens.at(3)) 97 : { 98 : // 4 tokens 99 9 : peakAssignment.y = parseDoubleToken(tokens.at(2)); 100 9 : peakAssignment.m = tokens.at(3); 101 : } 102 4 : else if (s_varLists.at(3) == varList && tokens.at(2) && tokens.at(3) 103 4 : && tokens.at(4)) 104 : { 105 : // 5 tokens 106 1 : peakAssignment.y = parseDoubleToken(tokens.at(2)); 107 1 : peakAssignment.m = tokens.at(3); 108 1 : peakAssignment.w = parseDoubleToken(tokens.at(4)); 109 : } 110 : 111 48 : return peakAssignment; 112 : }