• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

idaholab / MontePy / 12918569417

22 Jan 2025 10:48PM UTC coverage: 98.013% (+0.2%) from 97.855%
12918569417

Pull #608

github

MicahGale
Reved changelog to 1.0.0a1
Pull Request #608: 1.0.0 alpha to develop staging

1471 of 1487 new or added lines in 41 files covered. (98.92%)

12 existing lines in 7 files now uncovered.

7595 of 7749 relevant lines covered (98.01%)

0.98 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.48
/montepy/input_parser/data_parser.py
1
# Copyright 2024, Battelle Energy Alliance, LLC All Rights Reserved.
2
from montepy.errors import *
1✔
3
from montepy.input_parser.tokens import DataLexer
1✔
4
from montepy.input_parser.parser_base import MCNP_Parser, MetaBuilder
1✔
5
from montepy.input_parser import syntax_node
1✔
6

7

8
class DataParser(MCNP_Parser):
1✔
9
    """
10
    A parser for almost all data inputs.
11

12
    :returns: a syntax tree for the data input.
13
    :rtype: SyntaxNode
14
    """
15

16
    debugfile = None
1✔
17

18
    @_(
1✔
19
        "introduction",
20
        "introduction data",
21
        "introduction data parameters",
22
        "introduction parameters",
23
    )
24
    def data_input(self, p):
1✔
25
        ret = {}
1✔
26
        for key, node in p.introduction.nodes.items():
1✔
27
            ret[key] = node
1✔
28
        if hasattr(p, "data"):
1✔
29
            ret["data"] = p.data
1✔
30
        else:
31
            ret["data"] = syntax_node.ListNode("empty data")
1✔
32
        if hasattr(p, "parameters"):
1✔
33
            ret["parameters"] = p.parameters
1✔
34
        return syntax_node.SyntaxNode("data", ret)
1✔
35

36
    @_(
1✔
37
        "classifier_phrase",
38
        "classifier_phrase KEYWORD padding",
39
        "padding classifier_phrase",
40
        "padding classifier_phrase KEYWORD padding",
41
    )
42
    def introduction(self, p):
1✔
43
        ret = {}
1✔
44
        if isinstance(p[0], syntax_node.PaddingNode):
1✔
45
            ret["start_pad"] = p[0]
1✔
46
        else:
47
            ret["start_pad"] = syntax_node.PaddingNode()
1✔
48
        ret["classifier"] = p.classifier_phrase
1✔
49
        if hasattr(p, "KEYWORD"):
1✔
50
            ret["keyword"] = syntax_node.ValueNode(p.KEYWORD, str, padding=p[-1])
1✔
51
        else:
52
            ret["keyword"] = syntax_node.ValueNode(None, str, padding=None)
1✔
53
        return syntax_node.SyntaxNode("data intro", ret)
1✔
54

55
    @_(
1✔
56
        "number_sequence",
57
        "isotope_fractions",
58
        "particle_sequence",
59
        "text_sequence",
60
        "kitchen_sink",
61
    )
62
    def data(self, p):
1✔
63
        return p[0]
1✔
64

65
    @_("zaid_phrase number_phrase")
1✔
66
    def isotope_fraction(self, p):
1✔
67
        return p
1✔
68

69
    @_("isotope_fraction", "isotope_fractions isotope_fraction")
1✔
70
    def isotope_fractions(self, p):
1✔
71
        if hasattr(p, "isotope_fractions"):
1✔
UNCOV
72
            fractions = p.isotope_fractions
×
73
        else:
74
            fractions = syntax_node.MaterialsNode("isotope list")
1✔
75
        fractions.append_nuclide(p.isotope_fraction)
1✔
76
        return fractions
1✔
77

78
    @_("ZAID", "ZAID padding")
1✔
79
    def zaid_phrase(self, p):
1✔
80
        return self._flush_phrase(p, str)
1✔
81

82
    @_("particle_phrase", "particle_sequence particle_phrase")
1✔
83
    def particle_sequence(self, p):
1✔
84
        if len(p) == 1:
1✔
85
            sequence = syntax_node.ListNode("particle sequence")
1✔
86
            sequence.append(p[0], True)
1✔
87
        else:
88
            sequence = p[0]
1✔
89
            sequence.append(p[1], True)
1✔
90
        return sequence
1✔
91

92
    @_("PARTICLE", "SURFACE_TYPE", "PARTICLE_SPECIAL")
1✔
93
    def particle_text(self, p):
1✔
94
        return p[0]
1✔
95

96
    @_("particle_text padding", "particle_text")
1✔
97
    def particle_phrase(self, p):
1✔
98
        return self._flush_phrase(p, str)
1✔
99

100
    # Manually specifying because more levels break SLY. Might be hitting some hard coded limit.
101
    @_(
1✔
102
        "NUMBER_WORD",
103
        "NUM_MULTIPLY",
104
        "NUMBER_WORD padding ",
105
        "NUM_MULTIPLY padding",
106
    )
107
    def text_phrase(self, p):
1✔
108
        self._flush_phrase(p, str)
1✔
109

110
    @_("text_phrase", "text_sequence text_phrase")
1✔
111
    def text_sequence(self, p):
1✔
112
        if len(p) == 1:
1✔
113
            sequence = syntax_node.ListNode("text sequence")
1✔
114
            sequence.append(p[0], True)
1✔
115
        else:
116
            sequence = p[0]
×
117
            sequence.append(p[1], True)
×
118
        return sequence
1✔
119

