NEML2 2.0.0
Loading...
Searching...
No Matches
Parser.h
1// Copyright 2024, UChicago Argonne, LLC
2// All Rights Reserved
3// Software Name: NEML2 -- the New Engineering material Model Library, version 2
4// By: Argonne National Laboratory
5// OPEN SOURCE LICENSE (MIT)
6//
7// Permission is hereby granted, free of charge, to any person obtaining a copy
8// of this software and associated documentation files (the "Software"), to deal
9// in the Software without restriction, including without limitation the rights
10// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11// copies of the Software, and to permit persons to whom the Software is
12// furnished to do so, subject to the following conditions:
13//
14// The above copyright notice and this permission notice shall be included in
15// all copies or substantial portions of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23// THE SOFTWARE.
24
25#pragma once
26
27#include <filesystem>
28
29#include "neml2/misc/string_utils.h"
30#include "neml2/misc/errors.h"
31#include "neml2/misc/types.h"
32
33namespace neml2
34{
35class InputFile;
36class LabeledAxisAccessor;
37using VariableName = LabeledAxisAccessor;
38class EnumSelection;
39class MultiEnumSelection;
40
46class Parser
47{
48public:
49 Parser() = default;
50
51 Parser(const Parser &) = default;
52 Parser(Parser &&) noexcept = default;
53 Parser & operator=(const Parser &) = default;
54 Parser & operator=(Parser &&) noexcept = default;
55 virtual ~Parser() = default;
56
58 static const std::vector<std::string> sections;
59
68 virtual InputFile parse(const std::filesystem::path & filename,
69 const std::string & additional_input = "") const = 0;
70};
71
72namespace utils
73{
74template <typename T>
75std::string
76parse_failure_message(const std::string & raw_str)
77{
78 if constexpr (std::is_same_v<T, bool>)
79 return "Failed to parse '" + raw_str +
80 "' as a boolean. Only 'true' and 'false' (case-sensitive) are recognized.";
81
82 if constexpr (std::is_same_v<T, TensorShape>)
83 return "Failed to parse '" + raw_str +
84 "' as a tensor shape. Tensor shapes must be of the form "
85 "'(d1,d2,...,dn)': It must begin with '(' and end with ')', d1, d2, "
86 "... must be integers, and there must be no white spaces.";
87
88 return "Failed to parse '" + raw_str + "' as a " + utils::demangle(typeid(T).name());
89}
90
91template <typename T>
92bool
93parse_(T & val, const std::string & raw_str)
94{
95 std::stringstream ss(trim(raw_str));
96 ss >> val;
97 return !ss.fail();
98}
99
100template <typename T>
101T
102parse(const std::string & raw_str)
103{
104 T val;
105 auto success = parse_(val, raw_str);
106 if (!success)
107 throw ParserException(parse_failure_message<T>(raw_str));
108 return val;
109}
110
111template <typename T>
112bool
113parse_vector_(std::vector<T> & vals, const std::string & raw_str)
114{
115 auto tokens = split(raw_str, " \t\n\v\f\r");
116 if constexpr (std::is_same_v<T, Device>)
117 vals.resize(tokens.size(), kCPU);
118 else
119 vals.resize(tokens.size());
120 for (size_t i = 0; i < tokens.size(); i++)
121 {
122 auto success = parse_<T>(vals[i], tokens[i]);
123 if (!success)
124 return false;
125 }
126 return true;
127}
128
129template <typename T>
130std::vector<T>
131parse_vector(const std::string & raw_str)
132{
133 std::vector<T> vals;
134 auto success = parse_vector_(vals, raw_str);
135 if (!success)
136 throw ParserException("Failed to parse '" + raw_str + "' as a vector of " +
137 utils::demangle(typeid(T).name()));
138 return vals;
139}
140
141template <typename T>
142bool
143parse_vector_vector_(std::vector<std::vector<T>> & vals, const std::string & raw_str)
144{
145 auto token_vecs = split(raw_str, ";");
146 vals.resize(token_vecs.size());
147 for (size_t i = 0; i < token_vecs.size(); i++)
148 {
149 auto success = parse_vector_<T>(vals[i], token_vecs[i]);
150 if (!success)
151 return false;
152 }
153 return true;
154}
155
156template <typename T>
157std::vector<std::vector<T>>
158parse_vector_vector(const std::string & raw_str)
159{
160 std::vector<std::vector<T>> vals;
161 auto success = parse_vector_vector_(vals, raw_str);
162 if (!success)
163 throw ParserException("Failed to parse '" + raw_str + "' as a vector of vector of " +
164 utils::demangle(typeid(T).name()));
165 return vals;
166}
167
168// template specializations for special option types
169template <>
170bool parse_<bool>(bool &, const std::string & raw_str);
172template <>
173bool parse_vector_<bool>(std::vector<bool> &, const std::string & raw_str);
174template <>
175bool parse_<TensorShape>(TensorShape &, const std::string & raw_str);
176template <>
177bool parse_<VariableName>(VariableName &, const std::string & raw_str);
178template <>
179Device parse<Device>(const std::string & raw_str);
180template <>
181bool parse_<Device>(Device &, const std::string & raw_str);
182} // namespace utils
183} // namespace neml2
A data structure that holds options of multiple objects.
Definition InputFile.h:37
The accessor containing all the information needed to access an item in a LabeledAxis.
Definition LabeledAxisAccessor.h:56
Definition errors.h:64
A parser is responsible for parsing an input file into a collection of options which can be used by t...
Definition Parser.h:47
static const std::vector< std::string > sections
Known top-level sections in the input file.
Definition Parser.h:58
Parser()=default
virtual InputFile parse(const std::filesystem::path &filename, const std::string &additional_input="") const =0
Deserialize a file.
Parser(const Parser &)=default
Parser(Parser &&) noexcept=default
std::string trim(const std::string &str, const std::string &white_space)
Definition string_utils.cxx:73
std::string parse_failure_message(const std::string &raw_str)
Definition Parser.h:76
bool parse_vector_vector_(std::vector< std::vector< T > > &vals, const std::string &raw_str)
Definition Parser.h:143
bool parse_vector_(std::vector< bool > &vals, const std::string &raw_str)
Definition Parser.cxx:63
std::string demangle(const char *name)
Demangle a piece of cxx abi type information.
Definition string_utils.cxx:32
std::vector< T > parse_vector(const std::string &raw_str)
Definition Parser.h:131
std::vector< std::vector< T > > parse_vector_vector(const std::string &raw_str)
Definition Parser.h:158
std::vector< std::string > split(const std::string &str, const std::string &delims)
Definition string_utils.cxx:52
bool parse_(bool &val, const std::string &raw_str)
Definition Parser.cxx:39
Definition DiagnosticsInterface.cxx:30
c10::Device Device
Definition types.h:63
c10::SmallVector< Size, 8 > TensorShape
Definition types.h:66
std::string name(ElasticConstant p)
Definition ElasticityConverter.cxx:30
LabeledAxisAccessor VariableName
Definition LabeledAxisAccessor.h:185
constexpr auto kCPU
Definition types.h:53