120
    @_("kitchen_junk", "kitchen_sink kitchen_junk")
1✔
121
    def kitchen_sink(self, p):
1✔
122
        sequence = p[0]
1✔
123
        if len(p) != 1:
1✔
124
            for node in p[1].nodes:
1✔
125
                sequence.append(node, True)
1✔
126
        return sequence
1✔
127

128
    @_("number_sequence", "text_sequence", "particle_sequence")
1✔
129
    def kitchen_junk(self, p):
1✔
130
        return p[0]
1✔
131

132
    @_("classifier param_seperator NUMBER text_phrase")
1✔
133
    def parameter(self, p):
1✔
134
        return syntax_node.SyntaxNode(
×
135
            p.classifier.prefix.value,
136
            {
137
                "classifier": p.classifier,
138
                "seperator": p.param_seperator,
139
                "data": syntax_node.ValueNode(p.NUMBER + p.text_phrase, str),
140
            },
141
        )
142

143

144
class ClassifierParser(DataParser):
1✔
145
    """
146
    A parser for parsing the first word or classifier of a data input.
147

148
    :returns: the classifier of the data input.
149
    :rtype: ClassifierNode
150
    """
151

152
    debugfile = None
1✔
153

154
    @_("classifier", "padding classifier")
1✔
155
    def data_classifier(self, p):
1✔
156
        if hasattr(p, "padding"):
1✔
157
            padding = p.padding
1✔
158
        else:
159
            padding = syntax_node.PaddingNode(None)
1✔
160
        return syntax_node.SyntaxNode(
1✔
161
            "data input classifier", {"start_pad": padding, "classifier": p.classifier}
162
        )
163

164

165
class ParamOnlyDataParser(DataParser):
1✔
166
    """
167
    A parser for parsing parameter (key-value pair) only data inputs.
168

169
    .e.g., SDEF
170

171
    .. versionadded:: 0.3.0
172

173
    :returns: a syntax tree for the data input.
174
    :rtype: SyntaxNode
175
    """
176

177
    debugfile = None
1✔
178

179
    @_(
1✔
180
        "param_introduction spec_parameters",
181
    )
182
    def param_data_input(self, p):
1✔
183
        ret = {}
1✔
184
        for key, node in p.param_introduction.nodes.items():
1✔
185
            ret[key] = node
1✔
186
        if hasattr(p, "spec_parameters"):
1✔
187
            ret["parameters"] = p.spec_parameters
1✔
188
        return syntax_node.SyntaxNode("data", ret)
1✔
189

190
    @_(
1✔
191
        "classifier_phrase",
192
        "padding classifier_phrase",
193
    )
194
    def param_introduction(self, p):
1✔
195
        ret = {}
1✔
196
        if isinstance(p[0], syntax_node.PaddingNode):
1✔
197
            ret["start_pad"] = p[0]
×
198
        else:
199
            ret["start_pad"] = syntax_node.PaddingNode()
1✔
200
        ret["classifier"] = p.classifier_phrase
1✔
201
        ret["keyword"] = syntax_node.ValueNode(None, str, padding=None)
1✔
202
        return syntax_node.SyntaxNode("data intro", ret)
1✔
203

204
    @_("spec_parameter", "spec_parameters spec_parameter")
1✔
205
    def spec_parameters(self, p):
1✔
206
        """
207
        A list of the parameters (key, value pairs) for this input.
208

209
        :returns: all parameters
210
        :rtype: ParametersNode
211
        """
212
        if len(p) == 1:
1✔
213
            params = syntax_node.ParametersNode()
1✔
214
            param = p[0]
1✔
215
        else:
216
            params = p[0]
1✔
217
            param = p[1]
1✔
218
        params.append(param)
1✔
219
        return params
1✔
220

221
    @_("spec_classifier param_seperator data")
1✔
222
    def spec_parameter(self, p):
1✔
223
        return syntax_node.SyntaxNode(
1✔
224
            p.spec_classifier.prefix.value,
225
            {
226
                "classifier": p.spec_classifier,
227
                "seperator": p.param_seperator,
228
                "data": p.data,
229
            },
230
        )
231

232
    @_(
1✔
233
        "KEYWORD",
234
    )
235
    def spec_data_prefix(self, p):
1✔
236
        return syntax_node.ValueNode(p[0], str)
1✔
237

238
    @_(
1✔
239
        "modifier spec_data_prefix",
240
        "spec_data_prefix",
241
        "spec_classifier NUMBER",
242
        "spec_classifier particle_type",
243
    )
244
    def spec_classifier(self, p):
1✔
245
        """
246
        The classifier of a data input.
247

248
        This represents the first word of the data input.
249
        E.g.: ``M4``, `IMP:N`, ``F104:p``
250

251
        :rtype: ClassifierNode
252
        """
253
        if hasattr(p, "spec_classifier"):
1✔
254
            classifier = p.spec_classifier
×
255
        else:
256
            classifier = syntax_node.ClassifierNode()
1✔
257

258
        if hasattr(p, "modifier"):
1✔
259
            classifier.modifier = syntax_node.ValueNode(p.modifier, str)
×
260
        if hasattr(p, "spec_data_prefix"):
1✔
261
            classifier.prefix = p.spec_data_prefix
1✔
262
        if hasattr(p, "NUMBER"):
1✔
263
            classifier.number = syntax_node.ValueNode(p.NUMBER, int)
×
264
        if hasattr(p, "particle_type"):
1✔
265
            classifier.particles = p.particle_type
×
266
        return classifier
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc