From f273d74ae6568e85ddb6338be3f5801ba5b67e8b Mon Sep 17 00:00:00 2001 From: mcDandy Date: Thu, 8 Jan 2026 14:14:44 +0100 Subject: [PATCH] run ruff --- __init__.py | 1 - more_math/AudioMathNode.py | 46 +- more_math/AudioToSpectrogramNode.py | 35 +- more_math/ClipMathNode.py | 21 +- more_math/ConditioningMathNode.py | 16 +- more_math/FloatMathNode.py | 12 +- more_math/ImageMathNode.py | 38 +- more_math/LatentMathNode.py | 75 +- more_math/MathNodeBase.py | 33 +- more_math/ModelMathNode.py | 22 +- more_math/NoiseMathNode.py | 109 +- more_math/Parser/MathExprLexer.py | 4707 ++++++++++++++++- more_math/Parser/MathExprListener.py | 410 +- more_math/Parser/MathExprParser.py | 6621 +++++++++++++++++++----- more_math/Parser/MathExprVisitor.py | 248 +- more_math/Parser/UnifiedMathVisitor.py | 390 +- more_math/SpectrogramToAudioNode.py | 20 +- more_math/VaeMathNode.py | 22 +- more_math/VideoMathNode.py | 92 +- more_math/helper_functions.py | 51 +- more_math/modelLikeCommon.py | 26 +- more_math/nodes.py | 69 +- tests/conftest.py | 2 +- tests/reproduce_conv_issues.py | 57 +- tests/test_grammar_coverage.py | 58 +- tests/test_model_math.py | 132 +- tests/test_more_math.py | 55 +- tests/test_unified_math.py | 57 +- 28 files changed, 10849 insertions(+), 2576 deletions(-) diff --git a/__init__.py b/__init__.py index f9e7a96..252bc45 100644 --- a/__init__.py +++ b/__init__.py @@ -1,2 +1 @@ from .more_math.nodes import comfy_entrypoint - diff --git a/more_math/AudioMathNode.py b/more_math/AudioMathNode.py index b3b3e31..1d329bf 100644 --- a/more_math/AudioMathNode.py +++ b/more_math/AudioMathNode.py @@ -1,11 +1,12 @@ import torch -from .helper_functions import generate_dim_variables, getIndexTensorAlongDim, comonLazy, eval_tensor_expr, make_zero_like,as_tensor +from .helper_functions import generate_dim_variables, getIndexTensorAlongDim, comonLazy, eval_tensor_expr, make_zero_like, as_tensor from comfy_api.latest import io from .MathNodeBase import MathNodeBase + class AudioMathNode(MathNodeBase): """ Enables math expressions on Audio tensors. @@ -43,31 +44,36 @@ class AudioMathNode(MathNodeBase): @classmethod def execute(cls, AudioExpr, a, b=None, c=None, d=None, w=0.0, x=0.0, y=0.0, z=0.0): - av = a['waveform'] - sample_rate = a['sample_rate'] + av = a["waveform"] + sample_rate = a["sample_rate"] a, b, c, d = cls.prepare_inputs(a, b, c, d) - bv, cv, dv = b['waveform'], c['waveform'], d['waveform'] + bv, cv, dv = b["waveform"], c["waveform"], d["waveform"] variables = { - 'a': av, 'b': bv, 'c': cv, 'd': dv, - 'w': w, 'x': x, 'y': y, 'z': z, - 'B': getIndexTensorAlongDim(av, 0), - 'C': getIndexTensorAlongDim(av, 1), - 'S': getIndexTensorAlongDim(av, 2), - 'R': torch.full_like(av, sample_rate, dtype=torch.float32), - 'T': torch.full_like(av, av.shape[2], dtype=torch.float32), - 'N': av.shape[1], - 'batch': getIndexTensorAlongDim(av, 0), - 'channel': getIndexTensorAlongDim(av, 1), - 'sample': getIndexTensorAlongDim(av, 2), - 'sample_rate': torch.full_like(av, sample_rate, dtype=torch.float32), - 'sample_count': torch.full_like(av, av.shape[2], dtype=torch.float32), - 'channel_count': av.shape[1], + "a": av, + "b": bv, + "c": cv, + "d": dv, + "w": w, + "x": x, + "y": y, + "z": z, + "B": getIndexTensorAlongDim(av, 0), + "C": getIndexTensorAlongDim(av, 1), + "S": getIndexTensorAlongDim(av, 2), + "R": torch.full_like(av, sample_rate, dtype=torch.float32), + "T": torch.full_like(av, av.shape[2], dtype=torch.float32), + "N": av.shape[1], + "batch": getIndexTensorAlongDim(av, 0), + "channel": getIndexTensorAlongDim(av, 1), + "sample": getIndexTensorAlongDim(av, 2), + "sample_rate": torch.full_like(av, sample_rate, dtype=torch.float32), + "sample_count": torch.full_like(av, av.shape[2], dtype=torch.float32), + "channel_count": av.shape[1], } | generate_dim_variables(av) - result_tensor = eval_tensor_expr(AudioExpr, variables, av.shape) - return ({'waveform': as_tensor(result_tensor,a.shape), 'sample_rate': sample_rate},) + return ({"waveform": as_tensor(result_tensor, a.shape), "sample_rate": sample_rate},) diff --git a/more_math/AudioToSpectrogramNode.py b/more_math/AudioToSpectrogramNode.py index f13b9e5..f8c835e 100644 --- a/more_math/AudioToSpectrogramNode.py +++ b/more_math/AudioToSpectrogramNode.py @@ -1,7 +1,8 @@ from comfy_api.latest import io import torch -windows = {'bartlet':torch.bartlett_window, 'blackman':torch.blackman_window, 'hamming':torch.hamming_window,'hann':torch.hann_window} +windows = {"bartlet": torch.bartlett_window, "blackman": torch.blackman_window, "hamming": torch.hamming_window, "hann": torch.hann_window} + class AudioToSpectrogram(io.ComfyNode): """ @@ -9,6 +10,7 @@ class AudioToSpectrogram(io.ComfyNode): Red = Real, Green = logarithm of value (just so it looks good), Blue = Imaginary. Each audio channel is stacked vertically. """ + @classmethod def define_schema(cls) -> io.Schema: return io.Schema( @@ -19,7 +21,9 @@ class AudioToSpectrogram(io.ComfyNode): io.Audio.Input(id="audio", tooltip="Input audio"), io.Int.Input(id="window_length", default=1024, min=16, max=4096, tooltip="Window length in samples"), io.Int.Input(id="hop_length", default=256, min=1, max=4096, tooltip="Stride of the window (hop length) in samples"), - io.Int.Input(id="bucket_count", default=513, min=2, max=4096, tooltip="Number of frequency buckets (determines resolution)"), + io.Int.Input( + id="bucket_count", default=513, min=2, max=4096, tooltip="Number of frequency buckets (determines resolution)" + ), io.Combo.Input(id="window_type", default="hann", options=list(windows.keys()), tooltip="Type of window function to apply"), ], outputs=[ @@ -30,26 +34,29 @@ class AudioToSpectrogram(io.ComfyNode): ) @classmethod - def execute(cls, audio, window_length, hop_length, bucket_count,window_type): - waveform = audio['waveform'] - sample_rate = audio['sample_rate'] + def execute(cls, audio, window_length, hop_length, bucket_count, window_type): + waveform = audio["waveform"] + sample_rate = audio["sample_rate"] B, C, S = waveform.shape n_fft = (bucket_count - 1) * 2 flat_waveform = waveform.reshape(B * C, S) window = windows[window_type](window_length, device=waveform.device) stft_out = torch.stft( - flat_waveform, n_fft=n_fft, hop_length=hop_length, win_length=window_length, - window=window, center=True, pad_mode='reflect', normalized=False, - onesided=True, return_complex=True + flat_waveform, + n_fft=n_fft, + hop_length=hop_length, + win_length=window_length, + window=window, + center=True, + pad_mode="reflect", + normalized=False, + onesided=True, + return_complex=True, ) F, T = stft_out.shape[1], stft_out.shape[2] stft_out = stft_out.reshape(B, C, F, T).reshape(B, C * F, T) - image = torch.stack([ - stft_out.real, - torch.log1p(torch.abs(stft_out)), - stft_out.imag - ], dim=-1) + image = torch.stack([stft_out.real, torch.log1p(torch.abs(stft_out)), stft_out.imag], dim=-1) print(image.type()) - return (image, C, sample_rate) \ No newline at end of file + return (image, C, sample_rate) diff --git a/more_math/ClipMathNode.py b/more_math/ClipMathNode.py index 4956e80..7803cb3 100644 --- a/more_math/ClipMathNode.py +++ b/more_math/ClipMathNode.py @@ -3,10 +3,12 @@ from .modelLikeCommon import calculate_patches from inspect import cleandoc from .helper_functions import comonLazy + class CLIPMathNode(io.ComfyNode): """ This node enables the use of math expressions on CLIP weights. """ + @classmethod def define_schema(cls) -> io.Schema: return io.Schema( @@ -15,13 +17,13 @@ class CLIPMathNode(io.ComfyNode): category="More math", inputs=[ io.Clip.Input(id="a", tooltip="Main CLIP (base)"), - io.Clip.Input(id="b", optional=True,lazy=True, tooltip="Optional 2nd CLIP"), - io.Clip.Input(id="c", optional=True,lazy=True, tooltip="Optional 3rd CLIP"), - io.Clip.Input(id="d", optional=True,lazy=True, tooltip="Optional 4th CLIP"), - io.Float.Input(id="w", default=0.0, optional=True,lazy=True, force_input=True), - io.Float.Input(id="x", default=0.0, optional=True,lazy=True, force_input=True), - io.Float.Input(id="y", default=0.0, optional=True,lazy=True, force_input=True), - io.Float.Input(id="z", default=0.0, optional=True,lazy=True, force_input=True), + io.Clip.Input(id="b", optional=True, lazy=True, tooltip="Optional 2nd CLIP"), + io.Clip.Input(id="c", optional=True, lazy=True, tooltip="Optional 3rd CLIP"), + io.Clip.Input(id="d", optional=True, lazy=True, tooltip="Optional 4th CLIP"), + io.Float.Input(id="w", default=0.0, optional=True, lazy=True, force_input=True), + io.Float.Input(id="x", default=0.0, optional=True, lazy=True, force_input=True), + io.Float.Input(id="y", default=0.0, optional=True, lazy=True, force_input=True), + io.Float.Input(id="z", default=0.0, optional=True, lazy=True, force_input=True), io.String.Input(id="Model", default="a*(1-w)+b*w", tooltip="Expression to apply on weights"), ], outputs=[ @@ -30,9 +32,10 @@ class CLIPMathNode(io.ComfyNode): ) tooltip = cleandoc(__doc__) + @classmethod - def check_lazy_status(cls, Model, a, b=[], c=[], d=[],w=0,x=0,y=0,z=0): - return comonLazy(Model, a, b, c, d,w,x,y,z) + def check_lazy_status(cls, Model, a, b=[], c=[], d=[], w=0, x=0, y=0, z=0): + return comonLazy(Model, a, b, c, d, w, x, y, z) @classmethod def execute(cls, Model, a, b=None, c=None, d=None, w=0.0, x=0.0, y=0.0, z=0.0) -> io.NodeOutput: diff --git a/more_math/ConditioningMathNode.py b/more_math/ConditioningMathNode.py index 8effa13..d84973c 100644 --- a/more_math/ConditioningMathNode.py +++ b/more_math/ConditioningMathNode.py @@ -1,14 +1,14 @@ from inspect import cleandoc import torch -from .helper_functions import comonLazy, eval_tensor_expr, generate_dim_variables, make_zero_like,as_tensor +from .helper_functions import comonLazy, eval_tensor_expr, generate_dim_variables, make_zero_like, as_tensor from comfy_api.latest import io - from .MathNodeBase import MathNodeBase + class ConditioningMathNode(MathNodeBase): """ Enables math operations on conditionings. @@ -39,7 +39,9 @@ class ConditioningMathNode(MathNodeBase): io.Float.Input(id="y", default=0.0, optional=True, lazy=True, force_input=True), io.Float.Input(id="z", default=0.0, optional=True, lazy=True, force_input=True), io.String.Input(id="Tensor", default="a*(1-w)+b*w", tooltip="Expression for tensor part (image composition)"), - io.String.Input(id="pooled_output", default="a*(1-w)+b*w", tooltip="Expression for pooled output (condensed representation)"), + io.String.Input( + id="pooled_output", default="a*(1-w)+b*w", tooltip="Expression for pooled output (condensed representation)" + ), ], outputs=[ io.Conditioning.Output(), @@ -63,8 +65,8 @@ class ConditioningMathNode(MathNodeBase): ta, tb, tc, td = a[0][0], b[0][0], c[0][0], d[0][0] # Evaluate tensor expression - variables = {'a': ta, 'b': tb, 'c': tc, 'd': td, 'w': w, 'x': x, 'y': y, 'z': z} | generate_dim_variables(ta) - result_tensor = as_tensor(eval_tensor_expr(Tensor, variables, ta.shape),ta.shape) + variables = {"a": ta, "b": tb, "c": tc, "d": td, "w": w, "x": x, "y": y, "z": z} | generate_dim_variables(ta) + result_tensor = as_tensor(eval_tensor_expr(Tensor, variables, ta.shape), ta.shape) # Evaluate pooled_output expression if available pa = a[0][1].get("pooled_output") @@ -72,8 +74,8 @@ class ConditioningMathNode(MathNodeBase): pb = b[0][1].get("pooled_output") pc = c[0][1].get("pooled_output") pd = d[0][1].get("pooled_output") - variables = {'a': pa, 'b': pb, 'c': pc, 'd': pd, 'w': w, 'x': x, 'y': y, 'z': z} | generate_dim_variables(pa) - result_pooled = as_tensor(eval_tensor_expr(pooled_output, variables, pa.shape),pa.shape) + variables = {"a": pa, "b": pb, "c": pc, "d": pd, "w": w, "x": x, "y": y, "z": z} | generate_dim_variables(pa) + result_pooled = as_tensor(eval_tensor_expr(pooled_output, variables, pa.shape), pa.shape) else: result_pooled = None diff --git a/more_math/FloatMathNode.py b/more_math/FloatMathNode.py index 65396fd..ceab24f 100644 --- a/more_math/FloatMathNode.py +++ b/more_math/FloatMathNode.py @@ -3,21 +3,23 @@ from inspect import cleandoc from .helper_functions import comonLazy, eval_float_expr from comfy_api.latest import io + class FloatMathNode(io.ComfyNode): """ This node enables the use of math expressions on Floats. - + Inputs: a, b, c, d: Floats, bound to variables with the same name. w, x, y, z: Floats, bound to variables of the expression. - FloatFunc: String, describing math expression. + FloatFunc: String, describing math expression. Valid functions: sin, cos, tan, abs, sqrt, min, max, norm, etc. - Operators: +, -, *, /, ^, %. + Operators: +, -, *, /, ^, %. Constants: e, pi. - + Outputs: FLOAT: The result of evaluating the math expression. """ + @classmethod def define_schema(cls) -> io.Schema: return io.Schema( @@ -48,6 +50,6 @@ class FloatMathNode(io.ComfyNode): @classmethod def execute(cls, FloatFunc, a, b=0.0, c=0.0, d=0.0, w=0.0, x=0.0, y=0.0, z=0.0): - variables = {'a': a, 'b': b, 'c': c, 'd': d, 'w': w, 'x': x, 'y': y, 'z': z} + variables = {"a": a, "b": b, "c": c, "d": d, "w": w, "x": x, "y": y, "z": z} result = eval_float_expr(FloatFunc, variables) return (result,) diff --git a/more_math/ImageMathNode.py b/more_math/ImageMathNode.py index 3759044..5f7dd34 100644 --- a/more_math/ImageMathNode.py +++ b/more_math/ImageMathNode.py @@ -1,11 +1,12 @@ import torch -from .helper_functions import generate_dim_variables, getIndexTensorAlongDim, comonLazy, eval_tensor_expr, make_zero_like,as_tensor +from .helper_functions import generate_dim_variables, getIndexTensorAlongDim, comonLazy, eval_tensor_expr, make_zero_like, as_tensor from comfy_api.latest import io from .MathNodeBase import MathNodeBase + class ImageMathNode(MathNodeBase): """ Enables math expressions on Images. @@ -45,20 +46,31 @@ class ImageMathNode(MathNodeBase): def execute(cls, Image, a, b=None, c=None, d=None, w=0.0, x=0.0, y=0.0, z=0.0): a, b, c, d = cls.prepare_inputs(a, b, c, d) - variables = { - 'a': a, 'b': b, 'c': c, 'd': d, - 'w': w, 'x': x, 'y': y, 'z': z, - 'X': getIndexTensorAlongDim(a, 3), - 'Y': getIndexTensorAlongDim(a, 2), - 'B': getIndexTensorAlongDim(a, 0), 'batch': getIndexTensorAlongDim(a, 0), - 'C': getIndexTensorAlongDim(a, 1), 'channel': getIndexTensorAlongDim(a, 1), - 'W': a.shape[3], 'width': a.shape[3], - 'H': a.shape[2], 'height': a.shape[2], - 'T': a.shape[0], 'batch_count': a.shape[0], - 'N': a.shape[1], 'channel_count': a.shape[1], + "a": a, + "b": b, + "c": c, + "d": d, + "w": w, + "x": x, + "y": y, + "z": z, + "X": getIndexTensorAlongDim(a, 3), + "Y": getIndexTensorAlongDim(a, 2), + "B": getIndexTensorAlongDim(a, 0), + "batch": getIndexTensorAlongDim(a, 0), + "C": getIndexTensorAlongDim(a, 1), + "channel": getIndexTensorAlongDim(a, 1), + "W": a.shape[3], + "width": a.shape[3], + "H": a.shape[2], + "height": a.shape[2], + "T": a.shape[0], + "batch_count": a.shape[0], + "N": a.shape[1], + "channel_count": a.shape[1], } | generate_dim_variables(a) result = eval_tensor_expr(Image, variables, a.shape) - return (as_tensor(result,a.shape),) + return (as_tensor(result, a.shape),) diff --git a/more_math/LatentMathNode.py b/more_math/LatentMathNode.py index 6a1a5a6..42dfa9a 100644 --- a/more_math/LatentMathNode.py +++ b/more_math/LatentMathNode.py @@ -2,11 +2,18 @@ from inspect import cleandoc import comfy.nested_tensor from comfy_api.latest import io import torch -from .helper_functions import generate_dim_variables, getIndexTensorAlongDim, comonLazy, parse_expr, eval_tensor_expr_with_tree, make_zero_like,as_tensor +from .helper_functions import ( + generate_dim_variables, + getIndexTensorAlongDim, + comonLazy, + parse_expr, + eval_tensor_expr_with_tree, + make_zero_like, + as_tensor, +) from .MathNodeBase import MathNodeBase - class LatentMathNode(MathNodeBase): """ This node enables the use of math expressions on Latents. @@ -22,13 +29,13 @@ class LatentMathNode(MathNodeBase): LATENT: Returns a LATENT object that contains the result of the math expression applied to the input conditionings. """ + def __init__(self): pass @classmethod def define_schema(cls) -> io.Schema: - """ - """ + """ """ return io.Schema( node_id="mrmth_LatentMathNode", display_name="Latent math", @@ -38,10 +45,10 @@ class LatentMathNode(MathNodeBase): io.Latent.Input(id="b", optional=True, lazy=True), io.Latent.Input(id="c", optional=True, lazy=True), io.Latent.Input(id="d", optional=True, lazy=True), - io.Float.Input(id="w", default=0.0,optional=True,lazy=True, force_input=True), - io.Float.Input(id="x", default=0.0,optional=True,lazy=True, force_input=True), - io.Float.Input(id="y", default=0.0,optional=True,lazy=True, force_input=True), - io.Float.Input(id="z", default=0.0,optional=True,lazy=True, force_input=True), + io.Float.Input(id="w", default=0.0, optional=True, lazy=True, force_input=True), + io.Float.Input(id="x", default=0.0, optional=True, lazy=True, force_input=True), + io.Float.Input(id="y", default=0.0, optional=True, lazy=True, force_input=True), + io.Float.Input(id="z", default=0.0, optional=True, lazy=True, force_input=True), io.String.Input(id="Latent", default="a*(1-w)+b*w", tooltip="Expression to apply on input latents"), ], outputs=[ @@ -49,11 +56,11 @@ class LatentMathNode(MathNodeBase): ], ) - #RETURN_NAMES = ("image_output_name",) + # RETURN_NAMES = ("image_output_name",) tooltip = cleandoc(__doc__) - #OUTPUT_NODE = False - #OUTPUT_TOOLTIPS = ("",) # Tooltips for the output node + # OUTPUT_NODE = False + # OUTPUT_TOOLTIPS = ("",) # Tooltips for the output node @classmethod def execute(cls, Latent, a, b=None, c=None, d=None, w=0.0, x=0.0, y=0.0, z=0.0) -> io.NodeOutput: # Extract raw sample tensors (may be Tensor or NestedTensor) @@ -87,25 +94,37 @@ class LatentMathNode(MathNodeBase): frame_count = a_t.shape[time_dim] if time_dim is not None else a_t.shape[batch_dim] variables = { - 'a': a_t, 'b': b_t, 'c': c_t, 'd': d_t, - 'w': w, 'x': x, 'y': y, 'z': z, - - 'X': W, 'Y': H, - 'B': B, 'batch': B, - 'C': C, 'channel': C, - 'W': width_val, 'width': width_val, - 'H': height_val, 'height': height_val, - 'T': frame_count, 'batch_count': batch_count, - 'N': channel_count, 'channel_count': channel_count, + "a": a_t, + "b": b_t, + "c": c_t, + "d": d_t, + "w": w, + "x": x, + "y": y, + "z": z, + "X": W, + "Y": H, + "B": B, + "batch": B, + "C": C, + "channel": C, + "W": width_val, + "width": width_val, + "H": height_val, + "height": height_val, + "T": frame_count, + "batch_count": batch_count, + "N": channel_count, + "channel_count": channel_count, } | generate_dim_variables(a_t) if time_dim is not None: F = getIndexTensorAlongDim(a_t, time_dim) - variables.update({'frame_idx': F, 'frame': F, 'frame_count': frame_count}) + variables.update({"frame_idx": F, "frame": F, "frame_count": frame_count}) - return as_tensor(eval_tensor_expr_with_tree(tree, variables, a_t.shape),a_t.shape) + return as_tensor(eval_tensor_expr_with_tree(tree, variables, a_t.shape), a_t.shape) - if hasattr(a_in, 'is_nested') and getattr(a_in, 'is_nested'): + if hasattr(a_in, "is_nested") and getattr(a_in, "is_nested"): a_list = a_in.unbind() sizes = [t.shape[0] for t in a_list] merged_a = torch.cat(a_list, dim=0) @@ -113,7 +132,7 @@ class LatentMathNode(MathNodeBase): def merge_to_tensor(val, ref): if val is None: return make_zero_like(ref) - if hasattr(val, 'is_nested') and getattr(val, 'is_nested'): + if hasattr(val, "is_nested") and getattr(val, "is_nested"): lst = val.unbind() return torch.cat(lst, dim=0) if isinstance(val, (list, tuple)): @@ -143,7 +162,7 @@ class LatentMathNode(MathNodeBase): def to_tensor(val, ref): if val is None: return make_zero_like(ref) - if hasattr(val, 'is_nested') and getattr(val, 'is_nested'): + if hasattr(val, "is_nested") and getattr(val, "is_nested"): lst = val.unbind() elif isinstance(val, (list, tuple)): lst = list(val) @@ -184,6 +203,6 @@ class LatentMathNode(MathNodeBase): This method is used in the core repo for the LoadImage node where they return the image hash as a string, if the image hash changes between executions the LoadImage node is executed again. """ - #@classmethod - #def IS_CHANGED(s, image, string_field, int_field, float_field, print_to_screen): + # @classmethod + # def IS_CHANGED(s, image, string_field, int_field, float_field, print_to_screen): # return "" diff --git a/more_math/MathNodeBase.py b/more_math/MathNodeBase.py index ec69afc..ff10267 100644 --- a/more_math/MathNodeBase.py +++ b/more_math/MathNodeBase.py @@ -1,6 +1,7 @@ from comfy_api.latest import io from .helper_functions import comonLazy, make_zero_like + class MathNodeBase(io.ComfyNode): """ Base class for More Math nodes providing common utilities. @@ -13,35 +14,35 @@ class MathNodeBase(io.ComfyNode): Finds the first argument name that isn't a known variable (a-d, w-z) and assumes it's the expression. """ # Known variable inputs (and internal ones we might ignore) - known_vars = {'a', 'b', 'c', 'd', 'w', 'x', 'y', 'z', 'pooled_output'} - + known_vars = {"a", "b", "c", "d", "w", "x", "y", "z", "pooled_output"} + # Heuristic: The expression is usually the first argument that is not a known variable. # But `comonLazy` takes (expr, a, b, c, d, w, x, y, z). # We need to extract the values from kwargs correctly. - + expr_key = None # Try finding the expression key for k in kwargs: if k not in known_vars and isinstance(kwargs[k], str): expr_key = k break - + # If we can't find it heuristically (e.g. standard naming), fallback or error? # Let's try to be safe. If we can't find it, we might be in a node with custom logic like ConditioningMathNode. # ConditioningMathNode has 'Tensor' and 'pooled_output' as expressions. - + if expr_key: - expr = kwargs[expr_key] - a = kwargs.get('a', None) - b = kwargs.get('b', []) - c = kwargs.get('c', []) - d = kwargs.get('d', []) - w = kwargs.get('w', 0) - x = kwargs.get('x', 0) - y = kwargs.get('y', 0) - z = kwargs.get('z', 0) - return comonLazy(expr, a, b, c, d, w, x, y, z) - + expr = kwargs[expr_key] + a = kwargs.get("a", None) + b = kwargs.get("b", []) + c = kwargs.get("c", []) + d = kwargs.get("d", []) + w = kwargs.get("w", 0) + x = kwargs.get("x", 0) + y = kwargs.get("y", 0) + z = kwargs.get("z", 0) + return comonLazy(expr, a, b, c, d, w, x, y, z) + # Fallback/Empty return if we can't determine dependencies automatically return [] diff --git a/more_math/ModelMathNode.py b/more_math/ModelMathNode.py index 15054ca..abe76fa 100644 --- a/more_math/ModelMathNode.py +++ b/more_math/ModelMathNode.py @@ -4,12 +4,12 @@ from .helper_functions import comonLazy from .modelLikeCommon import calculate_patches - class ModelMathNode(io.ComfyNode): """ This node enables the use of math expressions on Model weights (state_dict). Functionally acts as a custom model merge. """ + @classmethod def define_schema(cls) -> io.Schema: return io.Schema( @@ -18,13 +18,13 @@ class ModelMathNode(io.ComfyNode): category="More math", inputs=[ io.Model.Input(id="a", tooltip="Main model (base)"), - io.Model.Input(id="b", optional=True,lazy=True, tooltip="Optional 2nd model"), - io.Model.Input(id="c", optional=True,lazy=True, tooltip="Optional 3rd model"), - io.Model.Input(id="d", optional=True,lazy=True, tooltip="Optional 4th model"), - io.Float.Input(id="w", default=0.0, optional=True,lazy=True, force_input=True), - io.Float.Input(id="x", default=0.0, optional=True,lazy=True, force_input=True), - io.Float.Input(id="y", default=0.0, optional=True,lazy=True, force_input=True), - io.Float.Input(id="z", default=0.0, optional=True,lazy=True, force_input=True), + io.Model.Input(id="b", optional=True, lazy=True, tooltip="Optional 2nd model"), + io.Model.Input(id="c", optional=True, lazy=True, tooltip="Optional 3rd model"), + io.Model.Input(id="d", optional=True, lazy=True, tooltip="Optional 4th model"), + io.Float.Input(id="w", default=0.0, optional=True, lazy=True, force_input=True), + io.Float.Input(id="x", default=0.0, optional=True, lazy=True, force_input=True), + io.Float.Input(id="y", default=0.0, optional=True, lazy=True, force_input=True), + io.Float.Input(id="z", default=0.0, optional=True, lazy=True, force_input=True), io.String.Input(id="Model", default="a*(1-w)+b*w", tooltip="Expression to apply on weights"), ], outputs=[ @@ -35,8 +35,8 @@ class ModelMathNode(io.ComfyNode): tooltip = cleandoc(__doc__) @classmethod - def check_lazy_status(cls, Model, a, b=[], c=[], d=[],w=0,x=0,y=0,z=0): - return comonLazy(Model, a, b, c, d,w,x,y,z) + def check_lazy_status(cls, Model, a, b=[], c=[], d=[], w=0, x=0, y=0, z=0): + return comonLazy(Model, a, b, c, d, w, x, y, z) @classmethod def execute(cls, Model, a, b=None, c=None, d=None, w=0.0, x=0.0, y=0.0, z=0.0) -> io.NodeOutput: @@ -44,4 +44,4 @@ class ModelMathNode(io.ComfyNode): out_model = a.clone() if patches: out_model.add_patches(patches, 1.0, 1.0) - return (out_model,) \ No newline at end of file + return (out_model,) diff --git a/more_math/NoiseMathNode.py b/more_math/NoiseMathNode.py index 55f8ae5..453e97e 100644 --- a/more_math/NoiseMathNode.py +++ b/more_math/NoiseMathNode.py @@ -2,14 +2,21 @@ from inspect import cleandoc import torch -from .helper_functions import generate_dim_variables, getIndexTensorAlongDim, comonLazy, parse_expr, eval_tensor_expr_with_tree, make_zero_like,as_tensor +from .helper_functions import ( + generate_dim_variables, + getIndexTensorAlongDim, + comonLazy, + parse_expr, + eval_tensor_expr_with_tree, + make_zero_like, + as_tensor, +) from comfy_api.latest import io import comfy.nested_tensor as _nested_tensor_module - class NoiseMathNode(io.ComfyNode): """ This node enables the use of math expressions on Latents. @@ -25,40 +32,44 @@ class NoiseMathNode(io.ComfyNode): LATENT: Returns a LATENT object that contains the result of the math expression applied to the input conditionings. """ + def __init__(self): - pass + pass + @classmethod def define_schema(cls) -> io.Schema: - """ - """ + """ """ return io.Schema( node_id="mrmth_NoiseMathNode", category="More math", display_name="Noise math", inputs=[ io.Noise.Input(id="a"), - io.Noise.Input(id="b", optional=True,lazy=True), - io.Noise.Input(id="c", optional=True,lazy=True), - io.Noise.Input(id="d", optional=True,lazy=True), - io.Float.Input(id="w", default=0.0,optional=True,lazy=True, force_input=True), - io.Float.Input(id="x", default=0.0,optional=True,lazy=True, force_input=True), - io.Float.Input(id="y", default=0.0,optional=True,lazy=True, force_input=True), - io.Float.Input(id="z", default=0.0,optional=True,lazy=True, force_input=True), + io.Noise.Input(id="b", optional=True, lazy=True), + io.Noise.Input(id="c", optional=True, lazy=True), + io.Noise.Input(id="d", optional=True, lazy=True), + io.Float.Input(id="w", default=0.0, optional=True, lazy=True, force_input=True), + io.Float.Input(id="x", default=0.0, optional=True, lazy=True, force_input=True), + io.Float.Input(id="y", default=0.0, optional=True, lazy=True, force_input=True), + io.Float.Input(id="z", default=0.0, optional=True, lazy=True, force_input=True), io.String.Input(id="Noise", default="a*(1-w)+b*w", tooltip="Expression to apply on input noise generators"), ], outputs=[ io.Noise.Output(), ], ) - #RETURN_NAMES = ("image_output_name",) + + # RETURN_NAMES = ("image_output_name",) tooltip = cleandoc(__doc__) - #OUTPUT_NODE = False - #OUTPUT_TOOLTIPS = ("",) # Tooltips for the output node + # OUTPUT_NODE = False + # OUTPUT_TOOLTIPS = ("",) # Tooltips for the output node CATEGORY = "More math" + @classmethod - def check_lazy_status(cls, Noise, a, b=[], c=[], d=[],w=0,x=0,y=0,z=0): - return comonLazy(Noise, a, b, c, d,w,x,y,z) + def check_lazy_status(cls, Noise, a, b=[], c=[], d=[], w=0, x=0, y=0, z=0): + return comonLazy(Noise, a, b, c, d, w, x, y, z) + @classmethod def execute(cls, Noise, a, b=None, c=None, d=None, w=0.0, x=0.0, y=0.0, z=0.0): return (NoiseExecutor(a, b, c, d, w, x, y, z, Noise),) @@ -71,15 +82,13 @@ class NoiseMathNode(io.ComfyNode): This method is used in the core repo for the LoadImage node where they return the image hash as a string, if the image hash changes between executions the LoadImage node is executed again. """ - #@classmethod - #def IS_CHANGED(s, image, string_field, int_field, float_field, print_to_screen): + # @classmethod + # def IS_CHANGED(s, image, string_field, int_field, float_field, print_to_screen): # return "" - - -class NoiseExecutor(): - def __init__(self,a,b,c,d,w,x,y,z, Noise): +class NoiseExecutor: + def __init__(self, a, b, c, d, w, x, y, z, Noise): self.a = a self.b = b self.c = c @@ -90,8 +99,10 @@ class NoiseExecutor(): self.z = z self.expr = Noise self.tree = parse_expr(Noise) - seed = -1; - def generate_noise(self, input_latent:torch.Tensor) -> torch.Tensor: + + seed = -1 + + def generate_noise(self, input_latent: torch.Tensor) -> torch.Tensor: samples = input_latent["samples"] a_val = self.a.generate_noise(input_latent) if self.a is not None else make_zero_like(samples) @@ -104,7 +115,7 @@ class NoiseExecutor(): if val is None: return [make_zero_like(r) for r in ref_list] # If val is a NestedTensor-like, return underlying list - if hasattr(val, 'is_nested') and getattr(val, 'is_nested'): + if hasattr(val, "is_nested") and getattr(val, "is_nested"): return val.unbind() if isinstance(val, list) or isinstance(val, tuple): return list(val) @@ -121,7 +132,7 @@ class NoiseExecutor(): return [val for _ in ref_list] # nested case: merge subtensors, evaluate once, split back - if hasattr(samples, 'is_nested') and getattr(samples, 'is_nested'): + if hasattr(samples, "is_nested") and getattr(samples, "is_nested"): sample_list = samples.unbind() sizes = [t.shape[0] for t in sample_list] merged_samples = torch.cat(sample_list, dim=0) @@ -129,7 +140,7 @@ class NoiseExecutor(): def merge_to_tensor(val, ref): if val is None: return make_zero_like(ref) - if hasattr(val, 'is_nested') and getattr(val, 'is_nested'): + if hasattr(val, "is_nested") and getattr(val, "is_nested"): lst = val.unbind() return torch.cat(lst, dim=0) if isinstance(val, (list, tuple)): @@ -142,7 +153,10 @@ class NoiseExecutor(): # if val has per-subtensor batches, try to split and cat try: if val.shape[0] == len(sample_list): - return torch.cat([val[i].unsqueeze(0).expand(sample_list[i].shape[0], *val.shape[1:]) for i in range(len(sample_list))], dim=0) + return torch.cat( + [val[i].unsqueeze(0).expand(sample_list[i].shape[0], *val.shape[1:]) for i in range(len(sample_list))], + dim=0, + ) except Exception: pass return make_zero_like(ref) @@ -176,21 +190,38 @@ class NoiseExecutor(): H = getIndexTensorAlongDim(merged_samples, height_dim) C = getIndexTensorAlongDim(merged_samples, channel_dim) variables = { - 'a': merged_a, 'b': merged_b, 'c': merged_c, 'd': merged_d, - 'w': self.w, 'x': self.x, 'y': self.y, 'z': self.z, - 'B': B, 'X': W, 'Y': H, 'C': C, - 'W': merged_samples.shape[width_dim], 'H': merged_samples.shape[height_dim], - 'I': merged_samples, 'T': frame_count, 'N': merged_samples.shape[channel_dim], - 'batch': B, 'width': merged_samples.shape[width_dim], 'height': merged_samples.shape[height_dim], 'channel': C, - 'batch_count': merged_samples.shape[0], 'channel_count': merged_samples.shape[1], 'input_latent': merged_samples, + "a": merged_a, + "b": merged_b, + "c": merged_c, + "d": merged_d, + "w": self.w, + "x": self.x, + "y": self.y, + "z": self.z, + "B": B, + "X": W, + "Y": H, + "C": C, + "W": merged_samples.shape[width_dim], + "H": merged_samples.shape[height_dim], + "I": merged_samples, + "T": frame_count, + "N": merged_samples.shape[channel_dim], + "batch": B, + "width": merged_samples.shape[width_dim], + "height": merged_samples.shape[height_dim], + "channel": C, + "batch_count": merged_samples.shape[0], + "channel_count": merged_samples.shape[1], + "input_latent": merged_samples, } | generate_dim_variables(merged_samples) if time_dim is not None: F = getIndexTensorAlongDim(merged_samples, time_dim) - variables.update({'frame': F, 'frame_count': frame_count}) + variables.update({"frame": F, "frame_count": frame_count}) - merged_result = as_tensor(eval_tensor_expr_with_tree(self.tree, variables, variables['a'].shape),variables['a'].shape) + merged_result = as_tensor(eval_tensor_expr_with_tree(self.tree, variables, variables["a"].shape), variables["a"].shape) - if hasattr(samples, 'is_nested') and getattr(samples, 'is_nested'): + if hasattr(samples, "is_nested") and getattr(samples, "is_nested"): split_results = list(merged_result.split(sizes, dim=0)) return _nested_tensor_module.NestedTensor(split_results) diff --git a/more_math/Parser/MathExprLexer.py b/more_math/Parser/MathExprLexer.py index 23332d6..9817a61 100644 --- a/more_math/Parser/MathExprLexer.py +++ b/more_math/Parser/MathExprLexer.py @@ -2,6 +2,7 @@ from antlr4 import * from io import StringIO import sys + if sys.version_info[1] > 5: from typing import TextIO else: @@ -10,189 +11,4280 @@ else: def serializedATN(): return [ - 4,0,73,502,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5, - 2,6,7,6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2, - 13,7,13,2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7, - 19,2,20,7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2, - 26,7,26,2,27,7,27,2,28,7,28,2,29,7,29,2,30,7,30,2,31,7,31,2,32,7, - 32,2,33,7,33,2,34,7,34,2,35,7,35,2,36,7,36,2,37,7,37,2,38,7,38,2, - 39,7,39,2,40,7,40,2,41,7,41,2,42,7,42,2,43,7,43,2,44,7,44,2,45,7, - 45,2,46,7,46,2,47,7,47,2,48,7,48,2,49,7,49,2,50,7,50,2,51,7,51,2, - 52,7,52,2,53,7,53,2,54,7,54,2,55,7,55,2,56,7,56,2,57,7,57,2,58,7, - 58,2,59,7,59,2,60,7,60,2,61,7,61,2,62,7,62,2,63,7,63,2,64,7,64,2, - 65,7,65,2,66,7,66,2,67,7,67,2,68,7,68,2,69,7,69,2,70,7,70,2,71,7, - 71,2,72,7,72,1,0,1,0,1,1,1,1,1,2,1,2,1,3,1,3,1,4,1,4,1,5,1,5,1,5, - 1,5,1,6,1,6,1,6,1,6,1,7,1,7,1,7,1,7,1,8,1,8,1,8,1,8,1,8,1,9,1,9, - 1,9,1,9,1,9,1,10,1,10,1,10,1,10,1,10,1,11,1,11,1,11,1,11,1,11,1, - 11,1,12,1,12,1,12,1,12,1,12,1,13,1,13,1,13,1,13,1,13,1,14,1,14,1, - 14,1,14,1,14,1,15,1,15,1,15,1,15,1,15,1,15,1,16,1,16,1,16,1,16,1, - 16,1,16,1,17,1,17,1,17,1,17,1,17,1,17,1,18,1,18,1,18,1,18,1,19,1, - 19,1,19,1,19,1,19,1,20,1,20,1,20,1,21,1,21,1,21,1,21,1,22,1,22,1, - 22,1,22,1,23,1,23,1,23,1,23,1,23,1,24,1,24,1,24,1,24,1,24,1,25,1, - 25,1,25,1,25,1,25,1,26,1,26,1,26,1,26,1,26,1,27,1,27,1,27,1,27,1, - 27,1,27,1,28,1,28,1,28,1,28,1,28,1,28,1,29,1,29,1,29,1,29,1,29,1, - 29,1,30,1,30,1,30,1,30,1,30,1,31,1,31,1,31,1,31,1,31,1,31,1,32,1, - 32,1,32,1,32,1,32,1,32,1,33,1,33,1,33,1,33,1,34,1,34,1,34,1,34,1, - 34,1,35,1,35,1,35,1,35,1,35,1,35,1,36,1,36,1,36,1,36,1,37,1,37,1, - 37,1,37,1,37,1,38,1,38,1,38,1,38,1,38,1,38,1,39,1,39,1,39,1,39,1, - 39,1,39,1,40,1,40,1,40,1,40,1,40,1,40,1,40,1,40,1,40,1,40,1,40,1, - 40,1,41,1,41,1,41,1,41,1,41,1,42,1,42,1,42,1,42,1,42,1,43,1,43,1, - 43,1,43,1,43,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1, - 44,1,45,1,45,1,45,1,45,1,45,1,45,1,46,1,46,1,46,1,46,1,46,1,47,1, - 47,1,47,1,47,1,47,1,47,1,47,1,47,1,47,1,48,1,48,1,48,1,48,1,48,1, - 49,1,49,1,49,1,49,1,49,1,50,1,50,1,50,1,50,1,51,1,51,1,51,1,51,1, - 51,1,52,1,52,1,52,1,52,1,52,1,53,1,53,1,53,1,53,1,53,1,53,1,53,1, - 53,1,54,1,54,1,54,1,54,1,54,1,54,1,54,1,54,1,55,1,55,1,55,1,55,1, - 55,1,55,1,56,1,56,1,57,1,57,1,58,1,58,1,59,1,59,1,60,1,60,1,61,1, - 61,1,62,1,62,1,62,1,63,1,63,1,64,1,64,1,64,1,65,1,65,1,66,1,66,1, - 66,1,67,1,67,1,67,1,68,1,68,1,69,1,69,1,69,1,69,1,69,3,69,474,8, - 69,1,70,4,70,477,8,70,11,70,12,70,478,1,70,1,70,4,70,483,8,70,11, - 70,12,70,484,3,70,487,8,70,1,71,1,71,5,71,491,8,71,10,71,12,71,494, - 9,71,1,72,4,72,497,8,72,11,72,12,72,498,1,72,1,72,0,0,73,1,1,3,2, - 5,3,7,4,9,5,11,6,13,7,15,8,17,9,19,10,21,11,23,12,25,13,27,14,29, - 15,31,16,33,17,35,18,37,19,39,20,41,21,43,22,45,23,47,24,49,25,51, - 26,53,27,55,28,57,29,59,30,61,31,63,32,65,33,67,34,69,35,71,36,73, - 37,75,38,77,39,79,40,81,41,83,42,85,43,87,44,89,45,91,46,93,47,95, - 48,97,49,99,50,101,51,103,52,105,53,107,54,109,55,111,56,113,57, - 115,58,117,59,119,60,121,61,123,62,125,63,127,64,129,65,131,66,133, - 67,135,68,137,69,139,70,141,71,143,72,145,73,1,0,5,2,0,69,69,101, - 101,1,0,48,57,3,0,65,90,95,95,97,122,4,0,48,57,65,90,95,95,97,122, - 3,0,9,10,13,13,32,32,508,0,1,1,0,0,0,0,3,1,0,0,0,0,5,1,0,0,0,0,7, - 1,0,0,0,0,9,1,0,0,0,0,11,1,0,0,0,0,13,1,0,0,0,0,15,1,0,0,0,0,17, - 1,0,0,0,0,19,1,0,0,0,0,21,1,0,0,0,0,23,1,0,0,0,0,25,1,0,0,0,0,27, - 1,0,0,0,0,29,1,0,0,0,0,31,1,0,0,0,0,33,1,0,0,0,0,35,1,0,0,0,0,37, - 1,0,0,0,0,39,1,0,0,0,0,41,1,0,0,0,0,43,1,0,0,0,0,45,1,0,0,0,0,47, - 1,0,0,0,0,49,1,0,0,0,0,51,1,0,0,0,0,53,1,0,0,0,0,55,1,0,0,0,0,57, - 1,0,0,0,0,59,1,0,0,0,0,61,1,0,0,0,0,63,1,0,0,0,0,65,1,0,0,0,0,67, - 1,0,0,0,0,69,1,0,0,0,0,71,1,0,0,0,0,73,1,0,0,0,0,75,1,0,0,0,0,77, - 1,0,0,0,0,79,1,0,0,0,0,81,1,0,0,0,0,83,1,0,0,0,0,85,1,0,0,0,0,87, - 1,0,0,0,0,89,1,0,0,0,0,91,1,0,0,0,0,93,1,0,0,0,0,95,1,0,0,0,0,97, - 1,0,0,0,0,99,1,0,0,0,0,101,1,0,0,0,0,103,1,0,0,0,0,105,1,0,0,0,0, - 107,1,0,0,0,0,109,1,0,0,0,0,111,1,0,0,0,0,113,1,0,0,0,0,115,1,0, - 0,0,0,117,1,0,0,0,0,119,1,0,0,0,0,121,1,0,0,0,0,123,1,0,0,0,0,125, - 1,0,0,0,0,127,1,0,0,0,0,129,1,0,0,0,0,131,1,0,0,0,0,133,1,0,0,0, - 0,135,1,0,0,0,0,137,1,0,0,0,0,139,1,0,0,0,0,141,1,0,0,0,0,143,1, - 0,0,0,0,145,1,0,0,0,1,147,1,0,0,0,3,149,1,0,0,0,5,151,1,0,0,0,7, - 153,1,0,0,0,9,155,1,0,0,0,11,157,1,0,0,0,13,161,1,0,0,0,15,165,1, - 0,0,0,17,169,1,0,0,0,19,174,1,0,0,0,21,179,1,0,0,0,23,184,1,0,0, - 0,25,190,1,0,0,0,27,195,1,0,0,0,29,200,1,0,0,0,31,205,1,0,0,0,33, - 211,1,0,0,0,35,217,1,0,0,0,37,223,1,0,0,0,39,227,1,0,0,0,41,232, - 1,0,0,0,43,235,1,0,0,0,45,239,1,0,0,0,47,243,1,0,0,0,49,248,1,0, - 0,0,51,253,1,0,0,0,53,258,1,0,0,0,55,263,1,0,0,0,57,269,1,0,0,0, - 59,275,1,0,0,0,61,281,1,0,0,0,63,286,1,0,0,0,65,292,1,0,0,0,67,298, - 1,0,0,0,69,302,1,0,0,0,71,307,1,0,0,0,73,313,1,0,0,0,75,317,1,0, - 0,0,77,322,1,0,0,0,79,328,1,0,0,0,81,334,1,0,0,0,83,346,1,0,0,0, - 85,351,1,0,0,0,87,356,1,0,0,0,89,361,1,0,0,0,91,372,1,0,0,0,93,378, - 1,0,0,0,95,383,1,0,0,0,97,392,1,0,0,0,99,397,1,0,0,0,101,402,1,0, - 0,0,103,406,1,0,0,0,105,411,1,0,0,0,107,416,1,0,0,0,109,424,1,0, - 0,0,111,432,1,0,0,0,113,438,1,0,0,0,115,440,1,0,0,0,117,442,1,0, - 0,0,119,444,1,0,0,0,121,446,1,0,0,0,123,448,1,0,0,0,125,450,1,0, - 0,0,127,453,1,0,0,0,129,455,1,0,0,0,131,458,1,0,0,0,133,460,1,0, - 0,0,135,463,1,0,0,0,137,466,1,0,0,0,139,473,1,0,0,0,141,476,1,0, - 0,0,143,488,1,0,0,0,145,496,1,0,0,0,147,148,5,40,0,0,148,2,1,0,0, - 0,149,150,5,41,0,0,150,4,1,0,0,0,151,152,5,91,0,0,152,6,1,0,0,0, - 153,154,5,44,0,0,154,8,1,0,0,0,155,156,5,93,0,0,156,10,1,0,0,0,157, - 158,5,115,0,0,158,159,5,105,0,0,159,160,5,110,0,0,160,12,1,0,0,0, - 161,162,5,99,0,0,162,163,5,111,0,0,163,164,5,115,0,0,164,14,1,0, - 0,0,165,166,5,116,0,0,166,167,5,97,0,0,167,168,5,110,0,0,168,16, - 1,0,0,0,169,170,5,97,0,0,170,171,5,115,0,0,171,172,5,105,0,0,172, - 173,5,110,0,0,173,18,1,0,0,0,174,175,5,97,0,0,175,176,5,99,0,0,176, - 177,5,111,0,0,177,178,5,115,0,0,178,20,1,0,0,0,179,180,5,97,0,0, - 180,181,5,116,0,0,181,182,5,97,0,0,182,183,5,110,0,0,183,22,1,0, - 0,0,184,185,5,97,0,0,185,186,5,116,0,0,186,187,5,97,0,0,187,188, - 5,110,0,0,188,189,5,50,0,0,189,24,1,0,0,0,190,191,5,115,0,0,191, - 192,5,105,0,0,192,193,5,110,0,0,193,194,5,104,0,0,194,26,1,0,0,0, - 195,196,5,99,0,0,196,197,5,111,0,0,197,198,5,115,0,0,198,199,5,104, - 0,0,199,28,1,0,0,0,200,201,5,116,0,0,201,202,5,97,0,0,202,203,5, - 110,0,0,203,204,5,104,0,0,204,30,1,0,0,0,205,206,5,97,0,0,206,207, - 5,115,0,0,207,208,5,105,0,0,208,209,5,110,0,0,209,210,5,104,0,0, - 210,32,1,0,0,0,211,212,5,97,0,0,212,213,5,99,0,0,213,214,5,111,0, - 0,214,215,5,115,0,0,215,216,5,104,0,0,216,34,1,0,0,0,217,218,5,97, - 0,0,218,219,5,116,0,0,219,220,5,97,0,0,220,221,5,110,0,0,221,222, - 5,104,0,0,222,36,1,0,0,0,223,224,5,97,0,0,224,225,5,98,0,0,225,226, - 5,115,0,0,226,38,1,0,0,0,227,228,5,115,0,0,228,229,5,113,0,0,229, - 230,5,114,0,0,230,231,5,116,0,0,231,40,1,0,0,0,232,233,5,108,0,0, - 233,234,5,110,0,0,234,42,1,0,0,0,235,236,5,108,0,0,236,237,5,111, - 0,0,237,238,5,103,0,0,238,44,1,0,0,0,239,240,5,101,0,0,240,241,5, - 120,0,0,241,242,5,112,0,0,242,46,1,0,0,0,243,244,5,115,0,0,244,245, - 5,109,0,0,245,246,5,105,0,0,246,247,5,110,0,0,247,48,1,0,0,0,248, - 249,5,115,0,0,249,250,5,109,0,0,250,251,5,97,0,0,251,252,5,120,0, - 0,252,50,1,0,0,0,253,254,5,116,0,0,254,255,5,109,0,0,255,256,5,105, - 0,0,256,257,5,110,0,0,257,52,1,0,0,0,258,259,5,116,0,0,259,260,5, - 109,0,0,260,261,5,97,0,0,261,262,5,120,0,0,262,54,1,0,0,0,263,264, - 5,116,0,0,264,265,5,110,0,0,265,266,5,111,0,0,266,267,5,114,0,0, - 267,268,5,109,0,0,268,56,1,0,0,0,269,270,5,115,0,0,270,271,5,110, - 0,0,271,272,5,111,0,0,272,273,5,114,0,0,273,274,5,109,0,0,274,58, - 1,0,0,0,275,276,5,102,0,0,276,277,5,108,0,0,277,278,5,111,0,0,278, - 279,5,111,0,0,279,280,5,114,0,0,280,60,1,0,0,0,281,282,5,99,0,0, - 282,283,5,101,0,0,283,284,5,105,0,0,284,285,5,108,0,0,285,62,1,0, - 0,0,286,287,5,114,0,0,287,288,5,111,0,0,288,289,5,117,0,0,289,290, - 5,110,0,0,290,291,5,100,0,0,291,64,1,0,0,0,292,293,5,103,0,0,293, - 294,5,97,0,0,294,295,5,109,0,0,295,296,5,109,0,0,296,297,5,97,0, - 0,297,66,1,0,0,0,298,299,5,112,0,0,299,300,5,111,0,0,300,301,5,119, - 0,0,301,68,1,0,0,0,302,303,5,115,0,0,303,304,5,105,0,0,304,305,5, - 103,0,0,305,306,5,109,0,0,306,70,1,0,0,0,307,308,5,99,0,0,308,309, - 5,108,0,0,309,310,5,97,0,0,310,311,5,109,0,0,311,312,5,112,0,0,312, - 72,1,0,0,0,313,314,5,102,0,0,314,315,5,102,0,0,315,316,5,116,0,0, - 316,74,1,0,0,0,317,318,5,105,0,0,318,319,5,102,0,0,319,320,5,102, - 0,0,320,321,5,116,0,0,321,76,1,0,0,0,322,323,5,97,0,0,323,324,5, - 110,0,0,324,325,5,103,0,0,325,326,5,108,0,0,326,327,5,101,0,0,327, - 78,1,0,0,0,328,329,5,112,0,0,329,330,5,114,0,0,330,331,5,105,0,0, - 331,332,5,110,0,0,332,333,5,116,0,0,333,80,1,0,0,0,334,335,5,112, - 0,0,335,336,5,114,0,0,336,337,5,105,0,0,337,338,5,110,0,0,338,339, - 5,116,0,0,339,340,5,95,0,0,340,341,5,115,0,0,341,342,5,104,0,0,342, - 343,5,97,0,0,343,344,5,112,0,0,344,345,5,101,0,0,345,82,1,0,0,0, - 346,347,5,112,0,0,347,348,5,115,0,0,348,349,5,104,0,0,349,350,5, - 112,0,0,350,84,1,0,0,0,351,352,5,108,0,0,352,353,5,101,0,0,353,354, - 5,114,0,0,354,355,5,112,0,0,355,86,1,0,0,0,356,357,5,115,0,0,357, - 358,5,116,0,0,358,359,5,101,0,0,359,360,5,112,0,0,360,88,1,0,0,0, - 361,362,5,115,0,0,362,363,5,109,0,0,363,364,5,111,0,0,364,365,5, - 111,0,0,365,366,5,116,0,0,366,367,5,104,0,0,367,368,5,115,0,0,368, - 369,5,116,0,0,369,370,5,101,0,0,370,371,5,112,0,0,371,90,1,0,0,0, - 372,373,5,102,0,0,373,374,5,114,0,0,374,375,5,97,0,0,375,376,5,99, - 0,0,376,377,5,116,0,0,377,92,1,0,0,0,378,379,5,114,0,0,379,380,5, - 101,0,0,380,381,5,108,0,0,381,382,5,117,0,0,382,94,1,0,0,0,383,384, - 5,115,0,0,384,385,5,111,0,0,385,386,5,102,0,0,386,387,5,116,0,0, - 387,388,5,112,0,0,388,389,5,108,0,0,389,390,5,117,0,0,390,391,5, - 115,0,0,391,96,1,0,0,0,392,393,5,103,0,0,393,394,5,101,0,0,394,395, - 5,108,0,0,395,396,5,117,0,0,396,98,1,0,0,0,397,398,5,115,0,0,398, - 399,5,105,0,0,399,400,5,103,0,0,400,401,5,110,0,0,401,100,1,0,0, - 0,402,403,5,109,0,0,403,404,5,97,0,0,404,405,5,112,0,0,405,102,1, - 0,0,0,406,407,5,99,0,0,407,408,5,111,0,0,408,409,5,110,0,0,409,410, - 5,118,0,0,410,104,1,0,0,0,411,412,5,115,0,0,412,413,5,119,0,0,413, - 414,5,97,0,0,414,415,5,112,0,0,415,106,1,0,0,0,416,417,5,112,0,0, - 417,418,5,101,0,0,418,419,5,114,0,0,419,420,5,109,0,0,420,421,5, - 117,0,0,421,422,5,116,0,0,422,423,5,101,0,0,423,108,1,0,0,0,424, - 425,5,114,0,0,425,426,5,101,0,0,426,427,5,115,0,0,427,428,5,104, - 0,0,428,429,5,97,0,0,429,430,5,112,0,0,430,431,5,101,0,0,431,110, - 1,0,0,0,432,433,5,114,0,0,433,434,5,97,0,0,434,435,5,110,0,0,435, - 436,5,103,0,0,436,437,5,101,0,0,437,112,1,0,0,0,438,439,5,43,0,0, - 439,114,1,0,0,0,440,441,5,45,0,0,441,116,1,0,0,0,442,443,5,42,0, - 0,443,118,1,0,0,0,444,445,5,47,0,0,445,120,1,0,0,0,446,447,5,37, - 0,0,447,122,1,0,0,0,448,449,5,94,0,0,449,124,1,0,0,0,450,451,5,62, - 0,0,451,452,5,61,0,0,452,126,1,0,0,0,453,454,5,62,0,0,454,128,1, - 0,0,0,455,456,5,60,0,0,456,457,5,61,0,0,457,130,1,0,0,0,458,459, - 5,60,0,0,459,132,1,0,0,0,460,461,5,61,0,0,461,462,5,61,0,0,462,134, - 1,0,0,0,463,464,5,33,0,0,464,465,5,61,0,0,465,136,1,0,0,0,466,467, - 5,124,0,0,467,138,1,0,0,0,468,469,5,112,0,0,469,474,5,105,0,0,470, - 471,5,80,0,0,471,474,5,73,0,0,472,474,7,0,0,0,473,468,1,0,0,0,473, - 470,1,0,0,0,473,472,1,0,0,0,474,140,1,0,0,0,475,477,7,1,0,0,476, - 475,1,0,0,0,477,478,1,0,0,0,478,476,1,0,0,0,478,479,1,0,0,0,479, - 486,1,0,0,0,480,482,5,46,0,0,481,483,7,1,0,0,482,481,1,0,0,0,483, - 484,1,0,0,0,484,482,1,0,0,0,484,485,1,0,0,0,485,487,1,0,0,0,486, - 480,1,0,0,0,486,487,1,0,0,0,487,142,1,0,0,0,488,492,7,2,0,0,489, - 491,7,3,0,0,490,489,1,0,0,0,491,494,1,0,0,0,492,490,1,0,0,0,492, - 493,1,0,0,0,493,144,1,0,0,0,494,492,1,0,0,0,495,497,7,4,0,0,496, - 495,1,0,0,0,497,498,1,0,0,0,498,496,1,0,0,0,498,499,1,0,0,0,499, - 500,1,0,0,0,500,501,6,72,0,0,501,146,1,0,0,0,7,0,473,478,484,486, - 492,498,1,6,0,0 + 4, + 0, + 73, + 502, + 6, + -1, + 2, + 0, + 7, + 0, + 2, + 1, + 7, + 1, + 2, + 2, + 7, + 2, + 2, + 3, + 7, + 3, + 2, + 4, + 7, + 4, + 2, + 5, + 7, + 5, + 2, + 6, + 7, + 6, + 2, + 7, + 7, + 7, + 2, + 8, + 7, + 8, + 2, + 9, + 7, + 9, + 2, + 10, + 7, + 10, + 2, + 11, + 7, + 11, + 2, + 12, + 7, + 12, + 2, + 13, + 7, + 13, + 2, + 14, + 7, + 14, + 2, + 15, + 7, + 15, + 2, + 16, + 7, + 16, + 2, + 17, + 7, + 17, + 2, + 18, + 7, + 18, + 2, + 19, + 7, + 19, + 2, + 20, + 7, + 20, + 2, + 21, + 7, + 21, + 2, + 22, + 7, + 22, + 2, + 23, + 7, + 23, + 2, + 24, + 7, + 24, + 2, + 25, + 7, + 25, + 2, + 26, + 7, + 26, + 2, + 27, + 7, + 27, + 2, + 28, + 7, + 28, + 2, + 29, + 7, + 29, + 2, + 30, + 7, + 30, + 2, + 31, + 7, + 31, + 2, + 32, + 7, + 32, + 2, + 33, + 7, + 33, + 2, + 34, + 7, + 34, + 2, + 35, + 7, + 35, + 2, + 36, + 7, + 36, + 2, + 37, + 7, + 37, + 2, + 38, + 7, + 38, + 2, + 39, + 7, + 39, + 2, + 40, + 7, + 40, + 2, + 41, + 7, + 41, + 2, + 42, + 7, + 42, + 2, + 43, + 7, + 43, + 2, + 44, + 7, + 44, + 2, + 45, + 7, + 45, + 2, + 46, + 7, + 46, + 2, + 47, + 7, + 47, + 2, + 48, + 7, + 48, + 2, + 49, + 7, + 49, + 2, + 50, + 7, + 50, + 2, + 51, + 7, + 51, + 2, + 52, + 7, + 52, + 2, + 53, + 7, + 53, + 2, + 54, + 7, + 54, + 2, + 55, + 7, + 55, + 2, + 56, + 7, + 56, + 2, + 57, + 7, + 57, + 2, + 58, + 7, + 58, + 2, + 59, + 7, + 59, + 2, + 60, + 7, + 60, + 2, + 61, + 7, + 61, + 2, + 62, + 7, + 62, + 2, + 63, + 7, + 63, + 2, + 64, + 7, + 64, + 2, + 65, + 7, + 65, + 2, + 66, + 7, + 66, + 2, + 67, + 7, + 67, + 2, + 68, + 7, + 68, + 2, + 69, + 7, + 69, + 2, + 70, + 7, + 70, + 2, + 71, + 7, + 71, + 2, + 72, + 7, + 72, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 2, + 1, + 2, + 1, + 3, + 1, + 3, + 1, + 4, + 1, + 4, + 1, + 5, + 1, + 5, + 1, + 5, + 1, + 5, + 1, + 6, + 1, + 6, + 1, + 6, + 1, + 6, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 10, + 1, + 10, + 1, + 10, + 1, + 10, + 1, + 10, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 12, + 1, + 12, + 1, + 12, + 1, + 12, + 1, + 12, + 1, + 13, + 1, + 13, + 1, + 13, + 1, + 13, + 1, + 13, + 1, + 14, + 1, + 14, + 1, + 14, + 1, + 14, + 1, + 14, + 1, + 15, + 1, + 15, + 1, + 15, + 1, + 15, + 1, + 15, + 1, + 15, + 1, + 16, + 1, + 16, + 1, + 16, + 1, + 16, + 1, + 16, + 1, + 16, + 1, + 17, + 1, + 17, + 1, + 17, + 1, + 17, + 1, + 17, + 1, + 17, + 1, + 18, + 1, + 18, + 1, + 18, + 1, + 18, + 1, + 19, + 1, + 19, + 1, + 19, + 1, + 19, + 1, + 19, + 1, + 20, + 1, + 20, + 1, + 20, + 1, + 21, + 1, + 21, + 1, + 21, + 1, + 21, + 1, + 22, + 1, + 22, + 1, + 22, + 1, + 22, + 1, + 23, + 1, + 23, + 1, + 23, + 1, + 23, + 1, + 23, + 1, + 24, + 1, + 24, + 1, + 24, + 1, + 24, + 1, + 24, + 1, + 25, + 1, + 25, + 1, + 25, + 1, + 25, + 1, + 25, + 1, + 26, + 1, + 26, + 1, + 26, + 1, + 26, + 1, + 26, + 1, + 27, + 1, + 27, + 1, + 27, + 1, + 27, + 1, + 27, + 1, + 27, + 1, + 28, + 1, + 28, + 1, + 28, + 1, + 28, + 1, + 28, + 1, + 28, + 1, + 29, + 1, + 29, + 1, + 29, + 1, + 29, + 1, + 29, + 1, + 29, + 1, + 30, + 1, + 30, + 1, + 30, + 1, + 30, + 1, + 30, + 1, + 31, + 1, + 31, + 1, + 31, + 1, + 31, + 1, + 31, + 1, + 31, + 1, + 32, + 1, + 32, + 1, + 32, + 1, + 32, + 1, + 32, + 1, + 32, + 1, + 33, + 1, + 33, + 1, + 33, + 1, + 33, + 1, + 34, + 1, + 34, + 1, + 34, + 1, + 34, + 1, + 34, + 1, + 35, + 1, + 35, + 1, + 35, + 1, + 35, + 1, + 35, + 1, + 35, + 1, + 36, + 1, + 36, + 1, + 36, + 1, + 36, + 1, + 37, + 1, + 37, + 1, + 37, + 1, + 37, + 1, + 37, + 1, + 38, + 1, + 38, + 1, + 38, + 1, + 38, + 1, + 38, + 1, + 38, + 1, + 39, + 1, + 39, + 1, + 39, + 1, + 39, + 1, + 39, + 1, + 39, + 1, + 40, + 1, + 40, + 1, + 40, + 1, + 40, + 1, + 40, + 1, + 40, + 1, + 40, + 1, + 40, + 1, + 40, + 1, + 40, + 1, + 40, + 1, + 40, + 1, + 41, + 1, + 41, + 1, + 41, + 1, + 41, + 1, + 41, + 1, + 42, + 1, + 42, + 1, + 42, + 1, + 42, + 1, + 42, + 1, + 43, + 1, + 43, + 1, + 43, + 1, + 43, + 1, + 43, + 1, + 44, + 1, + 44, + 1, + 44, + 1, + 44, + 1, + 44, + 1, + 44, + 1, + 44, + 1, + 44, + 1, + 44, + 1, + 44, + 1, + 44, + 1, + 45, + 1, + 45, + 1, + 45, + 1, + 45, + 1, + 45, + 1, + 45, + 1, + 46, + 1, + 46, + 1, + 46, + 1, + 46, + 1, + 46, + 1, + 47, + 1, + 47, + 1, + 47, + 1, + 47, + 1, + 47, + 1, + 47, + 1, + 47, + 1, + 47, + 1, + 47, + 1, + 48, + 1, + 48, + 1, + 48, + 1, + 48, + 1, + 48, + 1, + 49, + 1, + 49, + 1, + 49, + 1, + 49, + 1, + 49, + 1, + 50, + 1, + 50, + 1, + 50, + 1, + 50, + 1, + 51, + 1, + 51, + 1, + 51, + 1, + 51, + 1, + 51, + 1, + 52, + 1, + 52, + 1, + 52, + 1, + 52, + 1, + 52, + 1, + 53, + 1, + 53, + 1, + 53, + 1, + 53, + 1, + 53, + 1, + 53, + 1, + 53, + 1, + 53, + 1, + 54, + 1, + 54, + 1, + 54, + 1, + 54, + 1, + 54, + 1, + 54, + 1, + 54, + 1, + 54, + 1, + 55, + 1, + 55, + 1, + 55, + 1, + 55, + 1, + 55, + 1, + 55, + 1, + 56, + 1, + 56, + 1, + 57, + 1, + 57, + 1, + 58, + 1, + 58, + 1, + 59, + 1, + 59, + 1, + 60, + 1, + 60, + 1, + 61, + 1, + 61, + 1, + 62, + 1, + 62, + 1, + 62, + 1, + 63, + 1, + 63, + 1, + 64, + 1, + 64, + 1, + 64, + 1, + 65, + 1, + 65, + 1, + 66, + 1, + 66, + 1, + 66, + 1, + 67, + 1, + 67, + 1, + 67, + 1, + 68, + 1, + 68, + 1, + 69, + 1, + 69, + 1, + 69, + 1, + 69, + 1, + 69, + 3, + 69, + 474, + 8, + 69, + 1, + 70, + 4, + 70, + 477, + 8, + 70, + 11, + 70, + 12, + 70, + 478, + 1, + 70, + 1, + 70, + 4, + 70, + 483, + 8, + 70, + 11, + 70, + 12, + 70, + 484, + 3, + 70, + 487, + 8, + 70, + 1, + 71, + 1, + 71, + 5, + 71, + 491, + 8, + 71, + 10, + 71, + 12, + 71, + 494, + 9, + 71, + 1, + 72, + 4, + 72, + 497, + 8, + 72, + 11, + 72, + 12, + 72, + 498, + 1, + 72, + 1, + 72, + 0, + 0, + 73, + 1, + 1, + 3, + 2, + 5, + 3, + 7, + 4, + 9, + 5, + 11, + 6, + 13, + 7, + 15, + 8, + 17, + 9, + 19, + 10, + 21, + 11, + 23, + 12, + 25, + 13, + 27, + 14, + 29, + 15, + 31, + 16, + 33, + 17, + 35, + 18, + 37, + 19, + 39, + 20, + 41, + 21, + 43, + 22, + 45, + 23, + 47, + 24, + 49, + 25, + 51, + 26, + 53, + 27, + 55, + 28, + 57, + 29, + 59, + 30, + 61, + 31, + 63, + 32, + 65, + 33, + 67, + 34, + 69, + 35, + 71, + 36, + 73, + 37, + 75, + 38, + 77, + 39, + 79, + 40, + 81, + 41, + 83, + 42, + 85, + 43, + 87, + 44, + 89, + 45, + 91, + 46, + 93, + 47, + 95, + 48, + 97, + 49, + 99, + 50, + 101, + 51, + 103, + 52, + 105, + 53, + 107, + 54, + 109, + 55, + 111, + 56, + 113, + 57, + 115, + 58, + 117, + 59, + 119, + 60, + 121, + 61, + 123, + 62, + 125, + 63, + 127, + 64, + 129, + 65, + 131, + 66, + 133, + 67, + 135, + 68, + 137, + 69, + 139, + 70, + 141, + 71, + 143, + 72, + 145, + 73, + 1, + 0, + 5, + 2, + 0, + 69, + 69, + 101, + 101, + 1, + 0, + 48, + 57, + 3, + 0, + 65, + 90, + 95, + 95, + 97, + 122, + 4, + 0, + 48, + 57, + 65, + 90, + 95, + 95, + 97, + 122, + 3, + 0, + 9, + 10, + 13, + 13, + 32, + 32, + 508, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 3, + 1, + 0, + 0, + 0, + 0, + 5, + 1, + 0, + 0, + 0, + 0, + 7, + 1, + 0, + 0, + 0, + 0, + 9, + 1, + 0, + 0, + 0, + 0, + 11, + 1, + 0, + 0, + 0, + 0, + 13, + 1, + 0, + 0, + 0, + 0, + 15, + 1, + 0, + 0, + 0, + 0, + 17, + 1, + 0, + 0, + 0, + 0, + 19, + 1, + 0, + 0, + 0, + 0, + 21, + 1, + 0, + 0, + 0, + 0, + 23, + 1, + 0, + 0, + 0, + 0, + 25, + 1, + 0, + 0, + 0, + 0, + 27, + 1, + 0, + 0, + 0, + 0, + 29, + 1, + 0, + 0, + 0, + 0, + 31, + 1, + 0, + 0, + 0, + 0, + 33, + 1, + 0, + 0, + 0, + 0, + 35, + 1, + 0, + 0, + 0, + 0, + 37, + 1, + 0, + 0, + 0, + 0, + 39, + 1, + 0, + 0, + 0, + 0, + 41, + 1, + 0, + 0, + 0, + 0, + 43, + 1, + 0, + 0, + 0, + 0, + 45, + 1, + 0, + 0, + 0, + 0, + 47, + 1, + 0, + 0, + 0, + 0, + 49, + 1, + 0, + 0, + 0, + 0, + 51, + 1, + 0, + 0, + 0, + 0, + 53, + 1, + 0, + 0, + 0, + 0, + 55, + 1, + 0, + 0, + 0, + 0, + 57, + 1, + 0, + 0, + 0, + 0, + 59, + 1, + 0, + 0, + 0, + 0, + 61, + 1, + 0, + 0, + 0, + 0, + 63, + 1, + 0, + 0, + 0, + 0, + 65, + 1, + 0, + 0, + 0, + 0, + 67, + 1, + 0, + 0, + 0, + 0, + 69, + 1, + 0, + 0, + 0, + 0, + 71, + 1, + 0, + 0, + 0, + 0, + 73, + 1, + 0, + 0, + 0, + 0, + 75, + 1, + 0, + 0, + 0, + 0, + 77, + 1, + 0, + 0, + 0, + 0, + 79, + 1, + 0, + 0, + 0, + 0, + 81, + 1, + 0, + 0, + 0, + 0, + 83, + 1, + 0, + 0, + 0, + 0, + 85, + 1, + 0, + 0, + 0, + 0, + 87, + 1, + 0, + 0, + 0, + 0, + 89, + 1, + 0, + 0, + 0, + 0, + 91, + 1, + 0, + 0, + 0, + 0, + 93, + 1, + 0, + 0, + 0, + 0, + 95, + 1, + 0, + 0, + 0, + 0, + 97, + 1, + 0, + 0, + 0, + 0, + 99, + 1, + 0, + 0, + 0, + 0, + 101, + 1, + 0, + 0, + 0, + 0, + 103, + 1, + 0, + 0, + 0, + 0, + 105, + 1, + 0, + 0, + 0, + 0, + 107, + 1, + 0, + 0, + 0, + 0, + 109, + 1, + 0, + 0, + 0, + 0, + 111, + 1, + 0, + 0, + 0, + 0, + 113, + 1, + 0, + 0, + 0, + 0, + 115, + 1, + 0, + 0, + 0, + 0, + 117, + 1, + 0, + 0, + 0, + 0, + 119, + 1, + 0, + 0, + 0, + 0, + 121, + 1, + 0, + 0, + 0, + 0, + 123, + 1, + 0, + 0, + 0, + 0, + 125, + 1, + 0, + 0, + 0, + 0, + 127, + 1, + 0, + 0, + 0, + 0, + 129, + 1, + 0, + 0, + 0, + 0, + 131, + 1, + 0, + 0, + 0, + 0, + 133, + 1, + 0, + 0, + 0, + 0, + 135, + 1, + 0, + 0, + 0, + 0, + 137, + 1, + 0, + 0, + 0, + 0, + 139, + 1, + 0, + 0, + 0, + 0, + 141, + 1, + 0, + 0, + 0, + 0, + 143, + 1, + 0, + 0, + 0, + 0, + 145, + 1, + 0, + 0, + 0, + 1, + 147, + 1, + 0, + 0, + 0, + 3, + 149, + 1, + 0, + 0, + 0, + 5, + 151, + 1, + 0, + 0, + 0, + 7, + 153, + 1, + 0, + 0, + 0, + 9, + 155, + 1, + 0, + 0, + 0, + 11, + 157, + 1, + 0, + 0, + 0, + 13, + 161, + 1, + 0, + 0, + 0, + 15, + 165, + 1, + 0, + 0, + 0, + 17, + 169, + 1, + 0, + 0, + 0, + 19, + 174, + 1, + 0, + 0, + 0, + 21, + 179, + 1, + 0, + 0, + 0, + 23, + 184, + 1, + 0, + 0, + 0, + 25, + 190, + 1, + 0, + 0, + 0, + 27, + 195, + 1, + 0, + 0, + 0, + 29, + 200, + 1, + 0, + 0, + 0, + 31, + 205, + 1, + 0, + 0, + 0, + 33, + 211, + 1, + 0, + 0, + 0, + 35, + 217, + 1, + 0, + 0, + 0, + 37, + 223, + 1, + 0, + 0, + 0, + 39, + 227, + 1, + 0, + 0, + 0, + 41, + 232, + 1, + 0, + 0, + 0, + 43, + 235, + 1, + 0, + 0, + 0, + 45, + 239, + 1, + 0, + 0, + 0, + 47, + 243, + 1, + 0, + 0, + 0, + 49, + 248, + 1, + 0, + 0, + 0, + 51, + 253, + 1, + 0, + 0, + 0, + 53, + 258, + 1, + 0, + 0, + 0, + 55, + 263, + 1, + 0, + 0, + 0, + 57, + 269, + 1, + 0, + 0, + 0, + 59, + 275, + 1, + 0, + 0, + 0, + 61, + 281, + 1, + 0, + 0, + 0, + 63, + 286, + 1, + 0, + 0, + 0, + 65, + 292, + 1, + 0, + 0, + 0, + 67, + 298, + 1, + 0, + 0, + 0, + 69, + 302, + 1, + 0, + 0, + 0, + 71, + 307, + 1, + 0, + 0, + 0, + 73, + 313, + 1, + 0, + 0, + 0, + 75, + 317, + 1, + 0, + 0, + 0, + 77, + 322, + 1, + 0, + 0, + 0, + 79, + 328, + 1, + 0, + 0, + 0, + 81, + 334, + 1, + 0, + 0, + 0, + 83, + 346, + 1, + 0, + 0, + 0, + 85, + 351, + 1, + 0, + 0, + 0, + 87, + 356, + 1, + 0, + 0, + 0, + 89, + 361, + 1, + 0, + 0, + 0, + 91, + 372, + 1, + 0, + 0, + 0, + 93, + 378, + 1, + 0, + 0, + 0, + 95, + 383, + 1, + 0, + 0, + 0, + 97, + 392, + 1, + 0, + 0, + 0, + 99, + 397, + 1, + 0, + 0, + 0, + 101, + 402, + 1, + 0, + 0, + 0, + 103, + 406, + 1, + 0, + 0, + 0, + 105, + 411, + 1, + 0, + 0, + 0, + 107, + 416, + 1, + 0, + 0, + 0, + 109, + 424, + 1, + 0, + 0, + 0, + 111, + 432, + 1, + 0, + 0, + 0, + 113, + 438, + 1, + 0, + 0, + 0, + 115, + 440, + 1, + 0, + 0, + 0, + 117, + 442, + 1, + 0, + 0, + 0, + 119, + 444, + 1, + 0, + 0, + 0, + 121, + 446, + 1, + 0, + 0, + 0, + 123, + 448, + 1, + 0, + 0, + 0, + 125, + 450, + 1, + 0, + 0, + 0, + 127, + 453, + 1, + 0, + 0, + 0, + 129, + 455, + 1, + 0, + 0, + 0, + 131, + 458, + 1, + 0, + 0, + 0, + 133, + 460, + 1, + 0, + 0, + 0, + 135, + 463, + 1, + 0, + 0, + 0, + 137, + 466, + 1, + 0, + 0, + 0, + 139, + 473, + 1, + 0, + 0, + 0, + 141, + 476, + 1, + 0, + 0, + 0, + 143, + 488, + 1, + 0, + 0, + 0, + 145, + 496, + 1, + 0, + 0, + 0, + 147, + 148, + 5, + 40, + 0, + 0, + 148, + 2, + 1, + 0, + 0, + 0, + 149, + 150, + 5, + 41, + 0, + 0, + 150, + 4, + 1, + 0, + 0, + 0, + 151, + 152, + 5, + 91, + 0, + 0, + 152, + 6, + 1, + 0, + 0, + 0, + 153, + 154, + 5, + 44, + 0, + 0, + 154, + 8, + 1, + 0, + 0, + 0, + 155, + 156, + 5, + 93, + 0, + 0, + 156, + 10, + 1, + 0, + 0, + 0, + 157, + 158, + 5, + 115, + 0, + 0, + 158, + 159, + 5, + 105, + 0, + 0, + 159, + 160, + 5, + 110, + 0, + 0, + 160, + 12, + 1, + 0, + 0, + 0, + 161, + 162, + 5, + 99, + 0, + 0, + 162, + 163, + 5, + 111, + 0, + 0, + 163, + 164, + 5, + 115, + 0, + 0, + 164, + 14, + 1, + 0, + 0, + 0, + 165, + 166, + 5, + 116, + 0, + 0, + 166, + 167, + 5, + 97, + 0, + 0, + 167, + 168, + 5, + 110, + 0, + 0, + 168, + 16, + 1, + 0, + 0, + 0, + 169, + 170, + 5, + 97, + 0, + 0, + 170, + 171, + 5, + 115, + 0, + 0, + 171, + 172, + 5, + 105, + 0, + 0, + 172, + 173, + 5, + 110, + 0, + 0, + 173, + 18, + 1, + 0, + 0, + 0, + 174, + 175, + 5, + 97, + 0, + 0, + 175, + 176, + 5, + 99, + 0, + 0, + 176, + 177, + 5, + 111, + 0, + 0, + 177, + 178, + 5, + 115, + 0, + 0, + 178, + 20, + 1, + 0, + 0, + 0, + 179, + 180, + 5, + 97, + 0, + 0, + 180, + 181, + 5, + 116, + 0, + 0, + 181, + 182, + 5, + 97, + 0, + 0, + 182, + 183, + 5, + 110, + 0, + 0, + 183, + 22, + 1, + 0, + 0, + 0, + 184, + 185, + 5, + 97, + 0, + 0, + 185, + 186, + 5, + 116, + 0, + 0, + 186, + 187, + 5, + 97, + 0, + 0, + 187, + 188, + 5, + 110, + 0, + 0, + 188, + 189, + 5, + 50, + 0, + 0, + 189, + 24, + 1, + 0, + 0, + 0, + 190, + 191, + 5, + 115, + 0, + 0, + 191, + 192, + 5, + 105, + 0, + 0, + 192, + 193, + 5, + 110, + 0, + 0, + 193, + 194, + 5, + 104, + 0, + 0, + 194, + 26, + 1, + 0, + 0, + 0, + 195, + 196, + 5, + 99, + 0, + 0, + 196, + 197, + 5, + 111, + 0, + 0, + 197, + 198, + 5, + 115, + 0, + 0, + 198, + 199, + 5, + 104, + 0, + 0, + 199, + 28, + 1, + 0, + 0, + 0, + 200, + 201, + 5, + 116, + 0, + 0, + 201, + 202, + 5, + 97, + 0, + 0, + 202, + 203, + 5, + 110, + 0, + 0, + 203, + 204, + 5, + 104, + 0, + 0, + 204, + 30, + 1, + 0, + 0, + 0, + 205, + 206, + 5, + 97, + 0, + 0, + 206, + 207, + 5, + 115, + 0, + 0, + 207, + 208, + 5, + 105, + 0, + 0, + 208, + 209, + 5, + 110, + 0, + 0, + 209, + 210, + 5, + 104, + 0, + 0, + 210, + 32, + 1, + 0, + 0, + 0, + 211, + 212, + 5, + 97, + 0, + 0, + 212, + 213, + 5, + 99, + 0, + 0, + 213, + 214, + 5, + 111, + 0, + 0, + 214, + 215, + 5, + 115, + 0, + 0, + 215, + 216, + 5, + 104, + 0, + 0, + 216, + 34, + 1, + 0, + 0, + 0, + 217, + 218, + 5, + 97, + 0, + 0, + 218, + 219, + 5, + 116, + 0, + 0, + 219, + 220, + 5, + 97, + 0, + 0, + 220, + 221, + 5, + 110, + 0, + 0, + 221, + 222, + 5, + 104, + 0, + 0, + 222, + 36, + 1, + 0, + 0, + 0, + 223, + 224, + 5, + 97, + 0, + 0, + 224, + 225, + 5, + 98, + 0, + 0, + 225, + 226, + 5, + 115, + 0, + 0, + 226, + 38, + 1, + 0, + 0, + 0, + 227, + 228, + 5, + 115, + 0, + 0, + 228, + 229, + 5, + 113, + 0, + 0, + 229, + 230, + 5, + 114, + 0, + 0, + 230, + 231, + 5, + 116, + 0, + 0, + 231, + 40, + 1, + 0, + 0, + 0, + 232, + 233, + 5, + 108, + 0, + 0, + 233, + 234, + 5, + 110, + 0, + 0, + 234, + 42, + 1, + 0, + 0, + 0, + 235, + 236, + 5, + 108, + 0, + 0, + 236, + 237, + 5, + 111, + 0, + 0, + 237, + 238, + 5, + 103, + 0, + 0, + 238, + 44, + 1, + 0, + 0, + 0, + 239, + 240, + 5, + 101, + 0, + 0, + 240, + 241, + 5, + 120, + 0, + 0, + 241, + 242, + 5, + 112, + 0, + 0, + 242, + 46, + 1, + 0, + 0, + 0, + 243, + 244, + 5, + 115, + 0, + 0, + 244, + 245, + 5, + 109, + 0, + 0, + 245, + 246, + 5, + 105, + 0, + 0, + 246, + 247, + 5, + 110, + 0, + 0, + 247, + 48, + 1, + 0, + 0, + 0, + 248, + 249, + 5, + 115, + 0, + 0, + 249, + 250, + 5, + 109, + 0, + 0, + 250, + 251, + 5, + 97, + 0, + 0, + 251, + 252, + 5, + 120, + 0, + 0, + 252, + 50, + 1, + 0, + 0, + 0, + 253, + 254, + 5, + 116, + 0, + 0, + 254, + 255, + 5, + 109, + 0, + 0, + 255, + 256, + 5, + 105, + 0, + 0, + 256, + 257, + 5, + 110, + 0, + 0, + 257, + 52, + 1, + 0, + 0, + 0, + 258, + 259, + 5, + 116, + 0, + 0, + 259, + 260, + 5, + 109, + 0, + 0, + 260, + 261, + 5, + 97, + 0, + 0, + 261, + 262, + 5, + 120, + 0, + 0, + 262, + 54, + 1, + 0, + 0, + 0, + 263, + 264, + 5, + 116, + 0, + 0, + 264, + 265, + 5, + 110, + 0, + 0, + 265, + 266, + 5, + 111, + 0, + 0, + 266, + 267, + 5, + 114, + 0, + 0, + 267, + 268, + 5, + 109, + 0, + 0, + 268, + 56, + 1, + 0, + 0, + 0, + 269, + 270, + 5, + 115, + 0, + 0, + 270, + 271, + 5, + 110, + 0, + 0, + 271, + 272, + 5, + 111, + 0, + 0, + 272, + 273, + 5, + 114, + 0, + 0, + 273, + 274, + 5, + 109, + 0, + 0, + 274, + 58, + 1, + 0, + 0, + 0, + 275, + 276, + 5, + 102, + 0, + 0, + 276, + 277, + 5, + 108, + 0, + 0, + 277, + 278, + 5, + 111, + 0, + 0, + 278, + 279, + 5, + 111, + 0, + 0, + 279, + 280, + 5, + 114, + 0, + 0, + 280, + 60, + 1, + 0, + 0, + 0, + 281, + 282, + 5, + 99, + 0, + 0, + 282, + 283, + 5, + 101, + 0, + 0, + 283, + 284, + 5, + 105, + 0, + 0, + 284, + 285, + 5, + 108, + 0, + 0, + 285, + 62, + 1, + 0, + 0, + 0, + 286, + 287, + 5, + 114, + 0, + 0, + 287, + 288, + 5, + 111, + 0, + 0, + 288, + 289, + 5, + 117, + 0, + 0, + 289, + 290, + 5, + 110, + 0, + 0, + 290, + 291, + 5, + 100, + 0, + 0, + 291, + 64, + 1, + 0, + 0, + 0, + 292, + 293, + 5, + 103, + 0, + 0, + 293, + 294, + 5, + 97, + 0, + 0, + 294, + 295, + 5, + 109, + 0, + 0, + 295, + 296, + 5, + 109, + 0, + 0, + 296, + 297, + 5, + 97, + 0, + 0, + 297, + 66, + 1, + 0, + 0, + 0, + 298, + 299, + 5, + 112, + 0, + 0, + 299, + 300, + 5, + 111, + 0, + 0, + 300, + 301, + 5, + 119, + 0, + 0, + 301, + 68, + 1, + 0, + 0, + 0, + 302, + 303, + 5, + 115, + 0, + 0, + 303, + 304, + 5, + 105, + 0, + 0, + 304, + 305, + 5, + 103, + 0, + 0, + 305, + 306, + 5, + 109, + 0, + 0, + 306, + 70, + 1, + 0, + 0, + 0, + 307, + 308, + 5, + 99, + 0, + 0, + 308, + 309, + 5, + 108, + 0, + 0, + 309, + 310, + 5, + 97, + 0, + 0, + 310, + 311, + 5, + 109, + 0, + 0, + 311, + 312, + 5, + 112, + 0, + 0, + 312, + 72, + 1, + 0, + 0, + 0, + 313, + 314, + 5, + 102, + 0, + 0, + 314, + 315, + 5, + 102, + 0, + 0, + 315, + 316, + 5, + 116, + 0, + 0, + 316, + 74, + 1, + 0, + 0, + 0, + 317, + 318, + 5, + 105, + 0, + 0, + 318, + 319, + 5, + 102, + 0, + 0, + 319, + 320, + 5, + 102, + 0, + 0, + 320, + 321, + 5, + 116, + 0, + 0, + 321, + 76, + 1, + 0, + 0, + 0, + 322, + 323, + 5, + 97, + 0, + 0, + 323, + 324, + 5, + 110, + 0, + 0, + 324, + 325, + 5, + 103, + 0, + 0, + 325, + 326, + 5, + 108, + 0, + 0, + 326, + 327, + 5, + 101, + 0, + 0, + 327, + 78, + 1, + 0, + 0, + 0, + 328, + 329, + 5, + 112, + 0, + 0, + 329, + 330, + 5, + 114, + 0, + 0, + 330, + 331, + 5, + 105, + 0, + 0, + 331, + 332, + 5, + 110, + 0, + 0, + 332, + 333, + 5, + 116, + 0, + 0, + 333, + 80, + 1, + 0, + 0, + 0, + 334, + 335, + 5, + 112, + 0, + 0, + 335, + 336, + 5, + 114, + 0, + 0, + 336, + 337, + 5, + 105, + 0, + 0, + 337, + 338, + 5, + 110, + 0, + 0, + 338, + 339, + 5, + 116, + 0, + 0, + 339, + 340, + 5, + 95, + 0, + 0, + 340, + 341, + 5, + 115, + 0, + 0, + 341, + 342, + 5, + 104, + 0, + 0, + 342, + 343, + 5, + 97, + 0, + 0, + 343, + 344, + 5, + 112, + 0, + 0, + 344, + 345, + 5, + 101, + 0, + 0, + 345, + 82, + 1, + 0, + 0, + 0, + 346, + 347, + 5, + 112, + 0, + 0, + 347, + 348, + 5, + 115, + 0, + 0, + 348, + 349, + 5, + 104, + 0, + 0, + 349, + 350, + 5, + 112, + 0, + 0, + 350, + 84, + 1, + 0, + 0, + 0, + 351, + 352, + 5, + 108, + 0, + 0, + 352, + 353, + 5, + 101, + 0, + 0, + 353, + 354, + 5, + 114, + 0, + 0, + 354, + 355, + 5, + 112, + 0, + 0, + 355, + 86, + 1, + 0, + 0, + 0, + 356, + 357, + 5, + 115, + 0, + 0, + 357, + 358, + 5, + 116, + 0, + 0, + 358, + 359, + 5, + 101, + 0, + 0, + 359, + 360, + 5, + 112, + 0, + 0, + 360, + 88, + 1, + 0, + 0, + 0, + 361, + 362, + 5, + 115, + 0, + 0, + 362, + 363, + 5, + 109, + 0, + 0, + 363, + 364, + 5, + 111, + 0, + 0, + 364, + 365, + 5, + 111, + 0, + 0, + 365, + 366, + 5, + 116, + 0, + 0, + 366, + 367, + 5, + 104, + 0, + 0, + 367, + 368, + 5, + 115, + 0, + 0, + 368, + 369, + 5, + 116, + 0, + 0, + 369, + 370, + 5, + 101, + 0, + 0, + 370, + 371, + 5, + 112, + 0, + 0, + 371, + 90, + 1, + 0, + 0, + 0, + 372, + 373, + 5, + 102, + 0, + 0, + 373, + 374, + 5, + 114, + 0, + 0, + 374, + 375, + 5, + 97, + 0, + 0, + 375, + 376, + 5, + 99, + 0, + 0, + 376, + 377, + 5, + 116, + 0, + 0, + 377, + 92, + 1, + 0, + 0, + 0, + 378, + 379, + 5, + 114, + 0, + 0, + 379, + 380, + 5, + 101, + 0, + 0, + 380, + 381, + 5, + 108, + 0, + 0, + 381, + 382, + 5, + 117, + 0, + 0, + 382, + 94, + 1, + 0, + 0, + 0, + 383, + 384, + 5, + 115, + 0, + 0, + 384, + 385, + 5, + 111, + 0, + 0, + 385, + 386, + 5, + 102, + 0, + 0, + 386, + 387, + 5, + 116, + 0, + 0, + 387, + 388, + 5, + 112, + 0, + 0, + 388, + 389, + 5, + 108, + 0, + 0, + 389, + 390, + 5, + 117, + 0, + 0, + 390, + 391, + 5, + 115, + 0, + 0, + 391, + 96, + 1, + 0, + 0, + 0, + 392, + 393, + 5, + 103, + 0, + 0, + 393, + 394, + 5, + 101, + 0, + 0, + 394, + 395, + 5, + 108, + 0, + 0, + 395, + 396, + 5, + 117, + 0, + 0, + 396, + 98, + 1, + 0, + 0, + 0, + 397, + 398, + 5, + 115, + 0, + 0, + 398, + 399, + 5, + 105, + 0, + 0, + 399, + 400, + 5, + 103, + 0, + 0, + 400, + 401, + 5, + 110, + 0, + 0, + 401, + 100, + 1, + 0, + 0, + 0, + 402, + 403, + 5, + 109, + 0, + 0, + 403, + 404, + 5, + 97, + 0, + 0, + 404, + 405, + 5, + 112, + 0, + 0, + 405, + 102, + 1, + 0, + 0, + 0, + 406, + 407, + 5, + 99, + 0, + 0, + 407, + 408, + 5, + 111, + 0, + 0, + 408, + 409, + 5, + 110, + 0, + 0, + 409, + 410, + 5, + 118, + 0, + 0, + 410, + 104, + 1, + 0, + 0, + 0, + 411, + 412, + 5, + 115, + 0, + 0, + 412, + 413, + 5, + 119, + 0, + 0, + 413, + 414, + 5, + 97, + 0, + 0, + 414, + 415, + 5, + 112, + 0, + 0, + 415, + 106, + 1, + 0, + 0, + 0, + 416, + 417, + 5, + 112, + 0, + 0, + 417, + 418, + 5, + 101, + 0, + 0, + 418, + 419, + 5, + 114, + 0, + 0, + 419, + 420, + 5, + 109, + 0, + 0, + 420, + 421, + 5, + 117, + 0, + 0, + 421, + 422, + 5, + 116, + 0, + 0, + 422, + 423, + 5, + 101, + 0, + 0, + 423, + 108, + 1, + 0, + 0, + 0, + 424, + 425, + 5, + 114, + 0, + 0, + 425, + 426, + 5, + 101, + 0, + 0, + 426, + 427, + 5, + 115, + 0, + 0, + 427, + 428, + 5, + 104, + 0, + 0, + 428, + 429, + 5, + 97, + 0, + 0, + 429, + 430, + 5, + 112, + 0, + 0, + 430, + 431, + 5, + 101, + 0, + 0, + 431, + 110, + 1, + 0, + 0, + 0, + 432, + 433, + 5, + 114, + 0, + 0, + 433, + 434, + 5, + 97, + 0, + 0, + 434, + 435, + 5, + 110, + 0, + 0, + 435, + 436, + 5, + 103, + 0, + 0, + 436, + 437, + 5, + 101, + 0, + 0, + 437, + 112, + 1, + 0, + 0, + 0, + 438, + 439, + 5, + 43, + 0, + 0, + 439, + 114, + 1, + 0, + 0, + 0, + 440, + 441, + 5, + 45, + 0, + 0, + 441, + 116, + 1, + 0, + 0, + 0, + 442, + 443, + 5, + 42, + 0, + 0, + 443, + 118, + 1, + 0, + 0, + 0, + 444, + 445, + 5, + 47, + 0, + 0, + 445, + 120, + 1, + 0, + 0, + 0, + 446, + 447, + 5, + 37, + 0, + 0, + 447, + 122, + 1, + 0, + 0, + 0, + 448, + 449, + 5, + 94, + 0, + 0, + 449, + 124, + 1, + 0, + 0, + 0, + 450, + 451, + 5, + 62, + 0, + 0, + 451, + 452, + 5, + 61, + 0, + 0, + 452, + 126, + 1, + 0, + 0, + 0, + 453, + 454, + 5, + 62, + 0, + 0, + 454, + 128, + 1, + 0, + 0, + 0, + 455, + 456, + 5, + 60, + 0, + 0, + 456, + 457, + 5, + 61, + 0, + 0, + 457, + 130, + 1, + 0, + 0, + 0, + 458, + 459, + 5, + 60, + 0, + 0, + 459, + 132, + 1, + 0, + 0, + 0, + 460, + 461, + 5, + 61, + 0, + 0, + 461, + 462, + 5, + 61, + 0, + 0, + 462, + 134, + 1, + 0, + 0, + 0, + 463, + 464, + 5, + 33, + 0, + 0, + 464, + 465, + 5, + 61, + 0, + 0, + 465, + 136, + 1, + 0, + 0, + 0, + 466, + 467, + 5, + 124, + 0, + 0, + 467, + 138, + 1, + 0, + 0, + 0, + 468, + 469, + 5, + 112, + 0, + 0, + 469, + 474, + 5, + 105, + 0, + 0, + 470, + 471, + 5, + 80, + 0, + 0, + 471, + 474, + 5, + 73, + 0, + 0, + 472, + 474, + 7, + 0, + 0, + 0, + 473, + 468, + 1, + 0, + 0, + 0, + 473, + 470, + 1, + 0, + 0, + 0, + 473, + 472, + 1, + 0, + 0, + 0, + 474, + 140, + 1, + 0, + 0, + 0, + 475, + 477, + 7, + 1, + 0, + 0, + 476, + 475, + 1, + 0, + 0, + 0, + 477, + 478, + 1, + 0, + 0, + 0, + 478, + 476, + 1, + 0, + 0, + 0, + 478, + 479, + 1, + 0, + 0, + 0, + 479, + 486, + 1, + 0, + 0, + 0, + 480, + 482, + 5, + 46, + 0, + 0, + 481, + 483, + 7, + 1, + 0, + 0, + 482, + 481, + 1, + 0, + 0, + 0, + 483, + 484, + 1, + 0, + 0, + 0, + 484, + 482, + 1, + 0, + 0, + 0, + 484, + 485, + 1, + 0, + 0, + 0, + 485, + 487, + 1, + 0, + 0, + 0, + 486, + 480, + 1, + 0, + 0, + 0, + 486, + 487, + 1, + 0, + 0, + 0, + 487, + 142, + 1, + 0, + 0, + 0, + 488, + 492, + 7, + 2, + 0, + 0, + 489, + 491, + 7, + 3, + 0, + 0, + 490, + 489, + 1, + 0, + 0, + 0, + 491, + 494, + 1, + 0, + 0, + 0, + 492, + 490, + 1, + 0, + 0, + 0, + 492, + 493, + 1, + 0, + 0, + 0, + 493, + 144, + 1, + 0, + 0, + 0, + 494, + 492, + 1, + 0, + 0, + 0, + 495, + 497, + 7, + 4, + 0, + 0, + 496, + 495, + 1, + 0, + 0, + 0, + 497, + 498, + 1, + 0, + 0, + 0, + 498, + 496, + 1, + 0, + 0, + 0, + 498, + 499, + 1, + 0, + 0, + 0, + 499, + 500, + 1, + 0, + 0, + 0, + 500, + 501, + 6, + 72, + 0, + 0, + 501, + 146, + 1, + 0, + 0, + 0, + 7, + 0, + 473, + 478, + 484, + 486, + 492, + 498, + 1, + 6, + 0, + 0, ] -class MathExprLexer(Lexer): +class MathExprLexer(Lexer): atn = ATNDeserializer().deserialize(serializedATN()) - decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ] + decisionsToDFA = [DFA(ds, i) for i, ds in enumerate(atn.decisionToState)] T__0 = 1 T__1 = 2 @@ -268,53 +4360,236 @@ class MathExprLexer(Lexer): VARIABLE = 72 WS = 73 - channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ] + channelNames = ["DEFAULT_TOKEN_CHANNEL", "HIDDEN"] - modeNames = [ "DEFAULT_MODE" ] + modeNames = ["DEFAULT_MODE"] - literalNames = [ "", - "'('", "')'", "'['", "','", "']'", "'sin'", "'cos'", "'tan'", - "'asin'", "'acos'", "'atan'", "'atan2'", "'sinh'", "'cosh'", - "'tanh'", "'asinh'", "'acosh'", "'atanh'", "'abs'", "'sqrt'", - "'ln'", "'log'", "'exp'", "'smin'", "'smax'", "'tmin'", "'tmax'", - "'tnorm'", "'snorm'", "'floor'", "'ceil'", "'round'", "'gamma'", - "'pow'", "'sigm'", "'clamp'", "'fft'", "'ifft'", "'angle'", - "'print'", "'print_shape'", "'pshp'", "'lerp'", "'step'", "'smoothstep'", - "'fract'", "'relu'", "'softplus'", "'gelu'", "'sign'", "'map'", - "'conv'", "'swap'", "'permute'", "'reshape'", "'range'", "'+'", - "'-'", "'*'", "'/'", "'%'", "'^'", "'>='", "'>'", "'<='", "'<'", - "'=='", "'!='", "'|'" ] + literalNames = [ + "", + "'('", + "')'", + "'['", + "','", + "']'", + "'sin'", + "'cos'", + "'tan'", + "'asin'", + "'acos'", + "'atan'", + "'atan2'", + "'sinh'", + "'cosh'", + "'tanh'", + "'asinh'", + "'acosh'", + "'atanh'", + "'abs'", + "'sqrt'", + "'ln'", + "'log'", + "'exp'", + "'smin'", + "'smax'", + "'tmin'", + "'tmax'", + "'tnorm'", + "'snorm'", + "'floor'", + "'ceil'", + "'round'", + "'gamma'", + "'pow'", + "'sigm'", + "'clamp'", + "'fft'", + "'ifft'", + "'angle'", + "'print'", + "'print_shape'", + "'pshp'", + "'lerp'", + "'step'", + "'smoothstep'", + "'fract'", + "'relu'", + "'softplus'", + "'gelu'", + "'sign'", + "'map'", + "'conv'", + "'swap'", + "'permute'", + "'reshape'", + "'range'", + "'+'", + "'-'", + "'*'", + "'/'", + "'%'", + "'^'", + "'>='", + "'>'", + "'<='", + "'<'", + "'=='", + "'!='", + "'|'", + ] - symbolicNames = [ "", - "SIN", "COS", "TAN", "ASIN", "ACOS", "ATAN", "ATAN2", "SINH", - "COSH", "TANH", "ASINH", "ACOSH", "ATANH", "ABS", "SQRT", "LN", - "LOG", "EXP", "SMIN", "SMAX", "TMIN", "TMAX", "TNORM", "SNORM", - "FLOOR", "CEIL", "ROUND", "GAMMA", "POWE", "SIGM", "CLAMP", - "SFFT", "SIFFT", "ANGL", "PRNT", "PRINT_SHAPE_L", "PRINT_SHAPE", - "LERP", "STEP", "SMOOTHSTEP", "FRACT", "RELU", "SOFTPLUS", "GELU", - "SIGN", "MAP", "CONV", "SWAP", "PERM", "RESHAPE", "RANGE", "PLUS", - "MINUS", "MULT", "DIV", "MOD", "POW", "GE", "GT", "LE", "LT", - "EQ", "NE", "PIPE", "CONSTANT", "NUMBER", "VARIABLE", "WS" ] + symbolicNames = [ + "", + "SIN", + "COS", + "TAN", + "ASIN", + "ACOS", + "ATAN", + "ATAN2", + "SINH", + "COSH", + "TANH", + "ASINH", + "ACOSH", + "ATANH", + "ABS", + "SQRT", + "LN", + "LOG", + "EXP", + "SMIN", + "SMAX", + "TMIN", + "TMAX", + "TNORM", + "SNORM", + "FLOOR", + "CEIL", + "ROUND", + "GAMMA", + "POWE", + "SIGM", + "CLAMP", + "SFFT", + "SIFFT", + "ANGL", + "PRNT", + "PRINT_SHAPE_L", + "PRINT_SHAPE", + "LERP", + "STEP", + "SMOOTHSTEP", + "FRACT", + "RELU", + "SOFTPLUS", + "GELU", + "SIGN", + "MAP", + "CONV", + "SWAP", + "PERM", + "RESHAPE", + "RANGE", + "PLUS", + "MINUS", + "MULT", + "DIV", + "MOD", + "POW", + "GE", + "GT", + "LE", + "LT", + "EQ", + "NE", + "PIPE", + "CONSTANT", + "NUMBER", + "VARIABLE", + "WS", + ] - ruleNames = [ "T__0", "T__1", "T__2", "T__3", "T__4", "SIN", "COS", - "TAN", "ASIN", "ACOS", "ATAN", "ATAN2", "SINH", "COSH", - "TANH", "ASINH", "ACOSH", "ATANH", "ABS", "SQRT", "LN", - "LOG", "EXP", "SMIN", "SMAX", "TMIN", "TMAX", "TNORM", - "SNORM", "FLOOR", "CEIL", "ROUND", "GAMMA", "POWE", "SIGM", - "CLAMP", "SFFT", "SIFFT", "ANGL", "PRNT", "PRINT_SHAPE_L", - "PRINT_SHAPE", "LERP", "STEP", "SMOOTHSTEP", "FRACT", - "RELU", "SOFTPLUS", "GELU", "SIGN", "MAP", "CONV", "SWAP", - "PERM", "RESHAPE", "RANGE", "PLUS", "MINUS", "MULT", "DIV", - "MOD", "POW", "GE", "GT", "LE", "LT", "EQ", "NE", "PIPE", - "CONSTANT", "NUMBER", "VARIABLE", "WS" ] + ruleNames = [ + "T__0", + "T__1", + "T__2", + "T__3", + "T__4", + "SIN", + "COS", + "TAN", + "ASIN", + "ACOS", + "ATAN", + "ATAN2", + "SINH", + "COSH", + "TANH", + "ASINH", + "ACOSH", + "ATANH", + "ABS", + "SQRT", + "LN", + "LOG", + "EXP", + "SMIN", + "SMAX", + "TMIN", + "TMAX", + "TNORM", + "SNORM", + "FLOOR", + "CEIL", + "ROUND", + "GAMMA", + "POWE", + "SIGM", + "CLAMP", + "SFFT", + "SIFFT", + "ANGL", + "PRNT", + "PRINT_SHAPE_L", + "PRINT_SHAPE", + "LERP", + "STEP", + "SMOOTHSTEP", + "FRACT", + "RELU", + "SOFTPLUS", + "GELU", + "SIGN", + "MAP", + "CONV", + "SWAP", + "PERM", + "RESHAPE", + "RANGE", + "PLUS", + "MINUS", + "MULT", + "DIV", + "MOD", + "POW", + "GE", + "GT", + "LE", + "LT", + "EQ", + "NE", + "PIPE", + "CONSTANT", + "NUMBER", + "VARIABLE", + "WS", + ] grammarFileName = "MathExpr.g4" - def __init__(self, input=None, output:TextIO = sys.stdout): + def __init__(self, input=None, output: TextIO = sys.stdout): super().__init__(input, output) self.checkVersion("4.13.2") self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache()) self._actions = None self._predicates = None - - diff --git a/more_math/Parser/MathExprListener.py b/more_math/Parser/MathExprListener.py index 1ccba87..1659ae9 100644 --- a/more_math/Parser/MathExprListener.py +++ b/more_math/Parser/MathExprListener.py @@ -1,741 +1,661 @@ # Generated from ./MathExpr.g4 by ANTLR 4.13.2 from antlr4 import * + if "." in __name__: from .MathExprParser import MathExprParser else: from MathExprParser import MathExprParser + # This class defines a complete listener for a parse tree produced by MathExprParser. class MathExprListener(ParseTreeListener): - # Enter a parse tree produced by MathExprParser#expr. - def enterExpr(self, ctx:MathExprParser.ExprContext): + def enterExpr(self, ctx: MathExprParser.ExprContext): pass # Exit a parse tree produced by MathExprParser#expr. - def exitExpr(self, ctx:MathExprParser.ExprContext): + def exitExpr(self, ctx: MathExprParser.ExprContext): pass - # Enter a parse tree produced by MathExprParser#LtExp. - def enterLtExp(self, ctx:MathExprParser.LtExpContext): + def enterLtExp(self, ctx: MathExprParser.LtExpContext): pass # Exit a parse tree produced by MathExprParser#LtExp. - def exitLtExp(self, ctx:MathExprParser.LtExpContext): + def exitLtExp(self, ctx: MathExprParser.LtExpContext): pass - # Enter a parse tree produced by MathExprParser#EqExp. - def enterEqExp(self, ctx:MathExprParser.EqExpContext): + def enterEqExp(self, ctx: MathExprParser.EqExpContext): pass # Exit a parse tree produced by MathExprParser#EqExp. - def exitEqExp(self, ctx:MathExprParser.EqExpContext): + def exitEqExp(self, ctx: MathExprParser.EqExpContext): pass - # Enter a parse tree produced by MathExprParser#ToAdd. - def enterToAdd(self, ctx:MathExprParser.ToAddContext): + def enterToAdd(self, ctx: MathExprParser.ToAddContext): pass # Exit a parse tree produced by MathExprParser#ToAdd. - def exitToAdd(self, ctx:MathExprParser.ToAddContext): + def exitToAdd(self, ctx: MathExprParser.ToAddContext): pass - # Enter a parse tree produced by MathExprParser#GeExp. - def enterGeExp(self, ctx:MathExprParser.GeExpContext): + def enterGeExp(self, ctx: MathExprParser.GeExpContext): pass # Exit a parse tree produced by MathExprParser#GeExp. - def exitGeExp(self, ctx:MathExprParser.GeExpContext): + def exitGeExp(self, ctx: MathExprParser.GeExpContext): pass - # Enter a parse tree produced by MathExprParser#LeExp. - def enterLeExp(self, ctx:MathExprParser.LeExpContext): + def enterLeExp(self, ctx: MathExprParser.LeExpContext): pass # Exit a parse tree produced by MathExprParser#LeExp. - def exitLeExp(self, ctx:MathExprParser.LeExpContext): + def exitLeExp(self, ctx: MathExprParser.LeExpContext): pass - # Enter a parse tree produced by MathExprParser#NeExp. - def enterNeExp(self, ctx:MathExprParser.NeExpContext): + def enterNeExp(self, ctx: MathExprParser.NeExpContext): pass # Exit a parse tree produced by MathExprParser#NeExp. - def exitNeExp(self, ctx:MathExprParser.NeExpContext): + def exitNeExp(self, ctx: MathExprParser.NeExpContext): pass - # Enter a parse tree produced by MathExprParser#GtExp. - def enterGtExp(self, ctx:MathExprParser.GtExpContext): + def enterGtExp(self, ctx: MathExprParser.GtExpContext): pass # Exit a parse tree produced by MathExprParser#GtExp. - def exitGtExp(self, ctx:MathExprParser.GtExpContext): + def exitGtExp(self, ctx: MathExprParser.GtExpContext): pass - # Enter a parse tree produced by MathExprParser#AddExp. - def enterAddExp(self, ctx:MathExprParser.AddExpContext): + def enterAddExp(self, ctx: MathExprParser.AddExpContext): pass # Exit a parse tree produced by MathExprParser#AddExp. - def exitAddExp(self, ctx:MathExprParser.AddExpContext): + def exitAddExp(self, ctx: MathExprParser.AddExpContext): pass - # Enter a parse tree produced by MathExprParser#ToMul. - def enterToMul(self, ctx:MathExprParser.ToMulContext): + def enterToMul(self, ctx: MathExprParser.ToMulContext): pass # Exit a parse tree produced by MathExprParser#ToMul. - def exitToMul(self, ctx:MathExprParser.ToMulContext): + def exitToMul(self, ctx: MathExprParser.ToMulContext): pass - # Enter a parse tree produced by MathExprParser#SubExp. - def enterSubExp(self, ctx:MathExprParser.SubExpContext): + def enterSubExp(self, ctx: MathExprParser.SubExpContext): pass # Exit a parse tree produced by MathExprParser#SubExp. - def exitSubExp(self, ctx:MathExprParser.SubExpContext): + def exitSubExp(self, ctx: MathExprParser.SubExpContext): pass - # Enter a parse tree produced by MathExprParser#MulExp. - def enterMulExp(self, ctx:MathExprParser.MulExpContext): + def enterMulExp(self, ctx: MathExprParser.MulExpContext): pass # Exit a parse tree produced by MathExprParser#MulExp. - def exitMulExp(self, ctx:MathExprParser.MulExpContext): + def exitMulExp(self, ctx: MathExprParser.MulExpContext): pass - # Enter a parse tree produced by MathExprParser#ModExp. - def enterModExp(self, ctx:MathExprParser.ModExpContext): + def enterModExp(self, ctx: MathExprParser.ModExpContext): pass # Exit a parse tree produced by MathExprParser#ModExp. - def exitModExp(self, ctx:MathExprParser.ModExpContext): + def exitModExp(self, ctx: MathExprParser.ModExpContext): pass - # Enter a parse tree produced by MathExprParser#DivExp. - def enterDivExp(self, ctx:MathExprParser.DivExpContext): + def enterDivExp(self, ctx: MathExprParser.DivExpContext): pass # Exit a parse tree produced by MathExprParser#DivExp. - def exitDivExp(self, ctx:MathExprParser.DivExpContext): + def exitDivExp(self, ctx: MathExprParser.DivExpContext): pass - # Enter a parse tree produced by MathExprParser#ToPow. - def enterToPow(self, ctx:MathExprParser.ToPowContext): + def enterToPow(self, ctx: MathExprParser.ToPowContext): pass # Exit a parse tree produced by MathExprParser#ToPow. - def exitToPow(self, ctx:MathExprParser.ToPowContext): + def exitToPow(self, ctx: MathExprParser.ToPowContext): pass - # Enter a parse tree produced by MathExprParser#PowExp. - def enterPowExp(self, ctx:MathExprParser.PowExpContext): + def enterPowExp(self, ctx: MathExprParser.PowExpContext): pass # Exit a parse tree produced by MathExprParser#PowExp. - def exitPowExp(self, ctx:MathExprParser.PowExpContext): + def exitPowExp(self, ctx: MathExprParser.PowExpContext): pass - # Enter a parse tree produced by MathExprParser#ToUnary. - def enterToUnary(self, ctx:MathExprParser.ToUnaryContext): + def enterToUnary(self, ctx: MathExprParser.ToUnaryContext): pass # Exit a parse tree produced by MathExprParser#ToUnary. - def exitToUnary(self, ctx:MathExprParser.ToUnaryContext): + def exitToUnary(self, ctx: MathExprParser.ToUnaryContext): pass - # Enter a parse tree produced by MathExprParser#UnaryPlus. - def enterUnaryPlus(self, ctx:MathExprParser.UnaryPlusContext): + def enterUnaryPlus(self, ctx: MathExprParser.UnaryPlusContext): pass # Exit a parse tree produced by MathExprParser#UnaryPlus. - def exitUnaryPlus(self, ctx:MathExprParser.UnaryPlusContext): + def exitUnaryPlus(self, ctx: MathExprParser.UnaryPlusContext): pass - # Enter a parse tree produced by MathExprParser#UnaryMinus. - def enterUnaryMinus(self, ctx:MathExprParser.UnaryMinusContext): + def enterUnaryMinus(self, ctx: MathExprParser.UnaryMinusContext): pass # Exit a parse tree produced by MathExprParser#UnaryMinus. - def exitUnaryMinus(self, ctx:MathExprParser.UnaryMinusContext): + def exitUnaryMinus(self, ctx: MathExprParser.UnaryMinusContext): pass - # Enter a parse tree produced by MathExprParser#ToAtom. - def enterToAtom(self, ctx:MathExprParser.ToAtomContext): + def enterToAtom(self, ctx: MathExprParser.ToAtomContext): pass # Exit a parse tree produced by MathExprParser#ToAtom. - def exitToAtom(self, ctx:MathExprParser.ToAtomContext): + def exitToAtom(self, ctx: MathExprParser.ToAtomContext): pass - # Enter a parse tree produced by MathExprParser#Func1Exp. - def enterFunc1Exp(self, ctx:MathExprParser.Func1ExpContext): + def enterFunc1Exp(self, ctx: MathExprParser.Func1ExpContext): pass # Exit a parse tree produced by MathExprParser#Func1Exp. - def exitFunc1Exp(self, ctx:MathExprParser.Func1ExpContext): + def exitFunc1Exp(self, ctx: MathExprParser.Func1ExpContext): pass - # Enter a parse tree produced by MathExprParser#Func2Exp. - def enterFunc2Exp(self, ctx:MathExprParser.Func2ExpContext): + def enterFunc2Exp(self, ctx: MathExprParser.Func2ExpContext): pass # Exit a parse tree produced by MathExprParser#Func2Exp. - def exitFunc2Exp(self, ctx:MathExprParser.Func2ExpContext): + def exitFunc2Exp(self, ctx: MathExprParser.Func2ExpContext): pass - # Enter a parse tree produced by MathExprParser#Func3Exp. - def enterFunc3Exp(self, ctx:MathExprParser.Func3ExpContext): + def enterFunc3Exp(self, ctx: MathExprParser.Func3ExpContext): pass # Exit a parse tree produced by MathExprParser#Func3Exp. - def exitFunc3Exp(self, ctx:MathExprParser.Func3ExpContext): + def exitFunc3Exp(self, ctx: MathExprParser.Func3ExpContext): pass - # Enter a parse tree produced by MathExprParser#Func4Exp. - def enterFunc4Exp(self, ctx:MathExprParser.Func4ExpContext): + def enterFunc4Exp(self, ctx: MathExprParser.Func4ExpContext): pass # Exit a parse tree produced by MathExprParser#Func4Exp. - def exitFunc4Exp(self, ctx:MathExprParser.Func4ExpContext): + def exitFunc4Exp(self, ctx: MathExprParser.Func4ExpContext): pass - # Enter a parse tree produced by MathExprParser#FuncNExp. - def enterFuncNExp(self, ctx:MathExprParser.FuncNExpContext): + def enterFuncNExp(self, ctx: MathExprParser.FuncNExpContext): pass # Exit a parse tree produced by MathExprParser#FuncNExp. - def exitFuncNExp(self, ctx:MathExprParser.FuncNExpContext): + def exitFuncNExp(self, ctx: MathExprParser.FuncNExpContext): pass - # Enter a parse tree produced by MathExprParser#VariableExp. - def enterVariableExp(self, ctx:MathExprParser.VariableExpContext): + def enterVariableExp(self, ctx: MathExprParser.VariableExpContext): pass # Exit a parse tree produced by MathExprParser#VariableExp. - def exitVariableExp(self, ctx:MathExprParser.VariableExpContext): + def exitVariableExp(self, ctx: MathExprParser.VariableExpContext): pass - # Enter a parse tree produced by MathExprParser#NumberExp. - def enterNumberExp(self, ctx:MathExprParser.NumberExpContext): + def enterNumberExp(self, ctx: MathExprParser.NumberExpContext): pass # Exit a parse tree produced by MathExprParser#NumberExp. - def exitNumberExp(self, ctx:MathExprParser.NumberExpContext): + def exitNumberExp(self, ctx: MathExprParser.NumberExpContext): pass - # Enter a parse tree produced by MathExprParser#ConstantExp. - def enterConstantExp(self, ctx:MathExprParser.ConstantExpContext): + def enterConstantExp(self, ctx: MathExprParser.ConstantExpContext): pass # Exit a parse tree produced by MathExprParser#ConstantExp. - def exitConstantExp(self, ctx:MathExprParser.ConstantExpContext): + def exitConstantExp(self, ctx: MathExprParser.ConstantExpContext): pass - # Enter a parse tree produced by MathExprParser#ParenExp. - def enterParenExp(self, ctx:MathExprParser.ParenExpContext): + def enterParenExp(self, ctx: MathExprParser.ParenExpContext): pass # Exit a parse tree produced by MathExprParser#ParenExp. - def exitParenExp(self, ctx:MathExprParser.ParenExpContext): + def exitParenExp(self, ctx: MathExprParser.ParenExpContext): pass - # Enter a parse tree produced by MathExprParser#AbsExp. - def enterAbsExp(self, ctx:MathExprParser.AbsExpContext): + def enterAbsExp(self, ctx: MathExprParser.AbsExpContext): pass # Exit a parse tree produced by MathExprParser#AbsExp. - def exitAbsExp(self, ctx:MathExprParser.AbsExpContext): + def exitAbsExp(self, ctx: MathExprParser.AbsExpContext): pass - # Enter a parse tree produced by MathExprParser#ListExp. - def enterListExp(self, ctx:MathExprParser.ListExpContext): + def enterListExp(self, ctx: MathExprParser.ListExpContext): pass # Exit a parse tree produced by MathExprParser#ListExp. - def exitListExp(self, ctx:MathExprParser.ListExpContext): + def exitListExp(self, ctx: MathExprParser.ListExpContext): pass - # Enter a parse tree produced by MathExprParser#SinFunc. - def enterSinFunc(self, ctx:MathExprParser.SinFuncContext): + def enterSinFunc(self, ctx: MathExprParser.SinFuncContext): pass # Exit a parse tree produced by MathExprParser#SinFunc. - def exitSinFunc(self, ctx:MathExprParser.SinFuncContext): + def exitSinFunc(self, ctx: MathExprParser.SinFuncContext): pass - # Enter a parse tree produced by MathExprParser#CosFunc. - def enterCosFunc(self, ctx:MathExprParser.CosFuncContext): + def enterCosFunc(self, ctx: MathExprParser.CosFuncContext): pass # Exit a parse tree produced by MathExprParser#CosFunc. - def exitCosFunc(self, ctx:MathExprParser.CosFuncContext): + def exitCosFunc(self, ctx: MathExprParser.CosFuncContext): pass - # Enter a parse tree produced by MathExprParser#TanFunc. - def enterTanFunc(self, ctx:MathExprParser.TanFuncContext): + def enterTanFunc(self, ctx: MathExprParser.TanFuncContext): pass # Exit a parse tree produced by MathExprParser#TanFunc. - def exitTanFunc(self, ctx:MathExprParser.TanFuncContext): + def exitTanFunc(self, ctx: MathExprParser.TanFuncContext): pass - # Enter a parse tree produced by MathExprParser#AsinFunc. - def enterAsinFunc(self, ctx:MathExprParser.AsinFuncContext): + def enterAsinFunc(self, ctx: MathExprParser.AsinFuncContext): pass # Exit a parse tree produced by MathExprParser#AsinFunc. - def exitAsinFunc(self, ctx:MathExprParser.AsinFuncContext): + def exitAsinFunc(self, ctx: MathExprParser.AsinFuncContext): pass - # Enter a parse tree produced by MathExprParser#AcosFunc. - def enterAcosFunc(self, ctx:MathExprParser.AcosFuncContext): + def enterAcosFunc(self, ctx: MathExprParser.AcosFuncContext): pass # Exit a parse tree produced by MathExprParser#AcosFunc. - def exitAcosFunc(self, ctx:MathExprParser.AcosFuncContext): + def exitAcosFunc(self, ctx: MathExprParser.AcosFuncContext): pass - # Enter a parse tree produced by MathExprParser#AtanFunc. - def enterAtanFunc(self, ctx:MathExprParser.AtanFuncContext): + def enterAtanFunc(self, ctx: MathExprParser.AtanFuncContext): pass # Exit a parse tree produced by MathExprParser#AtanFunc. - def exitAtanFunc(self, ctx:MathExprParser.AtanFuncContext): + def exitAtanFunc(self, ctx: MathExprParser.AtanFuncContext): pass - # Enter a parse tree produced by MathExprParser#SinhFunc. - def enterSinhFunc(self, ctx:MathExprParser.SinhFuncContext): + def enterSinhFunc(self, ctx: MathExprParser.SinhFuncContext): pass # Exit a parse tree produced by MathExprParser#SinhFunc. - def exitSinhFunc(self, ctx:MathExprParser.SinhFuncContext): + def exitSinhFunc(self, ctx: MathExprParser.SinhFuncContext): pass - # Enter a parse tree produced by MathExprParser#CoshFunc. - def enterCoshFunc(self, ctx:MathExprParser.CoshFuncContext): + def enterCoshFunc(self, ctx: MathExprParser.CoshFuncContext): pass # Exit a parse tree produced by MathExprParser#CoshFunc. - def exitCoshFunc(self, ctx:MathExprParser.CoshFuncContext): + def exitCoshFunc(self, ctx: MathExprParser.CoshFuncContext): pass - # Enter a parse tree produced by MathExprParser#TanhFunc. - def enterTanhFunc(self, ctx:MathExprParser.TanhFuncContext): + def enterTanhFunc(self, ctx: MathExprParser.TanhFuncContext): pass # Exit a parse tree produced by MathExprParser#TanhFunc. - def exitTanhFunc(self, ctx:MathExprParser.TanhFuncContext): + def exitTanhFunc(self, ctx: MathExprParser.TanhFuncContext): pass - # Enter a parse tree produced by MathExprParser#AsinhFunc. - def enterAsinhFunc(self, ctx:MathExprParser.AsinhFuncContext): + def enterAsinhFunc(self, ctx: MathExprParser.AsinhFuncContext): pass # Exit a parse tree produced by MathExprParser#AsinhFunc. - def exitAsinhFunc(self, ctx:MathExprParser.AsinhFuncContext): + def exitAsinhFunc(self, ctx: MathExprParser.AsinhFuncContext): pass - # Enter a parse tree produced by MathExprParser#AcoshFunc. - def enterAcoshFunc(self, ctx:MathExprParser.AcoshFuncContext): + def enterAcoshFunc(self, ctx: MathExprParser.AcoshFuncContext): pass # Exit a parse tree produced by MathExprParser#AcoshFunc. - def exitAcoshFunc(self, ctx:MathExprParser.AcoshFuncContext): + def exitAcoshFunc(self, ctx: MathExprParser.AcoshFuncContext): pass - # Enter a parse tree produced by MathExprParser#AtanhFunc. - def enterAtanhFunc(self, ctx:MathExprParser.AtanhFuncContext): + def enterAtanhFunc(self, ctx: MathExprParser.AtanhFuncContext): pass # Exit a parse tree produced by MathExprParser#AtanhFunc. - def exitAtanhFunc(self, ctx:MathExprParser.AtanhFuncContext): + def exitAtanhFunc(self, ctx: MathExprParser.AtanhFuncContext): pass - # Enter a parse tree produced by MathExprParser#AbsFunc. - def enterAbsFunc(self, ctx:MathExprParser.AbsFuncContext): + def enterAbsFunc(self, ctx: MathExprParser.AbsFuncContext): pass # Exit a parse tree produced by MathExprParser#AbsFunc. - def exitAbsFunc(self, ctx:MathExprParser.AbsFuncContext): + def exitAbsFunc(self, ctx: MathExprParser.AbsFuncContext): pass - # Enter a parse tree produced by MathExprParser#SqrtFunc. - def enterSqrtFunc(self, ctx:MathExprParser.SqrtFuncContext): + def enterSqrtFunc(self, ctx: MathExprParser.SqrtFuncContext): pass # Exit a parse tree produced by MathExprParser#SqrtFunc. - def exitSqrtFunc(self, ctx:MathExprParser.SqrtFuncContext): + def exitSqrtFunc(self, ctx: MathExprParser.SqrtFuncContext): pass - # Enter a parse tree produced by MathExprParser#LnFunc. - def enterLnFunc(self, ctx:MathExprParser.LnFuncContext): + def enterLnFunc(self, ctx: MathExprParser.LnFuncContext): pass # Exit a parse tree produced by MathExprParser#LnFunc. - def exitLnFunc(self, ctx:MathExprParser.LnFuncContext): + def exitLnFunc(self, ctx: MathExprParser.LnFuncContext): pass - # Enter a parse tree produced by MathExprParser#LogFunc. - def enterLogFunc(self, ctx:MathExprParser.LogFuncContext): + def enterLogFunc(self, ctx: MathExprParser.LogFuncContext): pass # Exit a parse tree produced by MathExprParser#LogFunc. - def exitLogFunc(self, ctx:MathExprParser.LogFuncContext): + def exitLogFunc(self, ctx: MathExprParser.LogFuncContext): pass - # Enter a parse tree produced by MathExprParser#ExpFunc. - def enterExpFunc(self, ctx:MathExprParser.ExpFuncContext): + def enterExpFunc(self, ctx: MathExprParser.ExpFuncContext): pass # Exit a parse tree produced by MathExprParser#ExpFunc. - def exitExpFunc(self, ctx:MathExprParser.ExpFuncContext): + def exitExpFunc(self, ctx: MathExprParser.ExpFuncContext): pass - # Enter a parse tree produced by MathExprParser#TNormFunc. - def enterTNormFunc(self, ctx:MathExprParser.TNormFuncContext): + def enterTNormFunc(self, ctx: MathExprParser.TNormFuncContext): pass # Exit a parse tree produced by MathExprParser#TNormFunc. - def exitTNormFunc(self, ctx:MathExprParser.TNormFuncContext): + def exitTNormFunc(self, ctx: MathExprParser.TNormFuncContext): pass - # Enter a parse tree produced by MathExprParser#SNormFunc. - def enterSNormFunc(self, ctx:MathExprParser.SNormFuncContext): + def enterSNormFunc(self, ctx: MathExprParser.SNormFuncContext): pass # Exit a parse tree produced by MathExprParser#SNormFunc. - def exitSNormFunc(self, ctx:MathExprParser.SNormFuncContext): + def exitSNormFunc(self, ctx: MathExprParser.SNormFuncContext): pass - # Enter a parse tree produced by MathExprParser#FloorFunc. - def enterFloorFunc(self, ctx:MathExprParser.FloorFuncContext): + def enterFloorFunc(self, ctx: MathExprParser.FloorFuncContext): pass # Exit a parse tree produced by MathExprParser#FloorFunc. - def exitFloorFunc(self, ctx:MathExprParser.FloorFuncContext): + def exitFloorFunc(self, ctx: MathExprParser.FloorFuncContext): pass - # Enter a parse tree produced by MathExprParser#CeilFunc. - def enterCeilFunc(self, ctx:MathExprParser.CeilFuncContext): + def enterCeilFunc(self, ctx: MathExprParser.CeilFuncContext): pass # Exit a parse tree produced by MathExprParser#CeilFunc. - def exitCeilFunc(self, ctx:MathExprParser.CeilFuncContext): + def exitCeilFunc(self, ctx: MathExprParser.CeilFuncContext): pass - # Enter a parse tree produced by MathExprParser#RoundFunc. - def enterRoundFunc(self, ctx:MathExprParser.RoundFuncContext): + def enterRoundFunc(self, ctx: MathExprParser.RoundFuncContext): pass # Exit a parse tree produced by MathExprParser#RoundFunc. - def exitRoundFunc(self, ctx:MathExprParser.RoundFuncContext): + def exitRoundFunc(self, ctx: MathExprParser.RoundFuncContext): pass - # Enter a parse tree produced by MathExprParser#GammaFunc. - def enterGammaFunc(self, ctx:MathExprParser.GammaFuncContext): + def enterGammaFunc(self, ctx: MathExprParser.GammaFuncContext): pass # Exit a parse tree produced by MathExprParser#GammaFunc. - def exitGammaFunc(self, ctx:MathExprParser.GammaFuncContext): + def exitGammaFunc(self, ctx: MathExprParser.GammaFuncContext): pass - # Enter a parse tree produced by MathExprParser#sigmoidFunc. - def enterSigmoidFunc(self, ctx:MathExprParser.SigmoidFuncContext): + def enterSigmoidFunc(self, ctx: MathExprParser.SigmoidFuncContext): pass # Exit a parse tree produced by MathExprParser#sigmoidFunc. - def exitSigmoidFunc(self, ctx:MathExprParser.SigmoidFuncContext): + def exitSigmoidFunc(self, ctx: MathExprParser.SigmoidFuncContext): pass - # Enter a parse tree produced by MathExprParser#sfftFunc. - def enterSfftFunc(self, ctx:MathExprParser.SfftFuncContext): + def enterSfftFunc(self, ctx: MathExprParser.SfftFuncContext): pass # Exit a parse tree produced by MathExprParser#sfftFunc. - def exitSfftFunc(self, ctx:MathExprParser.SfftFuncContext): + def exitSfftFunc(self, ctx: MathExprParser.SfftFuncContext): pass - # Enter a parse tree produced by MathExprParser#sifftFunc. - def enterSifftFunc(self, ctx:MathExprParser.SifftFuncContext): + def enterSifftFunc(self, ctx: MathExprParser.SifftFuncContext): pass # Exit a parse tree produced by MathExprParser#sifftFunc. - def exitSifftFunc(self, ctx:MathExprParser.SifftFuncContext): + def exitSifftFunc(self, ctx: MathExprParser.SifftFuncContext): pass - # Enter a parse tree produced by MathExprParser#anglFunc. - def enterAnglFunc(self, ctx:MathExprParser.AnglFuncContext): + def enterAnglFunc(self, ctx: MathExprParser.AnglFuncContext): pass # Exit a parse tree produced by MathExprParser#anglFunc. - def exitAnglFunc(self, ctx:MathExprParser.AnglFuncContext): + def exitAnglFunc(self, ctx: MathExprParser.AnglFuncContext): pass - # Enter a parse tree produced by MathExprParser#printFunc. - def enterPrintFunc(self, ctx:MathExprParser.PrintFuncContext): + def enterPrintFunc(self, ctx: MathExprParser.PrintFuncContext): pass # Exit a parse tree produced by MathExprParser#printFunc. - def exitPrintFunc(self, ctx:MathExprParser.PrintFuncContext): + def exitPrintFunc(self, ctx: MathExprParser.PrintFuncContext): pass - # Enter a parse tree produced by MathExprParser#FractFunc. - def enterFractFunc(self, ctx:MathExprParser.FractFuncContext): + def enterFractFunc(self, ctx: MathExprParser.FractFuncContext): pass # Exit a parse tree produced by MathExprParser#FractFunc. - def exitFractFunc(self, ctx:MathExprParser.FractFuncContext): + def exitFractFunc(self, ctx: MathExprParser.FractFuncContext): pass - # Enter a parse tree produced by MathExprParser#ReluFunc. - def enterReluFunc(self, ctx:MathExprParser.ReluFuncContext): + def enterReluFunc(self, ctx: MathExprParser.ReluFuncContext): pass # Exit a parse tree produced by MathExprParser#ReluFunc. - def exitReluFunc(self, ctx:MathExprParser.ReluFuncContext): + def exitReluFunc(self, ctx: MathExprParser.ReluFuncContext): pass - # Enter a parse tree produced by MathExprParser#SoftplusFunc. - def enterSoftplusFunc(self, ctx:MathExprParser.SoftplusFuncContext): + def enterSoftplusFunc(self, ctx: MathExprParser.SoftplusFuncContext): pass # Exit a parse tree produced by MathExprParser#SoftplusFunc. - def exitSoftplusFunc(self, ctx:MathExprParser.SoftplusFuncContext): + def exitSoftplusFunc(self, ctx: MathExprParser.SoftplusFuncContext): pass - # Enter a parse tree produced by MathExprParser#GeluFunc. - def enterGeluFunc(self, ctx:MathExprParser.GeluFuncContext): + def enterGeluFunc(self, ctx: MathExprParser.GeluFuncContext): pass # Exit a parse tree produced by MathExprParser#GeluFunc. - def exitGeluFunc(self, ctx:MathExprParser.GeluFuncContext): + def exitGeluFunc(self, ctx: MathExprParser.GeluFuncContext): pass - # Enter a parse tree produced by MathExprParser#SignFunc. - def enterSignFunc(self, ctx:MathExprParser.SignFuncContext): + def enterSignFunc(self, ctx: MathExprParser.SignFuncContext): pass # Exit a parse tree produced by MathExprParser#SignFunc. - def exitSignFunc(self, ctx:MathExprParser.SignFuncContext): + def exitSignFunc(self, ctx: MathExprParser.SignFuncContext): pass - # Enter a parse tree produced by MathExprParser#PrintShapeFunc. - def enterPrintShapeFunc(self, ctx:MathExprParser.PrintShapeFuncContext): + def enterPrintShapeFunc(self, ctx: MathExprParser.PrintShapeFuncContext): pass # Exit a parse tree produced by MathExprParser#PrintShapeFunc. - def exitPrintShapeFunc(self, ctx:MathExprParser.PrintShapeFuncContext): + def exitPrintShapeFunc(self, ctx: MathExprParser.PrintShapeFuncContext): pass - # Enter a parse tree produced by MathExprParser#PowFunc. - def enterPowFunc(self, ctx:MathExprParser.PowFuncContext): + def enterPowFunc(self, ctx: MathExprParser.PowFuncContext): pass # Exit a parse tree produced by MathExprParser#PowFunc. - def exitPowFunc(self, ctx:MathExprParser.PowFuncContext): + def exitPowFunc(self, ctx: MathExprParser.PowFuncContext): pass - # Enter a parse tree produced by MathExprParser#Atan2Func. - def enterAtan2Func(self, ctx:MathExprParser.Atan2FuncContext): + def enterAtan2Func(self, ctx: MathExprParser.Atan2FuncContext): pass # Exit a parse tree produced by MathExprParser#Atan2Func. - def exitAtan2Func(self, ctx:MathExprParser.Atan2FuncContext): + def exitAtan2Func(self, ctx: MathExprParser.Atan2FuncContext): pass - # Enter a parse tree produced by MathExprParser#TMinFunc. - def enterTMinFunc(self, ctx:MathExprParser.TMinFuncContext): + def enterTMinFunc(self, ctx: MathExprParser.TMinFuncContext): pass # Exit a parse tree produced by MathExprParser#TMinFunc. - def exitTMinFunc(self, ctx:MathExprParser.TMinFuncContext): + def exitTMinFunc(self, ctx: MathExprParser.TMinFuncContext): pass - # Enter a parse tree produced by MathExprParser#TMaxFunc. - def enterTMaxFunc(self, ctx:MathExprParser.TMaxFuncContext): + def enterTMaxFunc(self, ctx: MathExprParser.TMaxFuncContext): pass # Exit a parse tree produced by MathExprParser#TMaxFunc. - def exitTMaxFunc(self, ctx:MathExprParser.TMaxFuncContext): + def exitTMaxFunc(self, ctx: MathExprParser.TMaxFuncContext): pass - # Enter a parse tree produced by MathExprParser#StepFunc. - def enterStepFunc(self, ctx:MathExprParser.StepFuncContext): + def enterStepFunc(self, ctx: MathExprParser.StepFuncContext): pass # Exit a parse tree produced by MathExprParser#StepFunc. - def exitStepFunc(self, ctx:MathExprParser.StepFuncContext): + def exitStepFunc(self, ctx: MathExprParser.StepFuncContext): pass - # Enter a parse tree produced by MathExprParser#ClampFunc. - def enterClampFunc(self, ctx:MathExprParser.ClampFuncContext): + def enterClampFunc(self, ctx: MathExprParser.ClampFuncContext): pass # Exit a parse tree produced by MathExprParser#ClampFunc. - def exitClampFunc(self, ctx:MathExprParser.ClampFuncContext): + def exitClampFunc(self, ctx: MathExprParser.ClampFuncContext): pass - # Enter a parse tree produced by MathExprParser#LerpFunc. - def enterLerpFunc(self, ctx:MathExprParser.LerpFuncContext): + def enterLerpFunc(self, ctx: MathExprParser.LerpFuncContext): pass # Exit a parse tree produced by MathExprParser#LerpFunc. - def exitLerpFunc(self, ctx:MathExprParser.LerpFuncContext): + def exitLerpFunc(self, ctx: MathExprParser.LerpFuncContext): pass - # Enter a parse tree produced by MathExprParser#SmoothstepFunc. - def enterSmoothstepFunc(self, ctx:MathExprParser.SmoothstepFuncContext): + def enterSmoothstepFunc(self, ctx: MathExprParser.SmoothstepFuncContext): pass # Exit a parse tree produced by MathExprParser#SmoothstepFunc. - def exitSmoothstepFunc(self, ctx:MathExprParser.SmoothstepFuncContext): + def exitSmoothstepFunc(self, ctx: MathExprParser.SmoothstepFuncContext): pass - # Enter a parse tree produced by MathExprParser#RangeFunc. - def enterRangeFunc(self, ctx:MathExprParser.RangeFuncContext): + def enterRangeFunc(self, ctx: MathExprParser.RangeFuncContext): pass # Exit a parse tree produced by MathExprParser#RangeFunc. - def exitRangeFunc(self, ctx:MathExprParser.RangeFuncContext): + def exitRangeFunc(self, ctx: MathExprParser.RangeFuncContext): pass - # Enter a parse tree produced by MathExprParser#SwapFunc. - def enterSwapFunc(self, ctx:MathExprParser.SwapFuncContext): + def enterSwapFunc(self, ctx: MathExprParser.SwapFuncContext): pass # Exit a parse tree produced by MathExprParser#SwapFunc. - def exitSwapFunc(self, ctx:MathExprParser.SwapFuncContext): + def exitSwapFunc(self, ctx: MathExprParser.SwapFuncContext): pass - # Enter a parse tree produced by MathExprParser#SMinFunc. - def enterSMinFunc(self, ctx:MathExprParser.SMinFuncContext): + def enterSMinFunc(self, ctx: MathExprParser.SMinFuncContext): pass # Exit a parse tree produced by MathExprParser#SMinFunc. - def exitSMinFunc(self, ctx:MathExprParser.SMinFuncContext): + def exitSMinFunc(self, ctx: MathExprParser.SMinFuncContext): pass - # Enter a parse tree produced by MathExprParser#SMaxFunc. - def enterSMaxFunc(self, ctx:MathExprParser.SMaxFuncContext): + def enterSMaxFunc(self, ctx: MathExprParser.SMaxFuncContext): pass # Exit a parse tree produced by MathExprParser#SMaxFunc. - def exitSMaxFunc(self, ctx:MathExprParser.SMaxFuncContext): + def exitSMaxFunc(self, ctx: MathExprParser.SMaxFuncContext): pass - # Enter a parse tree produced by MathExprParser#MapFunc. - def enterMapFunc(self, ctx:MathExprParser.MapFuncContext): + def enterMapFunc(self, ctx: MathExprParser.MapFuncContext): pass # Exit a parse tree produced by MathExprParser#MapFunc. - def exitMapFunc(self, ctx:MathExprParser.MapFuncContext): + def exitMapFunc(self, ctx: MathExprParser.MapFuncContext): pass - # Enter a parse tree produced by MathExprParser#ConvFunc. - def enterConvFunc(self, ctx:MathExprParser.ConvFuncContext): + def enterConvFunc(self, ctx: MathExprParser.ConvFuncContext): pass # Exit a parse tree produced by MathExprParser#ConvFunc. - def exitConvFunc(self, ctx:MathExprParser.ConvFuncContext): + def exitConvFunc(self, ctx: MathExprParser.ConvFuncContext): pass - # Enter a parse tree produced by MathExprParser#PermuteFunc. - def enterPermuteFunc(self, ctx:MathExprParser.PermuteFuncContext): + def enterPermuteFunc(self, ctx: MathExprParser.PermuteFuncContext): pass # Exit a parse tree produced by MathExprParser#PermuteFunc. - def exitPermuteFunc(self, ctx:MathExprParser.PermuteFuncContext): + def exitPermuteFunc(self, ctx: MathExprParser.PermuteFuncContext): pass - # Enter a parse tree produced by MathExprParser#ReshapeFunc. - def enterReshapeFunc(self, ctx:MathExprParser.ReshapeFuncContext): + def enterReshapeFunc(self, ctx: MathExprParser.ReshapeFuncContext): pass # Exit a parse tree produced by MathExprParser#ReshapeFunc. - def exitReshapeFunc(self, ctx:MathExprParser.ReshapeFuncContext): + def exitReshapeFunc(self, ctx: MathExprParser.ReshapeFuncContext): pass - -del MathExprParser \ No newline at end of file +del MathExprParser diff --git a/more_math/Parser/MathExprParser.py b/more_math/Parser/MathExprParser.py index 2acbc20..c416cd1 100644 --- a/more_math/Parser/MathExprParser.py +++ b/more_math/Parser/MathExprParser.py @@ -3,212 +3,4255 @@ from antlr4 import * from io import StringIO import sys + if sys.version_info[1] > 5: - from typing import TextIO + from typing import TextIO else: - from typing.io import TextIO + from typing.io import TextIO + def serializedATN(): return [ - 4,1,73,454,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, - 6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,1,0,1,0,3,0,27,8,0, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,5,1,50,8,1,10,1,12,1,53,9,1,1,2,1,2,1,2,1,2, - 1,2,1,2,1,2,1,2,1,2,5,2,64,8,2,10,2,12,2,67,9,2,1,3,1,3,1,3,1,3, - 1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,5,3,81,8,3,10,3,12,3,84,9,3,1,4, - 1,4,1,4,1,4,1,4,3,4,91,8,4,1,5,1,5,1,5,1,5,1,5,3,5,98,8,5,1,6,1, - 6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1,6,1, - 6,1,6,1,6,5,6,120,8,6,10,6,12,6,123,9,6,1,6,1,6,3,6,127,8,6,1,7, - 1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7, - 1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7, - 1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7, - 1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7, - 1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7, - 1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7, - 1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7, - 1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7, - 1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7, - 1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7, - 1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,7,3,7,304, - 8,7,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8, - 1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8, - 1,8,1,8,1,8,1,8,3,8,341,8,8,1,9,1,9,1,9,1,9,1,9,1,9,1,9,1,9,1,9, - 1,9,1,9,1,9,1,9,1,9,1,9,1,9,1,9,1,9,1,9,1,9,1,9,1,9,1,9,1,9,1,9, - 1,9,1,9,1,9,1,9,1,9,1,9,1,9,1,9,1,9,1,9,1,9,3,9,379,8,9,1,10,1,10, - 1,10,1,10,1,10,1,10,1,10,1,10,1,10,1,10,1,10,1,11,1,11,1,11,1,11, - 1,11,5,11,397,8,11,10,11,12,11,400,9,11,1,11,1,11,1,11,1,11,1,11, - 1,11,1,11,5,11,409,8,11,10,11,12,11,412,9,11,1,11,1,11,1,11,1,11, - 1,11,1,11,1,11,4,11,421,8,11,11,11,12,11,422,1,11,1,11,1,11,1,11, - 1,11,1,11,1,11,4,11,432,8,11,11,11,12,11,433,1,11,1,11,1,11,1,11, - 1,11,1,11,1,11,1,11,1,11,1,11,1,11,1,11,1,11,1,11,1,11,1,11,3,11, - 452,8,11,1,11,0,3,2,4,6,12,0,2,4,6,8,10,12,14,16,18,20,22,0,0,517, - 0,26,1,0,0,0,2,28,1,0,0,0,4,54,1,0,0,0,6,68,1,0,0,0,8,90,1,0,0,0, - 10,97,1,0,0,0,12,126,1,0,0,0,14,303,1,0,0,0,16,340,1,0,0,0,18,378, - 1,0,0,0,20,380,1,0,0,0,22,451,1,0,0,0,24,27,3,12,6,0,25,27,3,2,1, - 0,26,24,1,0,0,0,26,25,1,0,0,0,27,1,1,0,0,0,28,29,6,1,-1,0,29,30, - 3,4,2,0,30,51,1,0,0,0,31,32,10,7,0,0,32,33,5,64,0,0,33,50,3,4,2, - 0,34,35,10,6,0,0,35,36,5,63,0,0,36,50,3,4,2,0,37,38,10,5,0,0,38, - 39,5,66,0,0,39,50,3,4,2,0,40,41,10,4,0,0,41,42,5,65,0,0,42,50,3, - 4,2,0,43,44,10,3,0,0,44,45,5,67,0,0,45,50,3,4,2,0,46,47,10,2,0,0, - 47,48,5,68,0,0,48,50,3,4,2,0,49,31,1,0,0,0,49,34,1,0,0,0,49,37,1, - 0,0,0,49,40,1,0,0,0,49,43,1,0,0,0,49,46,1,0,0,0,50,53,1,0,0,0,51, - 49,1,0,0,0,51,52,1,0,0,0,52,3,1,0,0,0,53,51,1,0,0,0,54,55,6,2,-1, - 0,55,56,3,6,3,0,56,65,1,0,0,0,57,58,10,3,0,0,58,59,5,57,0,0,59,64, - 3,6,3,0,60,61,10,2,0,0,61,62,5,58,0,0,62,64,3,6,3,0,63,57,1,0,0, - 0,63,60,1,0,0,0,64,67,1,0,0,0,65,63,1,0,0,0,65,66,1,0,0,0,66,5,1, - 0,0,0,67,65,1,0,0,0,68,69,6,3,-1,0,69,70,3,8,4,0,70,82,1,0,0,0,71, - 72,10,4,0,0,72,73,5,59,0,0,73,81,3,8,4,0,74,75,10,3,0,0,75,76,5, - 60,0,0,76,81,3,8,4,0,77,78,10,2,0,0,78,79,5,61,0,0,79,81,3,8,4,0, - 80,71,1,0,0,0,80,74,1,0,0,0,80,77,1,0,0,0,81,84,1,0,0,0,82,80,1, - 0,0,0,82,83,1,0,0,0,83,7,1,0,0,0,84,82,1,0,0,0,85,86,3,10,5,0,86, - 87,5,62,0,0,87,88,3,8,4,0,88,91,1,0,0,0,89,91,3,10,5,0,90,85,1,0, - 0,0,90,89,1,0,0,0,91,9,1,0,0,0,92,93,5,57,0,0,93,98,3,10,5,0,94, - 95,5,58,0,0,95,98,3,10,5,0,96,98,3,12,6,0,97,92,1,0,0,0,97,94,1, - 0,0,0,97,96,1,0,0,0,98,11,1,0,0,0,99,127,3,14,7,0,100,127,3,16,8, - 0,101,127,3,18,9,0,102,127,3,20,10,0,103,127,3,22,11,0,104,127,5, - 72,0,0,105,127,5,71,0,0,106,127,5,70,0,0,107,108,5,1,0,0,108,109, - 3,0,0,0,109,110,5,2,0,0,110,127,1,0,0,0,111,112,5,69,0,0,112,113, - 3,0,0,0,113,114,5,69,0,0,114,127,1,0,0,0,115,116,5,3,0,0,116,121, - 3,0,0,0,117,118,5,4,0,0,118,120,3,0,0,0,119,117,1,0,0,0,120,123, - 1,0,0,0,121,119,1,0,0,0,121,122,1,0,0,0,122,124,1,0,0,0,123,121, - 1,0,0,0,124,125,5,5,0,0,125,127,1,0,0,0,126,99,1,0,0,0,126,100,1, - 0,0,0,126,101,1,0,0,0,126,102,1,0,0,0,126,103,1,0,0,0,126,104,1, - 0,0,0,126,105,1,0,0,0,126,106,1,0,0,0,126,107,1,0,0,0,126,111,1, - 0,0,0,126,115,1,0,0,0,127,13,1,0,0,0,128,129,5,6,0,0,129,130,5,1, - 0,0,130,131,3,0,0,0,131,132,5,2,0,0,132,304,1,0,0,0,133,134,5,7, - 0,0,134,135,5,1,0,0,135,136,3,0,0,0,136,137,5,2,0,0,137,304,1,0, - 0,0,138,139,5,8,0,0,139,140,5,1,0,0,140,141,3,0,0,0,141,142,5,2, - 0,0,142,304,1,0,0,0,143,144,5,9,0,0,144,145,5,1,0,0,145,146,3,0, - 0,0,146,147,5,2,0,0,147,304,1,0,0,0,148,149,5,10,0,0,149,150,5,1, - 0,0,150,151,3,0,0,0,151,152,5,2,0,0,152,304,1,0,0,0,153,154,5,11, - 0,0,154,155,5,1,0,0,155,156,3,0,0,0,156,157,5,2,0,0,157,304,1,0, - 0,0,158,159,5,13,0,0,159,160,5,1,0,0,160,161,3,0,0,0,161,162,5,2, - 0,0,162,304,1,0,0,0,163,164,5,14,0,0,164,165,5,1,0,0,165,166,3,0, - 0,0,166,167,5,2,0,0,167,304,1,0,0,0,168,169,5,15,0,0,169,170,5,1, - 0,0,170,171,3,0,0,0,171,172,5,2,0,0,172,304,1,0,0,0,173,174,5,16, - 0,0,174,175,5,1,0,0,175,176,3,0,0,0,176,177,5,2,0,0,177,304,1,0, - 0,0,178,179,5,17,0,0,179,180,5,1,0,0,180,181,3,0,0,0,181,182,5,2, - 0,0,182,304,1,0,0,0,183,184,5,18,0,0,184,185,5,1,0,0,185,186,3,0, - 0,0,186,187,5,2,0,0,187,304,1,0,0,0,188,189,5,19,0,0,189,190,5,1, - 0,0,190,191,3,0,0,0,191,192,5,2,0,0,192,304,1,0,0,0,193,194,5,20, - 0,0,194,195,5,1,0,0,195,196,3,0,0,0,196,197,5,2,0,0,197,304,1,0, - 0,0,198,199,5,21,0,0,199,200,5,1,0,0,200,201,3,0,0,0,201,202,5,2, - 0,0,202,304,1,0,0,0,203,204,5,22,0,0,204,205,5,1,0,0,205,206,3,0, - 0,0,206,207,5,2,0,0,207,304,1,0,0,0,208,209,5,23,0,0,209,210,5,1, - 0,0,210,211,3,0,0,0,211,212,5,2,0,0,212,304,1,0,0,0,213,214,5,28, - 0,0,214,215,5,1,0,0,215,216,3,0,0,0,216,217,5,2,0,0,217,304,1,0, - 0,0,218,219,5,29,0,0,219,220,5,1,0,0,220,221,3,0,0,0,221,222,5,2, - 0,0,222,304,1,0,0,0,223,224,5,30,0,0,224,225,5,1,0,0,225,226,3,0, - 0,0,226,227,5,2,0,0,227,304,1,0,0,0,228,229,5,31,0,0,229,230,5,1, - 0,0,230,231,3,0,0,0,231,232,5,2,0,0,232,304,1,0,0,0,233,234,5,32, - 0,0,234,235,5,1,0,0,235,236,3,0,0,0,236,237,5,2,0,0,237,304,1,0, - 0,0,238,239,5,33,0,0,239,240,5,1,0,0,240,241,3,0,0,0,241,242,5,2, - 0,0,242,304,1,0,0,0,243,244,5,35,0,0,244,245,5,1,0,0,245,246,3,0, - 0,0,246,247,5,2,0,0,247,304,1,0,0,0,248,249,5,37,0,0,249,250,5,1, - 0,0,250,251,3,0,0,0,251,252,5,2,0,0,252,304,1,0,0,0,253,254,5,38, - 0,0,254,255,5,1,0,0,255,256,3,0,0,0,256,257,5,2,0,0,257,304,1,0, - 0,0,258,259,5,39,0,0,259,260,5,1,0,0,260,261,3,0,0,0,261,262,5,2, - 0,0,262,304,1,0,0,0,263,264,5,40,0,0,264,265,5,1,0,0,265,266,3,0, - 0,0,266,267,5,2,0,0,267,304,1,0,0,0,268,269,5,46,0,0,269,270,5,1, - 0,0,270,271,3,0,0,0,271,272,5,2,0,0,272,304,1,0,0,0,273,274,5,47, - 0,0,274,275,5,1,0,0,275,276,3,0,0,0,276,277,5,2,0,0,277,304,1,0, - 0,0,278,279,5,48,0,0,279,280,5,1,0,0,280,281,3,0,0,0,281,282,5,2, - 0,0,282,304,1,0,0,0,283,284,5,49,0,0,284,285,5,1,0,0,285,286,3,0, - 0,0,286,287,5,2,0,0,287,304,1,0,0,0,288,289,5,50,0,0,289,290,5,1, - 0,0,290,291,3,0,0,0,291,292,5,2,0,0,292,304,1,0,0,0,293,294,5,41, - 0,0,294,295,5,1,0,0,295,296,3,0,0,0,296,297,5,2,0,0,297,304,1,0, - 0,0,298,299,5,42,0,0,299,300,5,1,0,0,300,301,3,0,0,0,301,302,5,2, - 0,0,302,304,1,0,0,0,303,128,1,0,0,0,303,133,1,0,0,0,303,138,1,0, - 0,0,303,143,1,0,0,0,303,148,1,0,0,0,303,153,1,0,0,0,303,158,1,0, - 0,0,303,163,1,0,0,0,303,168,1,0,0,0,303,173,1,0,0,0,303,178,1,0, - 0,0,303,183,1,0,0,0,303,188,1,0,0,0,303,193,1,0,0,0,303,198,1,0, - 0,0,303,203,1,0,0,0,303,208,1,0,0,0,303,213,1,0,0,0,303,218,1,0, - 0,0,303,223,1,0,0,0,303,228,1,0,0,0,303,233,1,0,0,0,303,238,1,0, - 0,0,303,243,1,0,0,0,303,248,1,0,0,0,303,253,1,0,0,0,303,258,1,0, - 0,0,303,263,1,0,0,0,303,268,1,0,0,0,303,273,1,0,0,0,303,278,1,0, - 0,0,303,283,1,0,0,0,303,288,1,0,0,0,303,293,1,0,0,0,303,298,1,0, - 0,0,304,15,1,0,0,0,305,306,5,34,0,0,306,307,5,1,0,0,307,308,3,0, - 0,0,308,309,5,4,0,0,309,310,3,0,0,0,310,311,5,2,0,0,311,341,1,0, - 0,0,312,313,5,12,0,0,313,314,5,1,0,0,314,315,3,0,0,0,315,316,5,4, - 0,0,316,317,3,0,0,0,317,318,5,2,0,0,318,341,1,0,0,0,319,320,5,26, - 0,0,320,321,5,1,0,0,321,322,3,0,0,0,322,323,5,4,0,0,323,324,3,0, - 0,0,324,325,5,2,0,0,325,341,1,0,0,0,326,327,5,27,0,0,327,328,5,1, - 0,0,328,329,3,0,0,0,329,330,5,4,0,0,330,331,3,0,0,0,331,332,5,2, - 0,0,332,341,1,0,0,0,333,334,5,44,0,0,334,335,5,1,0,0,335,336,3,0, - 0,0,336,337,5,4,0,0,337,338,3,0,0,0,338,339,5,2,0,0,339,341,1,0, - 0,0,340,305,1,0,0,0,340,312,1,0,0,0,340,319,1,0,0,0,340,326,1,0, - 0,0,340,333,1,0,0,0,341,17,1,0,0,0,342,343,5,36,0,0,343,344,5,1, - 0,0,344,345,3,0,0,0,345,346,5,4,0,0,346,347,3,0,0,0,347,348,5,4, - 0,0,348,349,3,0,0,0,349,350,5,2,0,0,350,379,1,0,0,0,351,352,5,43, - 0,0,352,353,5,1,0,0,353,354,3,0,0,0,354,355,5,4,0,0,355,356,3,0, - 0,0,356,357,5,4,0,0,357,358,3,0,0,0,358,359,5,2,0,0,359,379,1,0, - 0,0,360,361,5,45,0,0,361,362,5,1,0,0,362,363,3,0,0,0,363,364,5,4, - 0,0,364,365,3,0,0,0,365,366,5,4,0,0,366,367,3,0,0,0,367,368,5,2, - 0,0,368,379,1,0,0,0,369,370,5,56,0,0,370,371,5,1,0,0,371,372,3,0, - 0,0,372,373,5,4,0,0,373,374,3,0,0,0,374,375,5,4,0,0,375,376,3,0, - 0,0,376,377,5,2,0,0,377,379,1,0,0,0,378,342,1,0,0,0,378,351,1,0, - 0,0,378,360,1,0,0,0,378,369,1,0,0,0,379,19,1,0,0,0,380,381,5,53, - 0,0,381,382,5,1,0,0,382,383,3,0,0,0,383,384,5,4,0,0,384,385,3,0, - 0,0,385,386,5,4,0,0,386,387,3,0,0,0,387,388,5,4,0,0,388,389,3,0, - 0,0,389,390,5,2,0,0,390,21,1,0,0,0,391,392,5,24,0,0,392,393,5,1, - 0,0,393,398,3,0,0,0,394,395,5,4,0,0,395,397,3,0,0,0,396,394,1,0, - 0,0,397,400,1,0,0,0,398,396,1,0,0,0,398,399,1,0,0,0,399,401,1,0, - 0,0,400,398,1,0,0,0,401,402,5,2,0,0,402,452,1,0,0,0,403,404,5,25, - 0,0,404,405,5,1,0,0,405,410,3,0,0,0,406,407,5,4,0,0,407,409,3,0, - 0,0,408,406,1,0,0,0,409,412,1,0,0,0,410,408,1,0,0,0,410,411,1,0, - 0,0,411,413,1,0,0,0,412,410,1,0,0,0,413,414,5,2,0,0,414,452,1,0, - 0,0,415,416,5,51,0,0,416,417,5,1,0,0,417,420,3,0,0,0,418,419,5,4, - 0,0,419,421,3,0,0,0,420,418,1,0,0,0,421,422,1,0,0,0,422,420,1,0, - 0,0,422,423,1,0,0,0,423,424,1,0,0,0,424,425,5,2,0,0,425,452,1,0, - 0,0,426,427,5,52,0,0,427,428,5,1,0,0,428,431,3,0,0,0,429,430,5,4, - 0,0,430,432,3,0,0,0,431,429,1,0,0,0,432,433,1,0,0,0,433,431,1,0, - 0,0,433,434,1,0,0,0,434,435,1,0,0,0,435,436,5,2,0,0,436,452,1,0, - 0,0,437,438,5,54,0,0,438,439,5,1,0,0,439,440,3,0,0,0,440,441,5,4, - 0,0,441,442,3,0,0,0,442,443,5,2,0,0,443,452,1,0,0,0,444,445,5,55, - 0,0,445,446,5,1,0,0,446,447,3,0,0,0,447,448,5,4,0,0,448,449,3,0, - 0,0,449,450,5,2,0,0,450,452,1,0,0,0,451,391,1,0,0,0,451,403,1,0, - 0,0,451,415,1,0,0,0,451,426,1,0,0,0,451,437,1,0,0,0,451,444,1,0, - 0,0,452,23,1,0,0,0,19,26,49,51,63,65,80,82,90,97,121,126,303,340, - 378,398,410,422,433,451 + 4, + 1, + 73, + 454, + 2, + 0, + 7, + 0, + 2, + 1, + 7, + 1, + 2, + 2, + 7, + 2, + 2, + 3, + 7, + 3, + 2, + 4, + 7, + 4, + 2, + 5, + 7, + 5, + 2, + 6, + 7, + 6, + 2, + 7, + 7, + 7, + 2, + 8, + 7, + 8, + 2, + 9, + 7, + 9, + 2, + 10, + 7, + 10, + 2, + 11, + 7, + 11, + 1, + 0, + 1, + 0, + 3, + 0, + 27, + 8, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 5, + 1, + 50, + 8, + 1, + 10, + 1, + 12, + 1, + 53, + 9, + 1, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 1, + 2, + 5, + 2, + 64, + 8, + 2, + 10, + 2, + 12, + 2, + 67, + 9, + 2, + 1, + 3, + 1, + 3, + 1, + 3, + 1, + 3, + 1, + 3, + 1, + 3, + 1, + 3, + 1, + 3, + 1, + 3, + 1, + 3, + 1, + 3, + 1, + 3, + 5, + 3, + 81, + 8, + 3, + 10, + 3, + 12, + 3, + 84, + 9, + 3, + 1, + 4, + 1, + 4, + 1, + 4, + 1, + 4, + 1, + 4, + 3, + 4, + 91, + 8, + 4, + 1, + 5, + 1, + 5, + 1, + 5, + 1, + 5, + 1, + 5, + 3, + 5, + 98, + 8, + 5, + 1, + 6, + 1, + 6, + 1, + 6, + 1, + 6, + 1, + 6, + 1, + 6, + 1, + 6, + 1, + 6, + 1, + 6, + 1, + 6, + 1, + 6, + 1, + 6, + 1, + 6, + 1, + 6, + 1, + 6, + 1, + 6, + 1, + 6, + 1, + 6, + 1, + 6, + 1, + 6, + 5, + 6, + 120, + 8, + 6, + 10, + 6, + 12, + 6, + 123, + 9, + 6, + 1, + 6, + 1, + 6, + 3, + 6, + 127, + 8, + 6, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 1, + 7, + 3, + 7, + 304, + 8, + 7, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 1, + 8, + 3, + 8, + 341, + 8, + 8, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 1, + 9, + 3, + 9, + 379, + 8, + 9, + 1, + 10, + 1, + 10, + 1, + 10, + 1, + 10, + 1, + 10, + 1, + 10, + 1, + 10, + 1, + 10, + 1, + 10, + 1, + 10, + 1, + 10, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 5, + 11, + 397, + 8, + 11, + 10, + 11, + 12, + 11, + 400, + 9, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 5, + 11, + 409, + 8, + 11, + 10, + 11, + 12, + 11, + 412, + 9, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 4, + 11, + 421, + 8, + 11, + 11, + 11, + 12, + 11, + 422, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 4, + 11, + 432, + 8, + 11, + 11, + 11, + 12, + 11, + 433, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 1, + 11, + 3, + 11, + 452, + 8, + 11, + 1, + 11, + 0, + 3, + 2, + 4, + 6, + 12, + 0, + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 0, + 0, + 517, + 0, + 26, + 1, + 0, + 0, + 0, + 2, + 28, + 1, + 0, + 0, + 0, + 4, + 54, + 1, + 0, + 0, + 0, + 6, + 68, + 1, + 0, + 0, + 0, + 8, + 90, + 1, + 0, + 0, + 0, + 10, + 97, + 1, + 0, + 0, + 0, + 12, + 126, + 1, + 0, + 0, + 0, + 14, + 303, + 1, + 0, + 0, + 0, + 16, + 340, + 1, + 0, + 0, + 0, + 18, + 378, + 1, + 0, + 0, + 0, + 20, + 380, + 1, + 0, + 0, + 0, + 22, + 451, + 1, + 0, + 0, + 0, + 24, + 27, + 3, + 12, + 6, + 0, + 25, + 27, + 3, + 2, + 1, + 0, + 26, + 24, + 1, + 0, + 0, + 0, + 26, + 25, + 1, + 0, + 0, + 0, + 27, + 1, + 1, + 0, + 0, + 0, + 28, + 29, + 6, + 1, + -1, + 0, + 29, + 30, + 3, + 4, + 2, + 0, + 30, + 51, + 1, + 0, + 0, + 0, + 31, + 32, + 10, + 7, + 0, + 0, + 32, + 33, + 5, + 64, + 0, + 0, + 33, + 50, + 3, + 4, + 2, + 0, + 34, + 35, + 10, + 6, + 0, + 0, + 35, + 36, + 5, + 63, + 0, + 0, + 36, + 50, + 3, + 4, + 2, + 0, + 37, + 38, + 10, + 5, + 0, + 0, + 38, + 39, + 5, + 66, + 0, + 0, + 39, + 50, + 3, + 4, + 2, + 0, + 40, + 41, + 10, + 4, + 0, + 0, + 41, + 42, + 5, + 65, + 0, + 0, + 42, + 50, + 3, + 4, + 2, + 0, + 43, + 44, + 10, + 3, + 0, + 0, + 44, + 45, + 5, + 67, + 0, + 0, + 45, + 50, + 3, + 4, + 2, + 0, + 46, + 47, + 10, + 2, + 0, + 0, + 47, + 48, + 5, + 68, + 0, + 0, + 48, + 50, + 3, + 4, + 2, + 0, + 49, + 31, + 1, + 0, + 0, + 0, + 49, + 34, + 1, + 0, + 0, + 0, + 49, + 37, + 1, + 0, + 0, + 0, + 49, + 40, + 1, + 0, + 0, + 0, + 49, + 43, + 1, + 0, + 0, + 0, + 49, + 46, + 1, + 0, + 0, + 0, + 50, + 53, + 1, + 0, + 0, + 0, + 51, + 49, + 1, + 0, + 0, + 0, + 51, + 52, + 1, + 0, + 0, + 0, + 52, + 3, + 1, + 0, + 0, + 0, + 53, + 51, + 1, + 0, + 0, + 0, + 54, + 55, + 6, + 2, + -1, + 0, + 55, + 56, + 3, + 6, + 3, + 0, + 56, + 65, + 1, + 0, + 0, + 0, + 57, + 58, + 10, + 3, + 0, + 0, + 58, + 59, + 5, + 57, + 0, + 0, + 59, + 64, + 3, + 6, + 3, + 0, + 60, + 61, + 10, + 2, + 0, + 0, + 61, + 62, + 5, + 58, + 0, + 0, + 62, + 64, + 3, + 6, + 3, + 0, + 63, + 57, + 1, + 0, + 0, + 0, + 63, + 60, + 1, + 0, + 0, + 0, + 64, + 67, + 1, + 0, + 0, + 0, + 65, + 63, + 1, + 0, + 0, + 0, + 65, + 66, + 1, + 0, + 0, + 0, + 66, + 5, + 1, + 0, + 0, + 0, + 67, + 65, + 1, + 0, + 0, + 0, + 68, + 69, + 6, + 3, + -1, + 0, + 69, + 70, + 3, + 8, + 4, + 0, + 70, + 82, + 1, + 0, + 0, + 0, + 71, + 72, + 10, + 4, + 0, + 0, + 72, + 73, + 5, + 59, + 0, + 0, + 73, + 81, + 3, + 8, + 4, + 0, + 74, + 75, + 10, + 3, + 0, + 0, + 75, + 76, + 5, + 60, + 0, + 0, + 76, + 81, + 3, + 8, + 4, + 0, + 77, + 78, + 10, + 2, + 0, + 0, + 78, + 79, + 5, + 61, + 0, + 0, + 79, + 81, + 3, + 8, + 4, + 0, + 80, + 71, + 1, + 0, + 0, + 0, + 80, + 74, + 1, + 0, + 0, + 0, + 80, + 77, + 1, + 0, + 0, + 0, + 81, + 84, + 1, + 0, + 0, + 0, + 82, + 80, + 1, + 0, + 0, + 0, + 82, + 83, + 1, + 0, + 0, + 0, + 83, + 7, + 1, + 0, + 0, + 0, + 84, + 82, + 1, + 0, + 0, + 0, + 85, + 86, + 3, + 10, + 5, + 0, + 86, + 87, + 5, + 62, + 0, + 0, + 87, + 88, + 3, + 8, + 4, + 0, + 88, + 91, + 1, + 0, + 0, + 0, + 89, + 91, + 3, + 10, + 5, + 0, + 90, + 85, + 1, + 0, + 0, + 0, + 90, + 89, + 1, + 0, + 0, + 0, + 91, + 9, + 1, + 0, + 0, + 0, + 92, + 93, + 5, + 57, + 0, + 0, + 93, + 98, + 3, + 10, + 5, + 0, + 94, + 95, + 5, + 58, + 0, + 0, + 95, + 98, + 3, + 10, + 5, + 0, + 96, + 98, + 3, + 12, + 6, + 0, + 97, + 92, + 1, + 0, + 0, + 0, + 97, + 94, + 1, + 0, + 0, + 0, + 97, + 96, + 1, + 0, + 0, + 0, + 98, + 11, + 1, + 0, + 0, + 0, + 99, + 127, + 3, + 14, + 7, + 0, + 100, + 127, + 3, + 16, + 8, + 0, + 101, + 127, + 3, + 18, + 9, + 0, + 102, + 127, + 3, + 20, + 10, + 0, + 103, + 127, + 3, + 22, + 11, + 0, + 104, + 127, + 5, + 72, + 0, + 0, + 105, + 127, + 5, + 71, + 0, + 0, + 106, + 127, + 5, + 70, + 0, + 0, + 107, + 108, + 5, + 1, + 0, + 0, + 108, + 109, + 3, + 0, + 0, + 0, + 109, + 110, + 5, + 2, + 0, + 0, + 110, + 127, + 1, + 0, + 0, + 0, + 111, + 112, + 5, + 69, + 0, + 0, + 112, + 113, + 3, + 0, + 0, + 0, + 113, + 114, + 5, + 69, + 0, + 0, + 114, + 127, + 1, + 0, + 0, + 0, + 115, + 116, + 5, + 3, + 0, + 0, + 116, + 121, + 3, + 0, + 0, + 0, + 117, + 118, + 5, + 4, + 0, + 0, + 118, + 120, + 3, + 0, + 0, + 0, + 119, + 117, + 1, + 0, + 0, + 0, + 120, + 123, + 1, + 0, + 0, + 0, + 121, + 119, + 1, + 0, + 0, + 0, + 121, + 122, + 1, + 0, + 0, + 0, + 122, + 124, + 1, + 0, + 0, + 0, + 123, + 121, + 1, + 0, + 0, + 0, + 124, + 125, + 5, + 5, + 0, + 0, + 125, + 127, + 1, + 0, + 0, + 0, + 126, + 99, + 1, + 0, + 0, + 0, + 126, + 100, + 1, + 0, + 0, + 0, + 126, + 101, + 1, + 0, + 0, + 0, + 126, + 102, + 1, + 0, + 0, + 0, + 126, + 103, + 1, + 0, + 0, + 0, + 126, + 104, + 1, + 0, + 0, + 0, + 126, + 105, + 1, + 0, + 0, + 0, + 126, + 106, + 1, + 0, + 0, + 0, + 126, + 107, + 1, + 0, + 0, + 0, + 126, + 111, + 1, + 0, + 0, + 0, + 126, + 115, + 1, + 0, + 0, + 0, + 127, + 13, + 1, + 0, + 0, + 0, + 128, + 129, + 5, + 6, + 0, + 0, + 129, + 130, + 5, + 1, + 0, + 0, + 130, + 131, + 3, + 0, + 0, + 0, + 131, + 132, + 5, + 2, + 0, + 0, + 132, + 304, + 1, + 0, + 0, + 0, + 133, + 134, + 5, + 7, + 0, + 0, + 134, + 135, + 5, + 1, + 0, + 0, + 135, + 136, + 3, + 0, + 0, + 0, + 136, + 137, + 5, + 2, + 0, + 0, + 137, + 304, + 1, + 0, + 0, + 0, + 138, + 139, + 5, + 8, + 0, + 0, + 139, + 140, + 5, + 1, + 0, + 0, + 140, + 141, + 3, + 0, + 0, + 0, + 141, + 142, + 5, + 2, + 0, + 0, + 142, + 304, + 1, + 0, + 0, + 0, + 143, + 144, + 5, + 9, + 0, + 0, + 144, + 145, + 5, + 1, + 0, + 0, + 145, + 146, + 3, + 0, + 0, + 0, + 146, + 147, + 5, + 2, + 0, + 0, + 147, + 304, + 1, + 0, + 0, + 0, + 148, + 149, + 5, + 10, + 0, + 0, + 149, + 150, + 5, + 1, + 0, + 0, + 150, + 151, + 3, + 0, + 0, + 0, + 151, + 152, + 5, + 2, + 0, + 0, + 152, + 304, + 1, + 0, + 0, + 0, + 153, + 154, + 5, + 11, + 0, + 0, + 154, + 155, + 5, + 1, + 0, + 0, + 155, + 156, + 3, + 0, + 0, + 0, + 156, + 157, + 5, + 2, + 0, + 0, + 157, + 304, + 1, + 0, + 0, + 0, + 158, + 159, + 5, + 13, + 0, + 0, + 159, + 160, + 5, + 1, + 0, + 0, + 160, + 161, + 3, + 0, + 0, + 0, + 161, + 162, + 5, + 2, + 0, + 0, + 162, + 304, + 1, + 0, + 0, + 0, + 163, + 164, + 5, + 14, + 0, + 0, + 164, + 165, + 5, + 1, + 0, + 0, + 165, + 166, + 3, + 0, + 0, + 0, + 166, + 167, + 5, + 2, + 0, + 0, + 167, + 304, + 1, + 0, + 0, + 0, + 168, + 169, + 5, + 15, + 0, + 0, + 169, + 170, + 5, + 1, + 0, + 0, + 170, + 171, + 3, + 0, + 0, + 0, + 171, + 172, + 5, + 2, + 0, + 0, + 172, + 304, + 1, + 0, + 0, + 0, + 173, + 174, + 5, + 16, + 0, + 0, + 174, + 175, + 5, + 1, + 0, + 0, + 175, + 176, + 3, + 0, + 0, + 0, + 176, + 177, + 5, + 2, + 0, + 0, + 177, + 304, + 1, + 0, + 0, + 0, + 178, + 179, + 5, + 17, + 0, + 0, + 179, + 180, + 5, + 1, + 0, + 0, + 180, + 181, + 3, + 0, + 0, + 0, + 181, + 182, + 5, + 2, + 0, + 0, + 182, + 304, + 1, + 0, + 0, + 0, + 183, + 184, + 5, + 18, + 0, + 0, + 184, + 185, + 5, + 1, + 0, + 0, + 185, + 186, + 3, + 0, + 0, + 0, + 186, + 187, + 5, + 2, + 0, + 0, + 187, + 304, + 1, + 0, + 0, + 0, + 188, + 189, + 5, + 19, + 0, + 0, + 189, + 190, + 5, + 1, + 0, + 0, + 190, + 191, + 3, + 0, + 0, + 0, + 191, + 192, + 5, + 2, + 0, + 0, + 192, + 304, + 1, + 0, + 0, + 0, + 193, + 194, + 5, + 20, + 0, + 0, + 194, + 195, + 5, + 1, + 0, + 0, + 195, + 196, + 3, + 0, + 0, + 0, + 196, + 197, + 5, + 2, + 0, + 0, + 197, + 304, + 1, + 0, + 0, + 0, + 198, + 199, + 5, + 21, + 0, + 0, + 199, + 200, + 5, + 1, + 0, + 0, + 200, + 201, + 3, + 0, + 0, + 0, + 201, + 202, + 5, + 2, + 0, + 0, + 202, + 304, + 1, + 0, + 0, + 0, + 203, + 204, + 5, + 22, + 0, + 0, + 204, + 205, + 5, + 1, + 0, + 0, + 205, + 206, + 3, + 0, + 0, + 0, + 206, + 207, + 5, + 2, + 0, + 0, + 207, + 304, + 1, + 0, + 0, + 0, + 208, + 209, + 5, + 23, + 0, + 0, + 209, + 210, + 5, + 1, + 0, + 0, + 210, + 211, + 3, + 0, + 0, + 0, + 211, + 212, + 5, + 2, + 0, + 0, + 212, + 304, + 1, + 0, + 0, + 0, + 213, + 214, + 5, + 28, + 0, + 0, + 214, + 215, + 5, + 1, + 0, + 0, + 215, + 216, + 3, + 0, + 0, + 0, + 216, + 217, + 5, + 2, + 0, + 0, + 217, + 304, + 1, + 0, + 0, + 0, + 218, + 219, + 5, + 29, + 0, + 0, + 219, + 220, + 5, + 1, + 0, + 0, + 220, + 221, + 3, + 0, + 0, + 0, + 221, + 222, + 5, + 2, + 0, + 0, + 222, + 304, + 1, + 0, + 0, + 0, + 223, + 224, + 5, + 30, + 0, + 0, + 224, + 225, + 5, + 1, + 0, + 0, + 225, + 226, + 3, + 0, + 0, + 0, + 226, + 227, + 5, + 2, + 0, + 0, + 227, + 304, + 1, + 0, + 0, + 0, + 228, + 229, + 5, + 31, + 0, + 0, + 229, + 230, + 5, + 1, + 0, + 0, + 230, + 231, + 3, + 0, + 0, + 0, + 231, + 232, + 5, + 2, + 0, + 0, + 232, + 304, + 1, + 0, + 0, + 0, + 233, + 234, + 5, + 32, + 0, + 0, + 234, + 235, + 5, + 1, + 0, + 0, + 235, + 236, + 3, + 0, + 0, + 0, + 236, + 237, + 5, + 2, + 0, + 0, + 237, + 304, + 1, + 0, + 0, + 0, + 238, + 239, + 5, + 33, + 0, + 0, + 239, + 240, + 5, + 1, + 0, + 0, + 240, + 241, + 3, + 0, + 0, + 0, + 241, + 242, + 5, + 2, + 0, + 0, + 242, + 304, + 1, + 0, + 0, + 0, + 243, + 244, + 5, + 35, + 0, + 0, + 244, + 245, + 5, + 1, + 0, + 0, + 245, + 246, + 3, + 0, + 0, + 0, + 246, + 247, + 5, + 2, + 0, + 0, + 247, + 304, + 1, + 0, + 0, + 0, + 248, + 249, + 5, + 37, + 0, + 0, + 249, + 250, + 5, + 1, + 0, + 0, + 250, + 251, + 3, + 0, + 0, + 0, + 251, + 252, + 5, + 2, + 0, + 0, + 252, + 304, + 1, + 0, + 0, + 0, + 253, + 254, + 5, + 38, + 0, + 0, + 254, + 255, + 5, + 1, + 0, + 0, + 255, + 256, + 3, + 0, + 0, + 0, + 256, + 257, + 5, + 2, + 0, + 0, + 257, + 304, + 1, + 0, + 0, + 0, + 258, + 259, + 5, + 39, + 0, + 0, + 259, + 260, + 5, + 1, + 0, + 0, + 260, + 261, + 3, + 0, + 0, + 0, + 261, + 262, + 5, + 2, + 0, + 0, + 262, + 304, + 1, + 0, + 0, + 0, + 263, + 264, + 5, + 40, + 0, + 0, + 264, + 265, + 5, + 1, + 0, + 0, + 265, + 266, + 3, + 0, + 0, + 0, + 266, + 267, + 5, + 2, + 0, + 0, + 267, + 304, + 1, + 0, + 0, + 0, + 268, + 269, + 5, + 46, + 0, + 0, + 269, + 270, + 5, + 1, + 0, + 0, + 270, + 271, + 3, + 0, + 0, + 0, + 271, + 272, + 5, + 2, + 0, + 0, + 272, + 304, + 1, + 0, + 0, + 0, + 273, + 274, + 5, + 47, + 0, + 0, + 274, + 275, + 5, + 1, + 0, + 0, + 275, + 276, + 3, + 0, + 0, + 0, + 276, + 277, + 5, + 2, + 0, + 0, + 277, + 304, + 1, + 0, + 0, + 0, + 278, + 279, + 5, + 48, + 0, + 0, + 279, + 280, + 5, + 1, + 0, + 0, + 280, + 281, + 3, + 0, + 0, + 0, + 281, + 282, + 5, + 2, + 0, + 0, + 282, + 304, + 1, + 0, + 0, + 0, + 283, + 284, + 5, + 49, + 0, + 0, + 284, + 285, + 5, + 1, + 0, + 0, + 285, + 286, + 3, + 0, + 0, + 0, + 286, + 287, + 5, + 2, + 0, + 0, + 287, + 304, + 1, + 0, + 0, + 0, + 288, + 289, + 5, + 50, + 0, + 0, + 289, + 290, + 5, + 1, + 0, + 0, + 290, + 291, + 3, + 0, + 0, + 0, + 291, + 292, + 5, + 2, + 0, + 0, + 292, + 304, + 1, + 0, + 0, + 0, + 293, + 294, + 5, + 41, + 0, + 0, + 294, + 295, + 5, + 1, + 0, + 0, + 295, + 296, + 3, + 0, + 0, + 0, + 296, + 297, + 5, + 2, + 0, + 0, + 297, + 304, + 1, + 0, + 0, + 0, + 298, + 299, + 5, + 42, + 0, + 0, + 299, + 300, + 5, + 1, + 0, + 0, + 300, + 301, + 3, + 0, + 0, + 0, + 301, + 302, + 5, + 2, + 0, + 0, + 302, + 304, + 1, + 0, + 0, + 0, + 303, + 128, + 1, + 0, + 0, + 0, + 303, + 133, + 1, + 0, + 0, + 0, + 303, + 138, + 1, + 0, + 0, + 0, + 303, + 143, + 1, + 0, + 0, + 0, + 303, + 148, + 1, + 0, + 0, + 0, + 303, + 153, + 1, + 0, + 0, + 0, + 303, + 158, + 1, + 0, + 0, + 0, + 303, + 163, + 1, + 0, + 0, + 0, + 303, + 168, + 1, + 0, + 0, + 0, + 303, + 173, + 1, + 0, + 0, + 0, + 303, + 178, + 1, + 0, + 0, + 0, + 303, + 183, + 1, + 0, + 0, + 0, + 303, + 188, + 1, + 0, + 0, + 0, + 303, + 193, + 1, + 0, + 0, + 0, + 303, + 198, + 1, + 0, + 0, + 0, + 303, + 203, + 1, + 0, + 0, + 0, + 303, + 208, + 1, + 0, + 0, + 0, + 303, + 213, + 1, + 0, + 0, + 0, + 303, + 218, + 1, + 0, + 0, + 0, + 303, + 223, + 1, + 0, + 0, + 0, + 303, + 228, + 1, + 0, + 0, + 0, + 303, + 233, + 1, + 0, + 0, + 0, + 303, + 238, + 1, + 0, + 0, + 0, + 303, + 243, + 1, + 0, + 0, + 0, + 303, + 248, + 1, + 0, + 0, + 0, + 303, + 253, + 1, + 0, + 0, + 0, + 303, + 258, + 1, + 0, + 0, + 0, + 303, + 263, + 1, + 0, + 0, + 0, + 303, + 268, + 1, + 0, + 0, + 0, + 303, + 273, + 1, + 0, + 0, + 0, + 303, + 278, + 1, + 0, + 0, + 0, + 303, + 283, + 1, + 0, + 0, + 0, + 303, + 288, + 1, + 0, + 0, + 0, + 303, + 293, + 1, + 0, + 0, + 0, + 303, + 298, + 1, + 0, + 0, + 0, + 304, + 15, + 1, + 0, + 0, + 0, + 305, + 306, + 5, + 34, + 0, + 0, + 306, + 307, + 5, + 1, + 0, + 0, + 307, + 308, + 3, + 0, + 0, + 0, + 308, + 309, + 5, + 4, + 0, + 0, + 309, + 310, + 3, + 0, + 0, + 0, + 310, + 311, + 5, + 2, + 0, + 0, + 311, + 341, + 1, + 0, + 0, + 0, + 312, + 313, + 5, + 12, + 0, + 0, + 313, + 314, + 5, + 1, + 0, + 0, + 314, + 315, + 3, + 0, + 0, + 0, + 315, + 316, + 5, + 4, + 0, + 0, + 316, + 317, + 3, + 0, + 0, + 0, + 317, + 318, + 5, + 2, + 0, + 0, + 318, + 341, + 1, + 0, + 0, + 0, + 319, + 320, + 5, + 26, + 0, + 0, + 320, + 321, + 5, + 1, + 0, + 0, + 321, + 322, + 3, + 0, + 0, + 0, + 322, + 323, + 5, + 4, + 0, + 0, + 323, + 324, + 3, + 0, + 0, + 0, + 324, + 325, + 5, + 2, + 0, + 0, + 325, + 341, + 1, + 0, + 0, + 0, + 326, + 327, + 5, + 27, + 0, + 0, + 327, + 328, + 5, + 1, + 0, + 0, + 328, + 329, + 3, + 0, + 0, + 0, + 329, + 330, + 5, + 4, + 0, + 0, + 330, + 331, + 3, + 0, + 0, + 0, + 331, + 332, + 5, + 2, + 0, + 0, + 332, + 341, + 1, + 0, + 0, + 0, + 333, + 334, + 5, + 44, + 0, + 0, + 334, + 335, + 5, + 1, + 0, + 0, + 335, + 336, + 3, + 0, + 0, + 0, + 336, + 337, + 5, + 4, + 0, + 0, + 337, + 338, + 3, + 0, + 0, + 0, + 338, + 339, + 5, + 2, + 0, + 0, + 339, + 341, + 1, + 0, + 0, + 0, + 340, + 305, + 1, + 0, + 0, + 0, + 340, + 312, + 1, + 0, + 0, + 0, + 340, + 319, + 1, + 0, + 0, + 0, + 340, + 326, + 1, + 0, + 0, + 0, + 340, + 333, + 1, + 0, + 0, + 0, + 341, + 17, + 1, + 0, + 0, + 0, + 342, + 343, + 5, + 36, + 0, + 0, + 343, + 344, + 5, + 1, + 0, + 0, + 344, + 345, + 3, + 0, + 0, + 0, + 345, + 346, + 5, + 4, + 0, + 0, + 346, + 347, + 3, + 0, + 0, + 0, + 347, + 348, + 5, + 4, + 0, + 0, + 348, + 349, + 3, + 0, + 0, + 0, + 349, + 350, + 5, + 2, + 0, + 0, + 350, + 379, + 1, + 0, + 0, + 0, + 351, + 352, + 5, + 43, + 0, + 0, + 352, + 353, + 5, + 1, + 0, + 0, + 353, + 354, + 3, + 0, + 0, + 0, + 354, + 355, + 5, + 4, + 0, + 0, + 355, + 356, + 3, + 0, + 0, + 0, + 356, + 357, + 5, + 4, + 0, + 0, + 357, + 358, + 3, + 0, + 0, + 0, + 358, + 359, + 5, + 2, + 0, + 0, + 359, + 379, + 1, + 0, + 0, + 0, + 360, + 361, + 5, + 45, + 0, + 0, + 361, + 362, + 5, + 1, + 0, + 0, + 362, + 363, + 3, + 0, + 0, + 0, + 363, + 364, + 5, + 4, + 0, + 0, + 364, + 365, + 3, + 0, + 0, + 0, + 365, + 366, + 5, + 4, + 0, + 0, + 366, + 367, + 3, + 0, + 0, + 0, + 367, + 368, + 5, + 2, + 0, + 0, + 368, + 379, + 1, + 0, + 0, + 0, + 369, + 370, + 5, + 56, + 0, + 0, + 370, + 371, + 5, + 1, + 0, + 0, + 371, + 372, + 3, + 0, + 0, + 0, + 372, + 373, + 5, + 4, + 0, + 0, + 373, + 374, + 3, + 0, + 0, + 0, + 374, + 375, + 5, + 4, + 0, + 0, + 375, + 376, + 3, + 0, + 0, + 0, + 376, + 377, + 5, + 2, + 0, + 0, + 377, + 379, + 1, + 0, + 0, + 0, + 378, + 342, + 1, + 0, + 0, + 0, + 378, + 351, + 1, + 0, + 0, + 0, + 378, + 360, + 1, + 0, + 0, + 0, + 378, + 369, + 1, + 0, + 0, + 0, + 379, + 19, + 1, + 0, + 0, + 0, + 380, + 381, + 5, + 53, + 0, + 0, + 381, + 382, + 5, + 1, + 0, + 0, + 382, + 383, + 3, + 0, + 0, + 0, + 383, + 384, + 5, + 4, + 0, + 0, + 384, + 385, + 3, + 0, + 0, + 0, + 385, + 386, + 5, + 4, + 0, + 0, + 386, + 387, + 3, + 0, + 0, + 0, + 387, + 388, + 5, + 4, + 0, + 0, + 388, + 389, + 3, + 0, + 0, + 0, + 389, + 390, + 5, + 2, + 0, + 0, + 390, + 21, + 1, + 0, + 0, + 0, + 391, + 392, + 5, + 24, + 0, + 0, + 392, + 393, + 5, + 1, + 0, + 0, + 393, + 398, + 3, + 0, + 0, + 0, + 394, + 395, + 5, + 4, + 0, + 0, + 395, + 397, + 3, + 0, + 0, + 0, + 396, + 394, + 1, + 0, + 0, + 0, + 397, + 400, + 1, + 0, + 0, + 0, + 398, + 396, + 1, + 0, + 0, + 0, + 398, + 399, + 1, + 0, + 0, + 0, + 399, + 401, + 1, + 0, + 0, + 0, + 400, + 398, + 1, + 0, + 0, + 0, + 401, + 402, + 5, + 2, + 0, + 0, + 402, + 452, + 1, + 0, + 0, + 0, + 403, + 404, + 5, + 25, + 0, + 0, + 404, + 405, + 5, + 1, + 0, + 0, + 405, + 410, + 3, + 0, + 0, + 0, + 406, + 407, + 5, + 4, + 0, + 0, + 407, + 409, + 3, + 0, + 0, + 0, + 408, + 406, + 1, + 0, + 0, + 0, + 409, + 412, + 1, + 0, + 0, + 0, + 410, + 408, + 1, + 0, + 0, + 0, + 410, + 411, + 1, + 0, + 0, + 0, + 411, + 413, + 1, + 0, + 0, + 0, + 412, + 410, + 1, + 0, + 0, + 0, + 413, + 414, + 5, + 2, + 0, + 0, + 414, + 452, + 1, + 0, + 0, + 0, + 415, + 416, + 5, + 51, + 0, + 0, + 416, + 417, + 5, + 1, + 0, + 0, + 417, + 420, + 3, + 0, + 0, + 0, + 418, + 419, + 5, + 4, + 0, + 0, + 419, + 421, + 3, + 0, + 0, + 0, + 420, + 418, + 1, + 0, + 0, + 0, + 421, + 422, + 1, + 0, + 0, + 0, + 422, + 420, + 1, + 0, + 0, + 0, + 422, + 423, + 1, + 0, + 0, + 0, + 423, + 424, + 1, + 0, + 0, + 0, + 424, + 425, + 5, + 2, + 0, + 0, + 425, + 452, + 1, + 0, + 0, + 0, + 426, + 427, + 5, + 52, + 0, + 0, + 427, + 428, + 5, + 1, + 0, + 0, + 428, + 431, + 3, + 0, + 0, + 0, + 429, + 430, + 5, + 4, + 0, + 0, + 430, + 432, + 3, + 0, + 0, + 0, + 431, + 429, + 1, + 0, + 0, + 0, + 432, + 433, + 1, + 0, + 0, + 0, + 433, + 431, + 1, + 0, + 0, + 0, + 433, + 434, + 1, + 0, + 0, + 0, + 434, + 435, + 1, + 0, + 0, + 0, + 435, + 436, + 5, + 2, + 0, + 0, + 436, + 452, + 1, + 0, + 0, + 0, + 437, + 438, + 5, + 54, + 0, + 0, + 438, + 439, + 5, + 1, + 0, + 0, + 439, + 440, + 3, + 0, + 0, + 0, + 440, + 441, + 5, + 4, + 0, + 0, + 441, + 442, + 3, + 0, + 0, + 0, + 442, + 443, + 5, + 2, + 0, + 0, + 443, + 452, + 1, + 0, + 0, + 0, + 444, + 445, + 5, + 55, + 0, + 0, + 445, + 446, + 5, + 1, + 0, + 0, + 446, + 447, + 3, + 0, + 0, + 0, + 447, + 448, + 5, + 4, + 0, + 0, + 448, + 449, + 3, + 0, + 0, + 0, + 449, + 450, + 5, + 2, + 0, + 0, + 450, + 452, + 1, + 0, + 0, + 0, + 451, + 391, + 1, + 0, + 0, + 0, + 451, + 403, + 1, + 0, + 0, + 0, + 451, + 415, + 1, + 0, + 0, + 0, + 451, + 426, + 1, + 0, + 0, + 0, + 451, + 437, + 1, + 0, + 0, + 0, + 451, + 444, + 1, + 0, + 0, + 0, + 452, + 23, + 1, + 0, + 0, + 0, + 19, + 26, + 49, + 51, + 63, + 65, + 80, + 82, + 90, + 97, + 121, + 126, + 303, + 340, + 378, + 398, + 410, + 422, + 433, + 451, ] -class MathExprParser ( Parser ): +class MathExprParser(Parser): grammarFileName = "MathExpr.g4" atn = ATNDeserializer().deserialize(serializedATN()) - decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ] + decisionsToDFA = [DFA(ds, i) for i, ds in enumerate(atn.decisionToState)] sharedContextCache = PredictionContextCache() - literalNames = [ "", "'('", "')'", "'['", "','", "']'", "'sin'", - "'cos'", "'tan'", "'asin'", "'acos'", "'atan'", "'atan2'", - "'sinh'", "'cosh'", "'tanh'", "'asinh'", "'acosh'", - "'atanh'", "'abs'", "'sqrt'", "'ln'", "'log'", "'exp'", - "'smin'", "'smax'", "'tmin'", "'tmax'", "'tnorm'", - "'snorm'", "'floor'", "'ceil'", "'round'", "'gamma'", - "'pow'", "'sigm'", "'clamp'", "'fft'", "'ifft'", "'angle'", - "'print'", "'print_shape'", "'pshp'", "'lerp'", "'step'", - "'smoothstep'", "'fract'", "'relu'", "'softplus'", - "'gelu'", "'sign'", "'map'", "'conv'", "'swap'", "'permute'", - "'reshape'", "'range'", "'+'", "'-'", "'*'", "'/'", - "'%'", "'^'", "'>='", "'>'", "'<='", "'<'", "'=='", - "'!='", "'|'" ] + literalNames = [ + "", + "'('", + "')'", + "'['", + "','", + "']'", + "'sin'", + "'cos'", + "'tan'", + "'asin'", + "'acos'", + "'atan'", + "'atan2'", + "'sinh'", + "'cosh'", + "'tanh'", + "'asinh'", + "'acosh'", + "'atanh'", + "'abs'", + "'sqrt'", + "'ln'", + "'log'", + "'exp'", + "'smin'", + "'smax'", + "'tmin'", + "'tmax'", + "'tnorm'", + "'snorm'", + "'floor'", + "'ceil'", + "'round'", + "'gamma'", + "'pow'", + "'sigm'", + "'clamp'", + "'fft'", + "'ifft'", + "'angle'", + "'print'", + "'print_shape'", + "'pshp'", + "'lerp'", + "'step'", + "'smoothstep'", + "'fract'", + "'relu'", + "'softplus'", + "'gelu'", + "'sign'", + "'map'", + "'conv'", + "'swap'", + "'permute'", + "'reshape'", + "'range'", + "'+'", + "'-'", + "'*'", + "'/'", + "'%'", + "'^'", + "'>='", + "'>'", + "'<='", + "'<'", + "'=='", + "'!='", + "'|'", + ] - symbolicNames = [ "", "", "", "", - "", "", "SIN", "COS", "TAN", "ASIN", - "ACOS", "ATAN", "ATAN2", "SINH", "COSH", "TANH", "ASINH", - "ACOSH", "ATANH", "ABS", "SQRT", "LN", "LOG", "EXP", - "SMIN", "SMAX", "TMIN", "TMAX", "TNORM", "SNORM", - "FLOOR", "CEIL", "ROUND", "GAMMA", "POWE", "SIGM", - "CLAMP", "SFFT", "SIFFT", "ANGL", "PRNT", "PRINT_SHAPE_L", - "PRINT_SHAPE", "LERP", "STEP", "SMOOTHSTEP", "FRACT", - "RELU", "SOFTPLUS", "GELU", "SIGN", "MAP", "CONV", - "SWAP", "PERM", "RESHAPE", "RANGE", "PLUS", "MINUS", - "MULT", "DIV", "MOD", "POW", "GE", "GT", "LE", "LT", - "EQ", "NE", "PIPE", "CONSTANT", "NUMBER", "VARIABLE", - "WS" ] + symbolicNames = [ + "", + "", + "", + "", + "", + "", + "SIN", + "COS", + "TAN", + "ASIN", + "ACOS", + "ATAN", + "ATAN2", + "SINH", + "COSH", + "TANH", + "ASINH", + "ACOSH", + "ATANH", + "ABS", + "SQRT", + "LN", + "LOG", + "EXP", + "SMIN", + "SMAX", + "TMIN", + "TMAX", + "TNORM", + "SNORM", + "FLOOR", + "CEIL", + "ROUND", + "GAMMA", + "POWE", + "SIGM", + "CLAMP", + "SFFT", + "SIFFT", + "ANGL", + "PRNT", + "PRINT_SHAPE_L", + "PRINT_SHAPE", + "LERP", + "STEP", + "SMOOTHSTEP", + "FRACT", + "RELU", + "SOFTPLUS", + "GELU", + "SIGN", + "MAP", + "CONV", + "SWAP", + "PERM", + "RESHAPE", + "RANGE", + "PLUS", + "MINUS", + "MULT", + "DIV", + "MOD", + "POW", + "GE", + "GT", + "LE", + "LT", + "EQ", + "NE", + "PIPE", + "CONSTANT", + "NUMBER", + "VARIABLE", + "WS", + ] RULE_expr = 0 RULE_compExpr = 1 @@ -223,137 +4266,126 @@ class MathExprParser ( Parser ): RULE_func4 = 10 RULE_funcN = 11 - ruleNames = [ "expr", "compExpr", "addExpr", "mulExpr", "powExpr", - "unaryExpr", "atom", "func1", "func2", "func3", "func4", - "funcN" ] + ruleNames = ["expr", "compExpr", "addExpr", "mulExpr", "powExpr", "unaryExpr", "atom", "func1", "func2", "func3", "func4", "funcN"] EOF = Token.EOF - T__0=1 - T__1=2 - T__2=3 - T__3=4 - T__4=5 - SIN=6 - COS=7 - TAN=8 - ASIN=9 - ACOS=10 - ATAN=11 - ATAN2=12 - SINH=13 - COSH=14 - TANH=15 - ASINH=16 - ACOSH=17 - ATANH=18 - ABS=19 - SQRT=20 - LN=21 - LOG=22 - EXP=23 - SMIN=24 - SMAX=25 - TMIN=26 - TMAX=27 - TNORM=28 - SNORM=29 - FLOOR=30 - CEIL=31 - ROUND=32 - GAMMA=33 - POWE=34 - SIGM=35 - CLAMP=36 - SFFT=37 - SIFFT=38 - ANGL=39 - PRNT=40 - PRINT_SHAPE_L=41 - PRINT_SHAPE=42 - LERP=43 - STEP=44 - SMOOTHSTEP=45 - FRACT=46 - RELU=47 - SOFTPLUS=48 - GELU=49 - SIGN=50 - MAP=51 - CONV=52 - SWAP=53 - PERM=54 - RESHAPE=55 - RANGE=56 - PLUS=57 - MINUS=58 - MULT=59 - DIV=60 - MOD=61 - POW=62 - GE=63 - GT=64 - LE=65 - LT=66 - EQ=67 - NE=68 - PIPE=69 - CONSTANT=70 - NUMBER=71 - VARIABLE=72 - WS=73 + T__0 = 1 + T__1 = 2 + T__2 = 3 + T__3 = 4 + T__4 = 5 + SIN = 6 + COS = 7 + TAN = 8 + ASIN = 9 + ACOS = 10 + ATAN = 11 + ATAN2 = 12 + SINH = 13 + COSH = 14 + TANH = 15 + ASINH = 16 + ACOSH = 17 + ATANH = 18 + ABS = 19 + SQRT = 20 + LN = 21 + LOG = 22 + EXP = 23 + SMIN = 24 + SMAX = 25 + TMIN = 26 + TMAX = 27 + TNORM = 28 + SNORM = 29 + FLOOR = 30 + CEIL = 31 + ROUND = 32 + GAMMA = 33 + POWE = 34 + SIGM = 35 + CLAMP = 36 + SFFT = 37 + SIFFT = 38 + ANGL = 39 + PRNT = 40 + PRINT_SHAPE_L = 41 + PRINT_SHAPE = 42 + LERP = 43 + STEP = 44 + SMOOTHSTEP = 45 + FRACT = 46 + RELU = 47 + SOFTPLUS = 48 + GELU = 49 + SIGN = 50 + MAP = 51 + CONV = 52 + SWAP = 53 + PERM = 54 + RESHAPE = 55 + RANGE = 56 + PLUS = 57 + MINUS = 58 + MULT = 59 + DIV = 60 + MOD = 61 + POW = 62 + GE = 63 + GT = 64 + LE = 65 + LT = 66 + EQ = 67 + NE = 68 + PIPE = 69 + CONSTANT = 70 + NUMBER = 71 + VARIABLE = 72 + WS = 73 - def __init__(self, input:TokenStream, output:TextIO = sys.stdout): + def __init__(self, input: TokenStream, output: TextIO = sys.stdout): super().__init__(input, output) self.checkVersion("4.13.2") self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache) self._predicates = None - - - class ExprContext(ParserRuleContext): - __slots__ = 'parser' + __slots__ = "parser" - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + def __init__(self, parser, parent: ParserRuleContext = None, invokingState: int = -1): super().__init__(parent, invokingState) self.parser = parser def atom(self): - return self.getTypedRuleContext(MathExprParser.AtomContext,0) - + return self.getTypedRuleContext(MathExprParser.AtomContext, 0) def compExpr(self): - return self.getTypedRuleContext(MathExprParser.CompExprContext,0) - + return self.getTypedRuleContext(MathExprParser.CompExprContext, 0) def getRuleIndex(self): return MathExprParser.RULE_expr - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterExpr" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterExpr"): listener.enterExpr(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitExpr" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitExpr"): listener.exitExpr(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitExpr" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitExpr"): return visitor.visitExpr(self) else: return visitor.visitChildren(self) - - - def expr(self): - localctx = MathExprParser.ExprContext(self, self._ctx, self.state) self.enterRule(localctx, 0, self.RULE_expr) try: self.state = 26 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,0,self._ctx) + la_ = self._interp.adaptivePredict(self._input, 0, self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) self.state = 24 @@ -366,7 +4398,6 @@ class MathExprParser ( Parser ): self.compExpr(0) pass - except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -375,230 +4406,210 @@ class MathExprParser ( Parser ): self.exitRule() return localctx - class CompExprContext(ParserRuleContext): - __slots__ = 'parser' + __slots__ = "parser" - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + def __init__(self, parser, parent: ParserRuleContext = None, invokingState: int = -1): super().__init__(parent, invokingState) self.parser = parser - def getRuleIndex(self): return MathExprParser.RULE_compExpr - - def copyFrom(self, ctx:ParserRuleContext): + def copyFrom(self, ctx: ParserRuleContext): super().copyFrom(ctx) - class LtExpContext(CompExprContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.CompExprContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.CompExprContext super().__init__(parser) self.copyFrom(ctx) def compExpr(self): - return self.getTypedRuleContext(MathExprParser.CompExprContext,0) + return self.getTypedRuleContext(MathExprParser.CompExprContext, 0) def LT(self): return self.getToken(MathExprParser.LT, 0) + def addExpr(self): - return self.getTypedRuleContext(MathExprParser.AddExprContext,0) + return self.getTypedRuleContext(MathExprParser.AddExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterLtExp" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterLtExp"): listener.enterLtExp(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitLtExp" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitLtExp"): listener.exitLtExp(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitLtExp" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitLtExp"): return visitor.visitLtExp(self) else: return visitor.visitChildren(self) - class EqExpContext(CompExprContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.CompExprContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.CompExprContext super().__init__(parser) self.copyFrom(ctx) def compExpr(self): - return self.getTypedRuleContext(MathExprParser.CompExprContext,0) + return self.getTypedRuleContext(MathExprParser.CompExprContext, 0) def EQ(self): return self.getToken(MathExprParser.EQ, 0) + def addExpr(self): - return self.getTypedRuleContext(MathExprParser.AddExprContext,0) + return self.getTypedRuleContext(MathExprParser.AddExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterEqExp" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterEqExp"): listener.enterEqExp(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitEqExp" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitEqExp"): listener.exitEqExp(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitEqExp" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitEqExp"): return visitor.visitEqExp(self) else: return visitor.visitChildren(self) - class ToAddContext(CompExprContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.CompExprContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.CompExprContext super().__init__(parser) self.copyFrom(ctx) def addExpr(self): - return self.getTypedRuleContext(MathExprParser.AddExprContext,0) + return self.getTypedRuleContext(MathExprParser.AddExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterToAdd" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterToAdd"): listener.enterToAdd(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitToAdd" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitToAdd"): listener.exitToAdd(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitToAdd" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitToAdd"): return visitor.visitToAdd(self) else: return visitor.visitChildren(self) - class GeExpContext(CompExprContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.CompExprContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.CompExprContext super().__init__(parser) self.copyFrom(ctx) def compExpr(self): - return self.getTypedRuleContext(MathExprParser.CompExprContext,0) + return self.getTypedRuleContext(MathExprParser.CompExprContext, 0) def GE(self): return self.getToken(MathExprParser.GE, 0) + def addExpr(self): - return self.getTypedRuleContext(MathExprParser.AddExprContext,0) + return self.getTypedRuleContext(MathExprParser.AddExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterGeExp" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterGeExp"): listener.enterGeExp(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitGeExp" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitGeExp"): listener.exitGeExp(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitGeExp" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitGeExp"): return visitor.visitGeExp(self) else: return visitor.visitChildren(self) - class LeExpContext(CompExprContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.CompExprContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.CompExprContext super().__init__(parser) self.copyFrom(ctx) def compExpr(self): - return self.getTypedRuleContext(MathExprParser.CompExprContext,0) + return self.getTypedRuleContext(MathExprParser.CompExprContext, 0) def LE(self): return self.getToken(MathExprParser.LE, 0) + def addExpr(self): - return self.getTypedRuleContext(MathExprParser.AddExprContext,0) + return self.getTypedRuleContext(MathExprParser.AddExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterLeExp" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterLeExp"): listener.enterLeExp(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitLeExp" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitLeExp"): listener.exitLeExp(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitLeExp" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitLeExp"): return visitor.visitLeExp(self) else: return visitor.visitChildren(self) - class NeExpContext(CompExprContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.CompExprContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.CompExprContext super().__init__(parser) self.copyFrom(ctx) def compExpr(self): - return self.getTypedRuleContext(MathExprParser.CompExprContext,0) + return self.getTypedRuleContext(MathExprParser.CompExprContext, 0) def NE(self): return self.getToken(MathExprParser.NE, 0) + def addExpr(self): - return self.getTypedRuleContext(MathExprParser.AddExprContext,0) + return self.getTypedRuleContext(MathExprParser.AddExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterNeExp" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterNeExp"): listener.enterNeExp(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitNeExp" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitNeExp"): listener.exitNeExp(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitNeExp" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitNeExp"): return visitor.visitNeExp(self) else: return visitor.visitChildren(self) - class GtExpContext(CompExprContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.CompExprContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.CompExprContext super().__init__(parser) self.copyFrom(ctx) def compExpr(self): - return self.getTypedRuleContext(MathExprParser.CompExprContext,0) + return self.getTypedRuleContext(MathExprParser.CompExprContext, 0) def GT(self): return self.getToken(MathExprParser.GT, 0) + def addExpr(self): - return self.getTypedRuleContext(MathExprParser.AddExprContext,0) + return self.getTypedRuleContext(MathExprParser.AddExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterGtExp" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterGtExp"): listener.enterGtExp(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitGtExp" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitGtExp"): listener.exitGtExp(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitGtExp" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitGtExp"): return visitor.visitGtExp(self) else: return visitor.visitChildren(self) - - - def compExpr(self, _p:int=0): + def compExpr(self, _p: int = 0): _parentctx = self._ctx _parentState = self.state localctx = MathExprParser.CompExprContext(self, self._ctx, _parentState) @@ -616,21 +4627,22 @@ class MathExprParser ( Parser ): self._ctx.stop = self._input.LT(-1) self.state = 51 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,2,self._ctx) - while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: - if _alt==1: + _alt = self._interp.adaptivePredict(self._input, 2, self._ctx) + while _alt != 2 and _alt != ATN.INVALID_ALT_NUMBER: + if _alt == 1: if self._parseListeners is not None: self.triggerExitRuleEvent() _prevctx = localctx self.state = 49 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,1,self._ctx) + la_ = self._interp.adaptivePredict(self._input, 1, self._ctx) if la_ == 1: localctx = MathExprParser.GtExpContext(self, MathExprParser.CompExprContext(self, _parentctx, _parentState)) self.pushNewRecursionContext(localctx, _startState, self.RULE_compExpr) self.state = 31 if not self.precpred(self._ctx, 7): from antlr4.error.Errors import FailedPredicateException + raise FailedPredicateException(self, "self.precpred(self._ctx, 7)") self.state = 32 self.match(MathExprParser.GT) @@ -644,6 +4656,7 @@ class MathExprParser ( Parser ): self.state = 34 if not self.precpred(self._ctx, 6): from antlr4.error.Errors import FailedPredicateException + raise FailedPredicateException(self, "self.precpred(self._ctx, 6)") self.state = 35 self.match(MathExprParser.GE) @@ -657,6 +4670,7 @@ class MathExprParser ( Parser ): self.state = 37 if not self.precpred(self._ctx, 5): from antlr4.error.Errors import FailedPredicateException + raise FailedPredicateException(self, "self.precpred(self._ctx, 5)") self.state = 38 self.match(MathExprParser.LT) @@ -670,6 +4684,7 @@ class MathExprParser ( Parser ): self.state = 40 if not self.precpred(self._ctx, 4): from antlr4.error.Errors import FailedPredicateException + raise FailedPredicateException(self, "self.precpred(self._ctx, 4)") self.state = 41 self.match(MathExprParser.LE) @@ -683,6 +4698,7 @@ class MathExprParser ( Parser ): self.state = 43 if not self.precpred(self._ctx, 3): from antlr4.error.Errors import FailedPredicateException + raise FailedPredicateException(self, "self.precpred(self._ctx, 3)") self.state = 44 self.match(MathExprParser.EQ) @@ -696,6 +4712,7 @@ class MathExprParser ( Parser ): self.state = 46 if not self.precpred(self._ctx, 2): from antlr4.error.Errors import FailedPredicateException + raise FailedPredicateException(self, "self.precpred(self._ctx, 2)") self.state = 47 self.match(MathExprParser.NE) @@ -703,10 +4720,9 @@ class MathExprParser ( Parser ): self.addExpr(0) pass - self.state = 53 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,2,self._ctx) + _alt = self._interp.adaptivePredict(self._input, 2, self._ctx) except RecognitionException as re: localctx.exception = re @@ -716,110 +4732,98 @@ class MathExprParser ( Parser ): self.unrollRecursionContexts(_parentctx) return localctx - class AddExprContext(ParserRuleContext): - __slots__ = 'parser' + __slots__ = "parser" - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + def __init__(self, parser, parent: ParserRuleContext = None, invokingState: int = -1): super().__init__(parent, invokingState) self.parser = parser - def getRuleIndex(self): return MathExprParser.RULE_addExpr - - def copyFrom(self, ctx:ParserRuleContext): + def copyFrom(self, ctx: ParserRuleContext): super().copyFrom(ctx) - class AddExpContext(AddExprContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.AddExprContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.AddExprContext super().__init__(parser) self.copyFrom(ctx) def addExpr(self): - return self.getTypedRuleContext(MathExprParser.AddExprContext,0) + return self.getTypedRuleContext(MathExprParser.AddExprContext, 0) def PLUS(self): return self.getToken(MathExprParser.PLUS, 0) + def mulExpr(self): - return self.getTypedRuleContext(MathExprParser.MulExprContext,0) + return self.getTypedRuleContext(MathExprParser.MulExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterAddExp" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterAddExp"): listener.enterAddExp(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitAddExp" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitAddExp"): listener.exitAddExp(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitAddExp" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitAddExp"): return visitor.visitAddExp(self) else: return visitor.visitChildren(self) - class ToMulContext(AddExprContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.AddExprContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.AddExprContext super().__init__(parser) self.copyFrom(ctx) def mulExpr(self): - return self.getTypedRuleContext(MathExprParser.MulExprContext,0) + return self.getTypedRuleContext(MathExprParser.MulExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterToMul" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterToMul"): listener.enterToMul(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitToMul" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitToMul"): listener.exitToMul(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitToMul" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitToMul"): return visitor.visitToMul(self) else: return visitor.visitChildren(self) - class SubExpContext(AddExprContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.AddExprContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.AddExprContext super().__init__(parser) self.copyFrom(ctx) def addExpr(self): - return self.getTypedRuleContext(MathExprParser.AddExprContext,0) + return self.getTypedRuleContext(MathExprParser.AddExprContext, 0) def MINUS(self): return self.getToken(MathExprParser.MINUS, 0) + def mulExpr(self): - return self.getTypedRuleContext(MathExprParser.MulExprContext,0) + return self.getTypedRuleContext(MathExprParser.MulExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterSubExp" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterSubExp"): listener.enterSubExp(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitSubExp" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitSubExp"): listener.exitSubExp(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitSubExp" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitSubExp"): return visitor.visitSubExp(self) else: return visitor.visitChildren(self) - - - def addExpr(self, _p:int=0): + def addExpr(self, _p: int = 0): _parentctx = self._ctx _parentState = self.state localctx = MathExprParser.AddExprContext(self, self._ctx, _parentState) @@ -837,21 +4841,22 @@ class MathExprParser ( Parser ): self._ctx.stop = self._input.LT(-1) self.state = 65 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,4,self._ctx) - while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: - if _alt==1: + _alt = self._interp.adaptivePredict(self._input, 4, self._ctx) + while _alt != 2 and _alt != ATN.INVALID_ALT_NUMBER: + if _alt == 1: if self._parseListeners is not None: self.triggerExitRuleEvent() _prevctx = localctx self.state = 63 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,3,self._ctx) + la_ = self._interp.adaptivePredict(self._input, 3, self._ctx) if la_ == 1: localctx = MathExprParser.AddExpContext(self, MathExprParser.AddExprContext(self, _parentctx, _parentState)) self.pushNewRecursionContext(localctx, _startState, self.RULE_addExpr) self.state = 57 if not self.precpred(self._ctx, 3): from antlr4.error.Errors import FailedPredicateException + raise FailedPredicateException(self, "self.precpred(self._ctx, 3)") self.state = 58 self.match(MathExprParser.PLUS) @@ -865,6 +4870,7 @@ class MathExprParser ( Parser ): self.state = 60 if not self.precpred(self._ctx, 2): from antlr4.error.Errors import FailedPredicateException + raise FailedPredicateException(self, "self.precpred(self._ctx, 2)") self.state = 61 self.match(MathExprParser.MINUS) @@ -872,10 +4878,9 @@ class MathExprParser ( Parser ): self.mulExpr(0) pass - self.state = 67 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,4,self._ctx) + _alt = self._interp.adaptivePredict(self._input, 4, self._ctx) except RecognitionException as re: localctx.exception = re @@ -885,140 +4890,126 @@ class MathExprParser ( Parser ): self.unrollRecursionContexts(_parentctx) return localctx - class MulExprContext(ParserRuleContext): - __slots__ = 'parser' + __slots__ = "parser" - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + def __init__(self, parser, parent: ParserRuleContext = None, invokingState: int = -1): super().__init__(parent, invokingState) self.parser = parser - def getRuleIndex(self): return MathExprParser.RULE_mulExpr - - def copyFrom(self, ctx:ParserRuleContext): + def copyFrom(self, ctx: ParserRuleContext): super().copyFrom(ctx) - class MulExpContext(MulExprContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.MulExprContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.MulExprContext super().__init__(parser) self.copyFrom(ctx) def mulExpr(self): - return self.getTypedRuleContext(MathExprParser.MulExprContext,0) + return self.getTypedRuleContext(MathExprParser.MulExprContext, 0) def MULT(self): return self.getToken(MathExprParser.MULT, 0) + def powExpr(self): - return self.getTypedRuleContext(MathExprParser.PowExprContext,0) + return self.getTypedRuleContext(MathExprParser.PowExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterMulExp" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterMulExp"): listener.enterMulExp(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitMulExp" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitMulExp"): listener.exitMulExp(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitMulExp" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitMulExp"): return visitor.visitMulExp(self) else: return visitor.visitChildren(self) - class ModExpContext(MulExprContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.MulExprContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.MulExprContext super().__init__(parser) self.copyFrom(ctx) def mulExpr(self): - return self.getTypedRuleContext(MathExprParser.MulExprContext,0) + return self.getTypedRuleContext(MathExprParser.MulExprContext, 0) def MOD(self): return self.getToken(MathExprParser.MOD, 0) + def powExpr(self): - return self.getTypedRuleContext(MathExprParser.PowExprContext,0) + return self.getTypedRuleContext(MathExprParser.PowExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterModExp" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterModExp"): listener.enterModExp(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitModExp" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitModExp"): listener.exitModExp(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitModExp" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitModExp"): return visitor.visitModExp(self) else: return visitor.visitChildren(self) - class DivExpContext(MulExprContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.MulExprContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.MulExprContext super().__init__(parser) self.copyFrom(ctx) def mulExpr(self): - return self.getTypedRuleContext(MathExprParser.MulExprContext,0) + return self.getTypedRuleContext(MathExprParser.MulExprContext, 0) def DIV(self): return self.getToken(MathExprParser.DIV, 0) + def powExpr(self): - return self.getTypedRuleContext(MathExprParser.PowExprContext,0) + return self.getTypedRuleContext(MathExprParser.PowExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterDivExp" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterDivExp"): listener.enterDivExp(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitDivExp" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitDivExp"): listener.exitDivExp(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitDivExp" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitDivExp"): return visitor.visitDivExp(self) else: return visitor.visitChildren(self) - class ToPowContext(MulExprContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.MulExprContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.MulExprContext super().__init__(parser) self.copyFrom(ctx) def powExpr(self): - return self.getTypedRuleContext(MathExprParser.PowExprContext,0) + return self.getTypedRuleContext(MathExprParser.PowExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterToPow" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterToPow"): listener.enterToPow(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitToPow" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitToPow"): listener.exitToPow(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitToPow" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitToPow"): return visitor.visitToPow(self) else: return visitor.visitChildren(self) - - - def mulExpr(self, _p:int=0): + def mulExpr(self, _p: int = 0): _parentctx = self._ctx _parentState = self.state localctx = MathExprParser.MulExprContext(self, self._ctx, _parentState) @@ -1036,21 +5027,22 @@ class MathExprParser ( Parser ): self._ctx.stop = self._input.LT(-1) self.state = 82 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,6,self._ctx) - while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: - if _alt==1: + _alt = self._interp.adaptivePredict(self._input, 6, self._ctx) + while _alt != 2 and _alt != ATN.INVALID_ALT_NUMBER: + if _alt == 1: if self._parseListeners is not None: self.triggerExitRuleEvent() _prevctx = localctx self.state = 80 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,5,self._ctx) + la_ = self._interp.adaptivePredict(self._input, 5, self._ctx) if la_ == 1: localctx = MathExprParser.MulExpContext(self, MathExprParser.MulExprContext(self, _parentctx, _parentState)) self.pushNewRecursionContext(localctx, _startState, self.RULE_mulExpr) self.state = 71 if not self.precpred(self._ctx, 4): from antlr4.error.Errors import FailedPredicateException + raise FailedPredicateException(self, "self.precpred(self._ctx, 4)") self.state = 72 self.match(MathExprParser.MULT) @@ -1064,6 +5056,7 @@ class MathExprParser ( Parser ): self.state = 74 if not self.precpred(self._ctx, 3): from antlr4.error.Errors import FailedPredicateException + raise FailedPredicateException(self, "self.precpred(self._ctx, 3)") self.state = 75 self.match(MathExprParser.DIV) @@ -1077,6 +5070,7 @@ class MathExprParser ( Parser ): self.state = 77 if not self.precpred(self._ctx, 2): from antlr4.error.Errors import FailedPredicateException + raise FailedPredicateException(self, "self.precpred(self._ctx, 2)") self.state = 78 self.match(MathExprParser.MOD) @@ -1084,10 +5078,9 @@ class MathExprParser ( Parser ): self.powExpr() pass - self.state = 84 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,6,self._ctx) + _alt = self._interp.adaptivePredict(self._input, 6, self._ctx) except RecognitionException as re: localctx.exception = re @@ -1097,88 +5090,76 @@ class MathExprParser ( Parser ): self.unrollRecursionContexts(_parentctx) return localctx - class PowExprContext(ParserRuleContext): - __slots__ = 'parser' + __slots__ = "parser" - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + def __init__(self, parser, parent: ParserRuleContext = None, invokingState: int = -1): super().__init__(parent, invokingState) self.parser = parser - def getRuleIndex(self): return MathExprParser.RULE_powExpr - - def copyFrom(self, ctx:ParserRuleContext): + def copyFrom(self, ctx: ParserRuleContext): super().copyFrom(ctx) - - class PowExpContext(PowExprContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.PowExprContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.PowExprContext super().__init__(parser) self.copyFrom(ctx) def unaryExpr(self): - return self.getTypedRuleContext(MathExprParser.UnaryExprContext,0) + return self.getTypedRuleContext(MathExprParser.UnaryExprContext, 0) def POW(self): return self.getToken(MathExprParser.POW, 0) + def powExpr(self): - return self.getTypedRuleContext(MathExprParser.PowExprContext,0) + return self.getTypedRuleContext(MathExprParser.PowExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterPowExp" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterPowExp"): listener.enterPowExp(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitPowExp" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitPowExp"): listener.exitPowExp(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitPowExp" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitPowExp"): return visitor.visitPowExp(self) else: return visitor.visitChildren(self) - class ToUnaryContext(PowExprContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.PowExprContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.PowExprContext super().__init__(parser) self.copyFrom(ctx) def unaryExpr(self): - return self.getTypedRuleContext(MathExprParser.UnaryExprContext,0) + return self.getTypedRuleContext(MathExprParser.UnaryExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterToUnary" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterToUnary"): listener.enterToUnary(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitToUnary" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitToUnary"): listener.exitToUnary(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitToUnary" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitToUnary"): return visitor.visitToUnary(self) else: return visitor.visitChildren(self) - - def powExpr(self): - localctx = MathExprParser.PowExprContext(self, self._ctx, self.state) self.enterRule(localctx, 8, self.RULE_powExpr) try: self.state = 90 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,7,self._ctx) + la_ = self._interp.adaptivePredict(self._input, 7, self._ctx) if la_ == 1: localctx = MathExprParser.PowExpContext(self, localctx) self.enterOuterAlt(localctx, 1) @@ -1197,7 +5178,6 @@ class MathExprParser ( Parser ): self.unaryExpr() pass - except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -1206,106 +5186,92 @@ class MathExprParser ( Parser ): self.exitRule() return localctx - class UnaryExprContext(ParserRuleContext): - __slots__ = 'parser' + __slots__ = "parser" - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + def __init__(self, parser, parent: ParserRuleContext = None, invokingState: int = -1): super().__init__(parent, invokingState) self.parser = parser - def getRuleIndex(self): return MathExprParser.RULE_unaryExpr - - def copyFrom(self, ctx:ParserRuleContext): + def copyFrom(self, ctx: ParserRuleContext): super().copyFrom(ctx) - - class UnaryPlusContext(UnaryExprContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.UnaryExprContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.UnaryExprContext super().__init__(parser) self.copyFrom(ctx) def PLUS(self): return self.getToken(MathExprParser.PLUS, 0) + def unaryExpr(self): - return self.getTypedRuleContext(MathExprParser.UnaryExprContext,0) + return self.getTypedRuleContext(MathExprParser.UnaryExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterUnaryPlus" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterUnaryPlus"): listener.enterUnaryPlus(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitUnaryPlus" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitUnaryPlus"): listener.exitUnaryPlus(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitUnaryPlus" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitUnaryPlus"): return visitor.visitUnaryPlus(self) else: return visitor.visitChildren(self) - class UnaryMinusContext(UnaryExprContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.UnaryExprContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.UnaryExprContext super().__init__(parser) self.copyFrom(ctx) def MINUS(self): return self.getToken(MathExprParser.MINUS, 0) + def unaryExpr(self): - return self.getTypedRuleContext(MathExprParser.UnaryExprContext,0) + return self.getTypedRuleContext(MathExprParser.UnaryExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterUnaryMinus" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterUnaryMinus"): listener.enterUnaryMinus(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitUnaryMinus" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitUnaryMinus"): listener.exitUnaryMinus(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitUnaryMinus" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitUnaryMinus"): return visitor.visitUnaryMinus(self) else: return visitor.visitChildren(self) - class ToAtomContext(UnaryExprContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.UnaryExprContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.UnaryExprContext super().__init__(parser) self.copyFrom(ctx) def atom(self): - return self.getTypedRuleContext(MathExprParser.AtomContext,0) + return self.getTypedRuleContext(MathExprParser.AtomContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterToAtom" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterToAtom"): listener.enterToAtom(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitToAtom" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitToAtom"): listener.exitToAtom(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitToAtom" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitToAtom"): return visitor.visitToAtom(self) else: return visitor.visitChildren(self) - - def unaryExpr(self): - localctx = MathExprParser.UnaryExprContext(self, self._ctx, self.state) self.enterRule(localctx, 10, self.RULE_unaryExpr) try: @@ -1328,7 +5294,65 @@ class MathExprParser ( Parser ): self.state = 95 self.unaryExpr() pass - elif token in [1, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 69, 70, 71, 72]: + elif token in [ + 1, + 3, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 69, + 70, + 71, + 72, + ]: localctx = MathExprParser.ToAtomContext(self, localctx) self.enterOuterAlt(localctx, 3) self.state = 96 @@ -1345,315 +5369,315 @@ class MathExprParser ( Parser ): self.exitRule() return localctx - class AtomContext(ParserRuleContext): - __slots__ = 'parser' + __slots__ = "parser" - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + def __init__(self, parser, parent: ParserRuleContext = None, invokingState: int = -1): super().__init__(parent, invokingState) self.parser = parser - def getRuleIndex(self): return MathExprParser.RULE_atom - - def copyFrom(self, ctx:ParserRuleContext): + def copyFrom(self, ctx: ParserRuleContext): super().copyFrom(ctx) - - class Func4ExpContext(AtomContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.AtomContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.AtomContext super().__init__(parser) self.copyFrom(ctx) def func4(self): - return self.getTypedRuleContext(MathExprParser.Func4Context,0) + return self.getTypedRuleContext(MathExprParser.Func4Context, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterFunc4Exp" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterFunc4Exp"): listener.enterFunc4Exp(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitFunc4Exp" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitFunc4Exp"): listener.exitFunc4Exp(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitFunc4Exp" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitFunc4Exp"): return visitor.visitFunc4Exp(self) else: return visitor.visitChildren(self) - class Func2ExpContext(AtomContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.AtomContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.AtomContext super().__init__(parser) self.copyFrom(ctx) def func2(self): - return self.getTypedRuleContext(MathExprParser.Func2Context,0) + return self.getTypedRuleContext(MathExprParser.Func2Context, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterFunc2Exp" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterFunc2Exp"): listener.enterFunc2Exp(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitFunc2Exp" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitFunc2Exp"): listener.exitFunc2Exp(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitFunc2Exp" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitFunc2Exp"): return visitor.visitFunc2Exp(self) else: return visitor.visitChildren(self) - class VariableExpContext(AtomContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.AtomContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.AtomContext super().__init__(parser) self.copyFrom(ctx) def VARIABLE(self): return self.getToken(MathExprParser.VARIABLE, 0) - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterVariableExp" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterVariableExp"): listener.enterVariableExp(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitVariableExp" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitVariableExp"): listener.exitVariableExp(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitVariableExp" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitVariableExp"): return visitor.visitVariableExp(self) else: return visitor.visitChildren(self) - class Func3ExpContext(AtomContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.AtomContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.AtomContext super().__init__(parser) self.copyFrom(ctx) def func3(self): - return self.getTypedRuleContext(MathExprParser.Func3Context,0) + return self.getTypedRuleContext(MathExprParser.Func3Context, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterFunc3Exp" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterFunc3Exp"): listener.enterFunc3Exp(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitFunc3Exp" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitFunc3Exp"): listener.exitFunc3Exp(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitFunc3Exp" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitFunc3Exp"): return visitor.visitFunc3Exp(self) else: return visitor.visitChildren(self) - class ParenExpContext(AtomContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.AtomContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.AtomContext super().__init__(parser) self.copyFrom(ctx) def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterParenExp" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterParenExp"): listener.enterParenExp(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitParenExp" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitParenExp"): listener.exitParenExp(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitParenExp" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitParenExp"): return visitor.visitParenExp(self) else: return visitor.visitChildren(self) - class ConstantExpContext(AtomContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.AtomContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.AtomContext super().__init__(parser) self.copyFrom(ctx) def CONSTANT(self): return self.getToken(MathExprParser.CONSTANT, 0) - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterConstantExp" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterConstantExp"): listener.enterConstantExp(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitConstantExp" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitConstantExp"): listener.exitConstantExp(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitConstantExp" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitConstantExp"): return visitor.visitConstantExp(self) else: return visitor.visitChildren(self) - class Func1ExpContext(AtomContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.AtomContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.AtomContext super().__init__(parser) self.copyFrom(ctx) def func1(self): - return self.getTypedRuleContext(MathExprParser.Func1Context,0) + return self.getTypedRuleContext(MathExprParser.Func1Context, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterFunc1Exp" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterFunc1Exp"): listener.enterFunc1Exp(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitFunc1Exp" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitFunc1Exp"): listener.exitFunc1Exp(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitFunc1Exp" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitFunc1Exp"): return visitor.visitFunc1Exp(self) else: return visitor.visitChildren(self) - class FuncNExpContext(AtomContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.AtomContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.AtomContext super().__init__(parser) self.copyFrom(ctx) def funcN(self): - return self.getTypedRuleContext(MathExprParser.FuncNContext,0) + return self.getTypedRuleContext(MathExprParser.FuncNContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterFuncNExp" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterFuncNExp"): listener.enterFuncNExp(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitFuncNExp" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitFuncNExp"): listener.exitFuncNExp(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitFuncNExp" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitFuncNExp"): return visitor.visitFuncNExp(self) else: return visitor.visitChildren(self) - class NumberExpContext(AtomContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.AtomContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.AtomContext super().__init__(parser) self.copyFrom(ctx) def NUMBER(self): return self.getToken(MathExprParser.NUMBER, 0) - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterNumberExp" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterNumberExp"): listener.enterNumberExp(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitNumberExp" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitNumberExp"): listener.exitNumberExp(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitNumberExp" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitNumberExp"): return visitor.visitNumberExp(self) else: return visitor.visitChildren(self) - class AbsExpContext(AtomContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.AtomContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.AtomContext super().__init__(parser) self.copyFrom(ctx) - def PIPE(self, i:int=None): + def PIPE(self, i: int = None): if i is None: return self.getTokens(MathExprParser.PIPE) else: return self.getToken(MathExprParser.PIPE, i) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterAbsExp" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterAbsExp"): listener.enterAbsExp(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitAbsExp" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitAbsExp"): listener.exitAbsExp(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitAbsExp" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitAbsExp"): return visitor.visitAbsExp(self) else: return visitor.visitChildren(self) - class ListExpContext(AtomContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.AtomContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.AtomContext super().__init__(parser) self.copyFrom(ctx) - def expr(self, i:int=None): + def expr(self, i: int = None): if i is None: return self.getTypedRuleContexts(MathExprParser.ExprContext) else: - return self.getTypedRuleContext(MathExprParser.ExprContext,i) + return self.getTypedRuleContext(MathExprParser.ExprContext, i) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterListExp" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterListExp"): listener.enterListExp(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitListExp" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitListExp"): listener.exitListExp(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitListExp" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitListExp"): return visitor.visitListExp(self) else: return visitor.visitChildren(self) - - def atom(self): - localctx = MathExprParser.AtomContext(self, self._ctx, self.state) self.enterRule(localctx, 12, self.RULE_atom) - self._la = 0 # Token type + self._la = 0 # Token type try: self.state = 126 self._errHandler.sync(self) token = self._input.LA(1) - if token in [6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 28, 29, 30, 31, 32, 33, 35, 37, 38, 39, 40, 41, 42, 46, 47, 48, 49, 50]: + if token in [ + 6, + 7, + 8, + 9, + 10, + 11, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 28, + 29, + 30, + 31, + 32, + 33, + 35, + 37, + 38, + 39, + 40, + 41, + 42, + 46, + 47, + 48, + 49, + 50, + ]: localctx = MathExprParser.Func1ExpContext(self, localctx) self.enterOuterAlt(localctx, 1) self.state = 99 @@ -1731,7 +5755,7 @@ class MathExprParser ( Parser ): self.state = 121 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==4: + while _la == 4: self.state = 117 self.match(MathExprParser.T__3) self.state = 118 @@ -1754,947 +5778,873 @@ class MathExprParser ( Parser ): self.exitRule() return localctx - class Func1Context(ParserRuleContext): - __slots__ = 'parser' + __slots__ = "parser" - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + def __init__(self, parser, parent: ParserRuleContext = None, invokingState: int = -1): super().__init__(parent, invokingState) self.parser = parser - def getRuleIndex(self): return MathExprParser.RULE_func1 - - def copyFrom(self, ctx:ParserRuleContext): + def copyFrom(self, ctx: ParserRuleContext): super().copyFrom(ctx) - - class SoftplusFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def SOFTPLUS(self): return self.getToken(MathExprParser.SOFTPLUS, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterSoftplusFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterSoftplusFunc"): listener.enterSoftplusFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitSoftplusFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitSoftplusFunc"): listener.exitSoftplusFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitSoftplusFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitSoftplusFunc"): return visitor.visitSoftplusFunc(self) else: return visitor.visitChildren(self) - class TanhFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def TANH(self): return self.getToken(MathExprParser.TANH, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterTanhFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterTanhFunc"): listener.enterTanhFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitTanhFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitTanhFunc"): listener.exitTanhFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitTanhFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitTanhFunc"): return visitor.visitTanhFunc(self) else: return visitor.visitChildren(self) - class AcoshFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def ACOSH(self): return self.getToken(MathExprParser.ACOSH, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterAcoshFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterAcoshFunc"): listener.enterAcoshFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitAcoshFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitAcoshFunc"): listener.exitAcoshFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitAcoshFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitAcoshFunc"): return visitor.visitAcoshFunc(self) else: return visitor.visitChildren(self) - class SqrtFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def SQRT(self): return self.getToken(MathExprParser.SQRT, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterSqrtFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterSqrtFunc"): listener.enterSqrtFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitSqrtFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitSqrtFunc"): listener.exitSqrtFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitSqrtFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitSqrtFunc"): return visitor.visitSqrtFunc(self) else: return visitor.visitChildren(self) - class FloorFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def FLOOR(self): return self.getToken(MathExprParser.FLOOR, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterFloorFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterFloorFunc"): listener.enterFloorFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitFloorFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitFloorFunc"): listener.exitFloorFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitFloorFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitFloorFunc"): return visitor.visitFloorFunc(self) else: return visitor.visitChildren(self) - class RoundFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def ROUND(self): return self.getToken(MathExprParser.ROUND, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterRoundFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterRoundFunc"): listener.enterRoundFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitRoundFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitRoundFunc"): listener.exitRoundFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitRoundFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitRoundFunc"): return visitor.visitRoundFunc(self) else: return visitor.visitChildren(self) - class CeilFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def CEIL(self): return self.getToken(MathExprParser.CEIL, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterCeilFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterCeilFunc"): listener.enterCeilFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitCeilFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitCeilFunc"): listener.exitCeilFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitCeilFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitCeilFunc"): return visitor.visitCeilFunc(self) else: return visitor.visitChildren(self) - class GeluFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def GELU(self): return self.getToken(MathExprParser.GELU, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterGeluFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterGeluFunc"): listener.enterGeluFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitGeluFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitGeluFunc"): listener.exitGeluFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitGeluFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitGeluFunc"): return visitor.visitGeluFunc(self) else: return visitor.visitChildren(self) - class PrintFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def PRNT(self): return self.getToken(MathExprParser.PRNT, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterPrintFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterPrintFunc"): listener.enterPrintFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitPrintFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitPrintFunc"): listener.exitPrintFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitPrintFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitPrintFunc"): return visitor.visitPrintFunc(self) else: return visitor.visitChildren(self) - class AbsFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def ABS(self): return self.getToken(MathExprParser.ABS, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterAbsFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterAbsFunc"): listener.enterAbsFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitAbsFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitAbsFunc"): listener.exitAbsFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitAbsFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitAbsFunc"): return visitor.visitAbsFunc(self) else: return visitor.visitChildren(self) - class AtanFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def ATAN(self): return self.getToken(MathExprParser.ATAN, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterAtanFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterAtanFunc"): listener.enterAtanFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitAtanFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitAtanFunc"): listener.exitAtanFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitAtanFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitAtanFunc"): return visitor.visitAtanFunc(self) else: return visitor.visitChildren(self) - class ReluFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def RELU(self): return self.getToken(MathExprParser.RELU, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterReluFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterReluFunc"): listener.enterReluFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitReluFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitReluFunc"): listener.exitReluFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitReluFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitReluFunc"): return visitor.visitReluFunc(self) else: return visitor.visitChildren(self) - class SinhFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def SINH(self): return self.getToken(MathExprParser.SINH, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterSinhFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterSinhFunc"): listener.enterSinhFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitSinhFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitSinhFunc"): listener.exitSinhFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitSinhFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitSinhFunc"): return visitor.visitSinhFunc(self) else: return visitor.visitChildren(self) - class SigmoidFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def SIGM(self): return self.getToken(MathExprParser.SIGM, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterSigmoidFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterSigmoidFunc"): listener.enterSigmoidFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitSigmoidFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitSigmoidFunc"): listener.exitSigmoidFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitSigmoidFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitSigmoidFunc"): return visitor.visitSigmoidFunc(self) else: return visitor.visitChildren(self) - class LogFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def LOG(self): return self.getToken(MathExprParser.LOG, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterLogFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterLogFunc"): listener.enterLogFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitLogFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitLogFunc"): listener.exitLogFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitLogFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitLogFunc"): return visitor.visitLogFunc(self) else: return visitor.visitChildren(self) - class LnFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def LN(self): return self.getToken(MathExprParser.LN, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterLnFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterLnFunc"): listener.enterLnFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitLnFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitLnFunc"): listener.exitLnFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitLnFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitLnFunc"): return visitor.visitLnFunc(self) else: return visitor.visitChildren(self) - class TNormFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def TNORM(self): return self.getToken(MathExprParser.TNORM, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterTNormFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterTNormFunc"): listener.enterTNormFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitTNormFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitTNormFunc"): listener.exitTNormFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitTNormFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitTNormFunc"): return visitor.visitTNormFunc(self) else: return visitor.visitChildren(self) - class SNormFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def SNORM(self): return self.getToken(MathExprParser.SNORM, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterSNormFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterSNormFunc"): listener.enterSNormFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitSNormFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitSNormFunc"): listener.exitSNormFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitSNormFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitSNormFunc"): return visitor.visitSNormFunc(self) else: return visitor.visitChildren(self) - class SinFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def SIN(self): return self.getToken(MathExprParser.SIN, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterSinFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterSinFunc"): listener.enterSinFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitSinFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitSinFunc"): listener.exitSinFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitSinFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitSinFunc"): return visitor.visitSinFunc(self) else: return visitor.visitChildren(self) - class AcosFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def ACOS(self): return self.getToken(MathExprParser.ACOS, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterAcosFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterAcosFunc"): listener.enterAcosFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitAcosFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitAcosFunc"): listener.exitAcosFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitAcosFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitAcosFunc"): return visitor.visitAcosFunc(self) else: return visitor.visitChildren(self) - class CoshFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def COSH(self): return self.getToken(MathExprParser.COSH, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterCoshFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterCoshFunc"): listener.enterCoshFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitCoshFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitCoshFunc"): listener.exitCoshFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitCoshFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitCoshFunc"): return visitor.visitCoshFunc(self) else: return visitor.visitChildren(self) - class AnglFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def ANGL(self): return self.getToken(MathExprParser.ANGL, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterAnglFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterAnglFunc"): listener.enterAnglFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitAnglFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitAnglFunc"): listener.exitAnglFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitAnglFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitAnglFunc"): return visitor.visitAnglFunc(self) else: return visitor.visitChildren(self) - class SignFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def SIGN(self): return self.getToken(MathExprParser.SIGN, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterSignFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterSignFunc"): listener.enterSignFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitSignFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitSignFunc"): listener.exitSignFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitSignFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitSignFunc"): return visitor.visitSignFunc(self) else: return visitor.visitChildren(self) - class TanFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def TAN(self): return self.getToken(MathExprParser.TAN, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterTanFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterTanFunc"): listener.enterTanFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitTanFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitTanFunc"): listener.exitTanFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitTanFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitTanFunc"): return visitor.visitTanFunc(self) else: return visitor.visitChildren(self) - class SifftFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def SIFFT(self): return self.getToken(MathExprParser.SIFFT, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterSifftFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterSifftFunc"): listener.enterSifftFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitSifftFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitSifftFunc"): listener.exitSifftFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitSifftFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitSifftFunc"): return visitor.visitSifftFunc(self) else: return visitor.visitChildren(self) - class FractFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def FRACT(self): return self.getToken(MathExprParser.FRACT, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterFractFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterFractFunc"): listener.enterFractFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitFractFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitFractFunc"): listener.exitFractFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitFractFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitFractFunc"): return visitor.visitFractFunc(self) else: return visitor.visitChildren(self) - class GammaFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def GAMMA(self): return self.getToken(MathExprParser.GAMMA, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterGammaFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterGammaFunc"): listener.enterGammaFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitGammaFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitGammaFunc"): listener.exitGammaFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitGammaFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitGammaFunc"): return visitor.visitGammaFunc(self) else: return visitor.visitChildren(self) - class CosFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def COS(self): return self.getToken(MathExprParser.COS, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterCosFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterCosFunc"): listener.enterCosFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitCosFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitCosFunc"): listener.exitCosFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitCosFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitCosFunc"): return visitor.visitCosFunc(self) else: return visitor.visitChildren(self) - class AsinFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def ASIN(self): return self.getToken(MathExprParser.ASIN, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterAsinFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterAsinFunc"): listener.enterAsinFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitAsinFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitAsinFunc"): listener.exitAsinFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitAsinFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitAsinFunc"): return visitor.visitAsinFunc(self) else: return visitor.visitChildren(self) - class AsinhFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def ASINH(self): return self.getToken(MathExprParser.ASINH, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterAsinhFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterAsinhFunc"): listener.enterAsinhFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitAsinhFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitAsinhFunc"): listener.exitAsinhFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitAsinhFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitAsinhFunc"): return visitor.visitAsinhFunc(self) else: return visitor.visitChildren(self) - class SfftFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def SFFT(self): return self.getToken(MathExprParser.SFFT, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterSfftFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterSfftFunc"): listener.enterSfftFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitSfftFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitSfftFunc"): listener.exitSfftFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitSfftFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitSfftFunc"): return visitor.visitSfftFunc(self) else: return visitor.visitChildren(self) - class AtanhFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def ATANH(self): return self.getToken(MathExprParser.ATANH, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterAtanhFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterAtanhFunc"): listener.enterAtanhFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitAtanhFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitAtanhFunc"): listener.exitAtanhFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitAtanhFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitAtanhFunc"): return visitor.visitAtanhFunc(self) else: return visitor.visitChildren(self) - class ExpFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def EXP(self): return self.getToken(MathExprParser.EXP, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterExpFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterExpFunc"): listener.enterExpFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitExpFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitExpFunc"): listener.exitExpFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitExpFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitExpFunc"): return visitor.visitExpFunc(self) else: return visitor.visitChildren(self) - class PrintShapeFuncContext(Func1Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func1Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func1Context super().__init__(parser) self.copyFrom(ctx) def PRINT_SHAPE_L(self): return self.getToken(MathExprParser.PRINT_SHAPE_L, 0) + def expr(self): - return self.getTypedRuleContext(MathExprParser.ExprContext,0) + return self.getTypedRuleContext(MathExprParser.ExprContext, 0) def PRINT_SHAPE(self): return self.getToken(MathExprParser.PRINT_SHAPE, 0) - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterPrintShapeFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterPrintShapeFunc"): listener.enterPrintShapeFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitPrintShapeFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitPrintShapeFunc"): listener.exitPrintShapeFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitPrintShapeFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitPrintShapeFunc"): return visitor.visitPrintShapeFunc(self) else: return visitor.visitChildren(self) - - def func1(self): - localctx = MathExprParser.Func1Context(self, self._ctx, self.state) self.enterRule(localctx, 14, self.RULE_func1) try: @@ -3132,177 +7082,160 @@ class MathExprParser ( Parser ): self.exitRule() return localctx - class Func2Context(ParserRuleContext): - __slots__ = 'parser' + __slots__ = "parser" - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + def __init__(self, parser, parent: ParserRuleContext = None, invokingState: int = -1): super().__init__(parent, invokingState) self.parser = parser - def getRuleIndex(self): return MathExprParser.RULE_func2 - - def copyFrom(self, ctx:ParserRuleContext): + def copyFrom(self, ctx: ParserRuleContext): super().copyFrom(ctx) - - class TMaxFuncContext(Func2Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func2Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func2Context super().__init__(parser) self.copyFrom(ctx) def TMAX(self): return self.getToken(MathExprParser.TMAX, 0) - def expr(self, i:int=None): + + def expr(self, i: int = None): if i is None: return self.getTypedRuleContexts(MathExprParser.ExprContext) else: - return self.getTypedRuleContext(MathExprParser.ExprContext,i) + return self.getTypedRuleContext(MathExprParser.ExprContext, i) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterTMaxFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterTMaxFunc"): listener.enterTMaxFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitTMaxFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitTMaxFunc"): listener.exitTMaxFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitTMaxFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitTMaxFunc"): return visitor.visitTMaxFunc(self) else: return visitor.visitChildren(self) - class PowFuncContext(Func2Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func2Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func2Context super().__init__(parser) self.copyFrom(ctx) def POWE(self): return self.getToken(MathExprParser.POWE, 0) - def expr(self, i:int=None): + + def expr(self, i: int = None): if i is None: return self.getTypedRuleContexts(MathExprParser.ExprContext) else: - return self.getTypedRuleContext(MathExprParser.ExprContext,i) + return self.getTypedRuleContext(MathExprParser.ExprContext, i) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterPowFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterPowFunc"): listener.enterPowFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitPowFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitPowFunc"): listener.exitPowFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitPowFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitPowFunc"): return visitor.visitPowFunc(self) else: return visitor.visitChildren(self) - class StepFuncContext(Func2Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func2Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func2Context super().__init__(parser) self.copyFrom(ctx) def STEP(self): return self.getToken(MathExprParser.STEP, 0) - def expr(self, i:int=None): + + def expr(self, i: int = None): if i is None: return self.getTypedRuleContexts(MathExprParser.ExprContext) else: - return self.getTypedRuleContext(MathExprParser.ExprContext,i) + return self.getTypedRuleContext(MathExprParser.ExprContext, i) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterStepFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterStepFunc"): listener.enterStepFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitStepFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitStepFunc"): listener.exitStepFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitStepFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitStepFunc"): return visitor.visitStepFunc(self) else: return visitor.visitChildren(self) - class Atan2FuncContext(Func2Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func2Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func2Context super().__init__(parser) self.copyFrom(ctx) def ATAN2(self): return self.getToken(MathExprParser.ATAN2, 0) - def expr(self, i:int=None): + + def expr(self, i: int = None): if i is None: return self.getTypedRuleContexts(MathExprParser.ExprContext) else: - return self.getTypedRuleContext(MathExprParser.ExprContext,i) + return self.getTypedRuleContext(MathExprParser.ExprContext, i) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterAtan2Func" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterAtan2Func"): listener.enterAtan2Func(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitAtan2Func" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitAtan2Func"): listener.exitAtan2Func(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitAtan2Func" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitAtan2Func"): return visitor.visitAtan2Func(self) else: return visitor.visitChildren(self) - class TMinFuncContext(Func2Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func2Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func2Context super().__init__(parser) self.copyFrom(ctx) def TMIN(self): return self.getToken(MathExprParser.TMIN, 0) - def expr(self, i:int=None): + + def expr(self, i: int = None): if i is None: return self.getTypedRuleContexts(MathExprParser.ExprContext) else: - return self.getTypedRuleContext(MathExprParser.ExprContext,i) + return self.getTypedRuleContext(MathExprParser.ExprContext, i) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterTMinFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterTMinFunc"): listener.enterTMinFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitTMinFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitTMinFunc"): listener.exitTMinFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitTMinFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitTMinFunc"): return visitor.visitTMinFunc(self) else: return visitor.visitChildren(self) - - def func2(self): - localctx = MathExprParser.Func2Context(self, self._ctx, self.state) self.enterRule(localctx, 16, self.RULE_func2) try: @@ -3400,147 +7333,132 @@ class MathExprParser ( Parser ): self.exitRule() return localctx - class Func3Context(ParserRuleContext): - __slots__ = 'parser' + __slots__ = "parser" - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + def __init__(self, parser, parent: ParserRuleContext = None, invokingState: int = -1): super().__init__(parent, invokingState) self.parser = parser - def getRuleIndex(self): return MathExprParser.RULE_func3 - - def copyFrom(self, ctx:ParserRuleContext): + def copyFrom(self, ctx: ParserRuleContext): super().copyFrom(ctx) - - class LerpFuncContext(Func3Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func3Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func3Context super().__init__(parser) self.copyFrom(ctx) def LERP(self): return self.getToken(MathExprParser.LERP, 0) - def expr(self, i:int=None): + + def expr(self, i: int = None): if i is None: return self.getTypedRuleContexts(MathExprParser.ExprContext) else: - return self.getTypedRuleContext(MathExprParser.ExprContext,i) + return self.getTypedRuleContext(MathExprParser.ExprContext, i) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterLerpFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterLerpFunc"): listener.enterLerpFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitLerpFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitLerpFunc"): listener.exitLerpFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitLerpFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitLerpFunc"): return visitor.visitLerpFunc(self) else: return visitor.visitChildren(self) - class SmoothstepFuncContext(Func3Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func3Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func3Context super().__init__(parser) self.copyFrom(ctx) def SMOOTHSTEP(self): return self.getToken(MathExprParser.SMOOTHSTEP, 0) - def expr(self, i:int=None): + + def expr(self, i: int = None): if i is None: return self.getTypedRuleContexts(MathExprParser.ExprContext) else: - return self.getTypedRuleContext(MathExprParser.ExprContext,i) + return self.getTypedRuleContext(MathExprParser.ExprContext, i) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterSmoothstepFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterSmoothstepFunc"): listener.enterSmoothstepFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitSmoothstepFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitSmoothstepFunc"): listener.exitSmoothstepFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitSmoothstepFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitSmoothstepFunc"): return visitor.visitSmoothstepFunc(self) else: return visitor.visitChildren(self) - class RangeFuncContext(Func3Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func3Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func3Context super().__init__(parser) self.copyFrom(ctx) def RANGE(self): return self.getToken(MathExprParser.RANGE, 0) - def expr(self, i:int=None): + + def expr(self, i: int = None): if i is None: return self.getTypedRuleContexts(MathExprParser.ExprContext) else: - return self.getTypedRuleContext(MathExprParser.ExprContext,i) + return self.getTypedRuleContext(MathExprParser.ExprContext, i) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterRangeFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterRangeFunc"): listener.enterRangeFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitRangeFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitRangeFunc"): listener.exitRangeFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitRangeFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitRangeFunc"): return visitor.visitRangeFunc(self) else: return visitor.visitChildren(self) - class ClampFuncContext(Func3Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func3Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func3Context super().__init__(parser) self.copyFrom(ctx) def CLAMP(self): return self.getToken(MathExprParser.CLAMP, 0) - def expr(self, i:int=None): + + def expr(self, i: int = None): if i is None: return self.getTypedRuleContexts(MathExprParser.ExprContext) else: - return self.getTypedRuleContext(MathExprParser.ExprContext,i) + return self.getTypedRuleContext(MathExprParser.ExprContext, i) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterClampFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterClampFunc"): listener.enterClampFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitClampFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitClampFunc"): listener.exitClampFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitClampFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitClampFunc"): return visitor.visitClampFunc(self) else: return visitor.visitChildren(self) - - def func3(self): - localctx = MathExprParser.Func3Context(self, self._ctx, self.state) self.enterRule(localctx, 18, self.RULE_func3) try: @@ -3638,57 +7556,48 @@ class MathExprParser ( Parser ): self.exitRule() return localctx - class Func4Context(ParserRuleContext): - __slots__ = 'parser' + __slots__ = "parser" - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + def __init__(self, parser, parent: ParserRuleContext = None, invokingState: int = -1): super().__init__(parent, invokingState) self.parser = parser - def getRuleIndex(self): return MathExprParser.RULE_func4 - - def copyFrom(self, ctx:ParserRuleContext): + def copyFrom(self, ctx: ParserRuleContext): super().copyFrom(ctx) - - class SwapFuncContext(Func4Context): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.Func4Context + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.Func4Context super().__init__(parser) self.copyFrom(ctx) def SWAP(self): return self.getToken(MathExprParser.SWAP, 0) - def expr(self, i:int=None): + + def expr(self, i: int = None): if i is None: return self.getTypedRuleContexts(MathExprParser.ExprContext) else: - return self.getTypedRuleContext(MathExprParser.ExprContext,i) + return self.getTypedRuleContext(MathExprParser.ExprContext, i) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterSwapFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterSwapFunc"): listener.enterSwapFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitSwapFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitSwapFunc"): listener.exitSwapFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitSwapFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitSwapFunc"): return visitor.visitSwapFunc(self) else: return visitor.visitChildren(self) - - def func4(self): - localctx = MathExprParser.Func4Context(self, self._ctx, self.state) self.enterRule(localctx, 20, self.RULE_func4) try: @@ -3722,210 +7631,191 @@ class MathExprParser ( Parser ): self.exitRule() return localctx - class FuncNContext(ParserRuleContext): - __slots__ = 'parser' + __slots__ = "parser" - def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + def __init__(self, parser, parent: ParserRuleContext = None, invokingState: int = -1): super().__init__(parent, invokingState) self.parser = parser - def getRuleIndex(self): return MathExprParser.RULE_funcN - - def copyFrom(self, ctx:ParserRuleContext): + def copyFrom(self, ctx: ParserRuleContext): super().copyFrom(ctx) - - class SMaxFuncContext(FuncNContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.FuncNContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.FuncNContext super().__init__(parser) self.copyFrom(ctx) def SMAX(self): return self.getToken(MathExprParser.SMAX, 0) - def expr(self, i:int=None): + + def expr(self, i: int = None): if i is None: return self.getTypedRuleContexts(MathExprParser.ExprContext) else: - return self.getTypedRuleContext(MathExprParser.ExprContext,i) + return self.getTypedRuleContext(MathExprParser.ExprContext, i) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterSMaxFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterSMaxFunc"): listener.enterSMaxFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitSMaxFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitSMaxFunc"): listener.exitSMaxFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitSMaxFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitSMaxFunc"): return visitor.visitSMaxFunc(self) else: return visitor.visitChildren(self) - class MapFuncContext(FuncNContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.FuncNContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.FuncNContext super().__init__(parser) self.copyFrom(ctx) def MAP(self): return self.getToken(MathExprParser.MAP, 0) - def expr(self, i:int=None): + + def expr(self, i: int = None): if i is None: return self.getTypedRuleContexts(MathExprParser.ExprContext) else: - return self.getTypedRuleContext(MathExprParser.ExprContext,i) + return self.getTypedRuleContext(MathExprParser.ExprContext, i) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterMapFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterMapFunc"): listener.enterMapFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitMapFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitMapFunc"): listener.exitMapFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitMapFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitMapFunc"): return visitor.visitMapFunc(self) else: return visitor.visitChildren(self) - class PermuteFuncContext(FuncNContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.FuncNContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.FuncNContext super().__init__(parser) self.copyFrom(ctx) def PERM(self): return self.getToken(MathExprParser.PERM, 0) - def expr(self, i:int=None): + + def expr(self, i: int = None): if i is None: return self.getTypedRuleContexts(MathExprParser.ExprContext) else: - return self.getTypedRuleContext(MathExprParser.ExprContext,i) + return self.getTypedRuleContext(MathExprParser.ExprContext, i) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterPermuteFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterPermuteFunc"): listener.enterPermuteFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitPermuteFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitPermuteFunc"): listener.exitPermuteFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitPermuteFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitPermuteFunc"): return visitor.visitPermuteFunc(self) else: return visitor.visitChildren(self) - class ReshapeFuncContext(FuncNContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.FuncNContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.FuncNContext super().__init__(parser) self.copyFrom(ctx) def RESHAPE(self): return self.getToken(MathExprParser.RESHAPE, 0) - def expr(self, i:int=None): + + def expr(self, i: int = None): if i is None: return self.getTypedRuleContexts(MathExprParser.ExprContext) else: - return self.getTypedRuleContext(MathExprParser.ExprContext,i) + return self.getTypedRuleContext(MathExprParser.ExprContext, i) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterReshapeFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterReshapeFunc"): listener.enterReshapeFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitReshapeFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitReshapeFunc"): listener.exitReshapeFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitReshapeFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitReshapeFunc"): return visitor.visitReshapeFunc(self) else: return visitor.visitChildren(self) - class SMinFuncContext(FuncNContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.FuncNContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.FuncNContext super().__init__(parser) self.copyFrom(ctx) def SMIN(self): return self.getToken(MathExprParser.SMIN, 0) - def expr(self, i:int=None): + + def expr(self, i: int = None): if i is None: return self.getTypedRuleContexts(MathExprParser.ExprContext) else: - return self.getTypedRuleContext(MathExprParser.ExprContext,i) + return self.getTypedRuleContext(MathExprParser.ExprContext, i) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterSMinFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterSMinFunc"): listener.enterSMinFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitSMinFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitSMinFunc"): listener.exitSMinFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitSMinFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitSMinFunc"): return visitor.visitSMinFunc(self) else: return visitor.visitChildren(self) - class ConvFuncContext(FuncNContext): - - def __init__(self, parser, ctx:ParserRuleContext): # actually a MathExprParser.FuncNContext + def __init__(self, parser, ctx: ParserRuleContext): # actually a MathExprParser.FuncNContext super().__init__(parser) self.copyFrom(ctx) def CONV(self): return self.getToken(MathExprParser.CONV, 0) - def expr(self, i:int=None): + + def expr(self, i: int = None): if i is None: return self.getTypedRuleContexts(MathExprParser.ExprContext) else: - return self.getTypedRuleContext(MathExprParser.ExprContext,i) + return self.getTypedRuleContext(MathExprParser.ExprContext, i) - - def enterRule(self, listener:ParseTreeListener): - if hasattr( listener, "enterConvFunc" ): + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterConvFunc"): listener.enterConvFunc(self) - def exitRule(self, listener:ParseTreeListener): - if hasattr( listener, "exitConvFunc" ): + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitConvFunc"): listener.exitConvFunc(self) - def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitConvFunc" ): + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitConvFunc"): return visitor.visitConvFunc(self) else: return visitor.visitChildren(self) - - def funcN(self): - localctx = MathExprParser.FuncNContext(self, self._ctx, self.state) self.enterRule(localctx, 22, self.RULE_funcN) - self._la = 0 # Token type + self._la = 0 # Token type try: self.state = 451 self._errHandler.sync(self) @@ -3942,7 +7832,7 @@ class MathExprParser ( Parser ): self.state = 398 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==4: + while _la == 4: self.state = 394 self.match(MathExprParser.T__3) self.state = 395 @@ -3966,7 +7856,7 @@ class MathExprParser ( Parser ): self.state = 410 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==4: + while _la == 4: self.state = 406 self.match(MathExprParser.T__3) self.state = 407 @@ -3987,7 +7877,7 @@ class MathExprParser ( Parser ): self.match(MathExprParser.T__0) self.state = 417 self.expr() - self.state = 420 + self.state = 420 self._errHandler.sync(self) _la = self._input.LA(1) while True: @@ -3995,10 +7885,10 @@ class MathExprParser ( Parser ): self.match(MathExprParser.T__3) self.state = 419 self.expr() - self.state = 422 + self.state = 422 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==4): + if not (_la == 4): break self.state = 424 @@ -4013,7 +7903,7 @@ class MathExprParser ( Parser ): self.match(MathExprParser.T__0) self.state = 428 self.expr() - self.state = 431 + self.state = 431 self._errHandler.sync(self) _la = self._input.LA(1) while True: @@ -4021,10 +7911,10 @@ class MathExprParser ( Parser ): self.match(MathExprParser.T__3) self.state = 430 self.expr() - self.state = 433 + self.state = 433 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==4): + if not (_la == 4): break self.state = 435 @@ -4073,9 +7963,7 @@ class MathExprParser ( Parser ): self.exitRule() return localctx - - - def sempred(self, localctx:RuleContext, ruleIndex:int, predIndex:int): + def sempred(self, localctx: RuleContext, ruleIndex: int, predIndex: int): if self._predicates == None: self._predicates = dict() self._predicates[1] = self.compExpr_sempred @@ -4087,53 +7975,38 @@ class MathExprParser ( Parser ): else: return pred(localctx, predIndex) - def compExpr_sempred(self, localctx:CompExprContext, predIndex:int): - if predIndex == 0: - return self.precpred(self._ctx, 7) - + def compExpr_sempred(self, localctx: CompExprContext, predIndex: int): + if predIndex == 0: + return self.precpred(self._ctx, 7) - if predIndex == 1: - return self.precpred(self._ctx, 6) - + if predIndex == 1: + return self.precpred(self._ctx, 6) - if predIndex == 2: - return self.precpred(self._ctx, 5) - + if predIndex == 2: + return self.precpred(self._ctx, 5) - if predIndex == 3: - return self.precpred(self._ctx, 4) - + if predIndex == 3: + return self.precpred(self._ctx, 4) - if predIndex == 4: - return self.precpred(self._ctx, 3) - + if predIndex == 4: + return self.precpred(self._ctx, 3) - if predIndex == 5: - return self.precpred(self._ctx, 2) - + if predIndex == 5: + return self.precpred(self._ctx, 2) - def addExpr_sempred(self, localctx:AddExprContext, predIndex:int): - if predIndex == 6: - return self.precpred(self._ctx, 3) - - - if predIndex == 7: - return self.precpred(self._ctx, 2) - - - def mulExpr_sempred(self, localctx:MulExprContext, predIndex:int): - if predIndex == 8: - return self.precpred(self._ctx, 4) - - - if predIndex == 9: - return self.precpred(self._ctx, 3) - - - if predIndex == 10: - return self.precpred(self._ctx, 2) - + def addExpr_sempred(self, localctx: AddExprContext, predIndex: int): + if predIndex == 6: + return self.precpred(self._ctx, 3) + if predIndex == 7: + return self.precpred(self._ctx, 2) + def mulExpr_sempred(self, localctx: MulExprContext, predIndex: int): + if predIndex == 8: + return self.precpred(self._ctx, 4) + if predIndex == 9: + return self.precpred(self._ctx, 3) + if predIndex == 10: + return self.precpred(self._ctx, 2) diff --git a/more_math/Parser/MathExprVisitor.py b/more_math/Parser/MathExprVisitor.py index a960267..9f4c67a 100644 --- a/more_math/Parser/MathExprVisitor.py +++ b/more_math/Parser/MathExprVisitor.py @@ -1,5 +1,6 @@ # Generated from ./MathExpr.g4 by ANTLR 4.13.2 from antlr4 import * + if "." in __name__: from .MathExprParser import MathExprParser else: @@ -7,412 +8,331 @@ else: # This class defines a complete generic visitor for a parse tree produced by MathExprParser. + class MathExprVisitor(ParseTreeVisitor): - # Visit a parse tree produced by MathExprParser#expr. - def visitExpr(self, ctx:MathExprParser.ExprContext): + def visitExpr(self, ctx: MathExprParser.ExprContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#LtExp. - def visitLtExp(self, ctx:MathExprParser.LtExpContext): + def visitLtExp(self, ctx: MathExprParser.LtExpContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#EqExp. - def visitEqExp(self, ctx:MathExprParser.EqExpContext): + def visitEqExp(self, ctx: MathExprParser.EqExpContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#ToAdd. - def visitToAdd(self, ctx:MathExprParser.ToAddContext): + def visitToAdd(self, ctx: MathExprParser.ToAddContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#GeExp. - def visitGeExp(self, ctx:MathExprParser.GeExpContext): + def visitGeExp(self, ctx: MathExprParser.GeExpContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#LeExp. - def visitLeExp(self, ctx:MathExprParser.LeExpContext): + def visitLeExp(self, ctx: MathExprParser.LeExpContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#NeExp. - def visitNeExp(self, ctx:MathExprParser.NeExpContext): + def visitNeExp(self, ctx: MathExprParser.NeExpContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#GtExp. - def visitGtExp(self, ctx:MathExprParser.GtExpContext): + def visitGtExp(self, ctx: MathExprParser.GtExpContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#AddExp. - def visitAddExp(self, ctx:MathExprParser.AddExpContext): + def visitAddExp(self, ctx: MathExprParser.AddExpContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#ToMul. - def visitToMul(self, ctx:MathExprParser.ToMulContext): + def visitToMul(self, ctx: MathExprParser.ToMulContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#SubExp. - def visitSubExp(self, ctx:MathExprParser.SubExpContext): + def visitSubExp(self, ctx: MathExprParser.SubExpContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#MulExp. - def visitMulExp(self, ctx:MathExprParser.MulExpContext): + def visitMulExp(self, ctx: MathExprParser.MulExpContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#ModExp. - def visitModExp(self, ctx:MathExprParser.ModExpContext): + def visitModExp(self, ctx: MathExprParser.ModExpContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#DivExp. - def visitDivExp(self, ctx:MathExprParser.DivExpContext): + def visitDivExp(self, ctx: MathExprParser.DivExpContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#ToPow. - def visitToPow(self, ctx:MathExprParser.ToPowContext): + def visitToPow(self, ctx: MathExprParser.ToPowContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#PowExp. - def visitPowExp(self, ctx:MathExprParser.PowExpContext): + def visitPowExp(self, ctx: MathExprParser.PowExpContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#ToUnary. - def visitToUnary(self, ctx:MathExprParser.ToUnaryContext): + def visitToUnary(self, ctx: MathExprParser.ToUnaryContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#UnaryPlus. - def visitUnaryPlus(self, ctx:MathExprParser.UnaryPlusContext): + def visitUnaryPlus(self, ctx: MathExprParser.UnaryPlusContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#UnaryMinus. - def visitUnaryMinus(self, ctx:MathExprParser.UnaryMinusContext): + def visitUnaryMinus(self, ctx: MathExprParser.UnaryMinusContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#ToAtom. - def visitToAtom(self, ctx:MathExprParser.ToAtomContext): + def visitToAtom(self, ctx: MathExprParser.ToAtomContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#Func1Exp. - def visitFunc1Exp(self, ctx:MathExprParser.Func1ExpContext): + def visitFunc1Exp(self, ctx: MathExprParser.Func1ExpContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#Func2Exp. - def visitFunc2Exp(self, ctx:MathExprParser.Func2ExpContext): + def visitFunc2Exp(self, ctx: MathExprParser.Func2ExpContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#Func3Exp. - def visitFunc3Exp(self, ctx:MathExprParser.Func3ExpContext): + def visitFunc3Exp(self, ctx: MathExprParser.Func3ExpContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#Func4Exp. - def visitFunc4Exp(self, ctx:MathExprParser.Func4ExpContext): + def visitFunc4Exp(self, ctx: MathExprParser.Func4ExpContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#FuncNExp. - def visitFuncNExp(self, ctx:MathExprParser.FuncNExpContext): + def visitFuncNExp(self, ctx: MathExprParser.FuncNExpContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#VariableExp. - def visitVariableExp(self, ctx:MathExprParser.VariableExpContext): + def visitVariableExp(self, ctx: MathExprParser.VariableExpContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#NumberExp. - def visitNumberExp(self, ctx:MathExprParser.NumberExpContext): + def visitNumberExp(self, ctx: MathExprParser.NumberExpContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#ConstantExp. - def visitConstantExp(self, ctx:MathExprParser.ConstantExpContext): + def visitConstantExp(self, ctx: MathExprParser.ConstantExpContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#ParenExp. - def visitParenExp(self, ctx:MathExprParser.ParenExpContext): + def visitParenExp(self, ctx: MathExprParser.ParenExpContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#AbsExp. - def visitAbsExp(self, ctx:MathExprParser.AbsExpContext): + def visitAbsExp(self, ctx: MathExprParser.AbsExpContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#ListExp. - def visitListExp(self, ctx:MathExprParser.ListExpContext): + def visitListExp(self, ctx: MathExprParser.ListExpContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#SinFunc. - def visitSinFunc(self, ctx:MathExprParser.SinFuncContext): + def visitSinFunc(self, ctx: MathExprParser.SinFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#CosFunc. - def visitCosFunc(self, ctx:MathExprParser.CosFuncContext): + def visitCosFunc(self, ctx: MathExprParser.CosFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#TanFunc. - def visitTanFunc(self, ctx:MathExprParser.TanFuncContext): + def visitTanFunc(self, ctx: MathExprParser.TanFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#AsinFunc. - def visitAsinFunc(self, ctx:MathExprParser.AsinFuncContext): + def visitAsinFunc(self, ctx: MathExprParser.AsinFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#AcosFunc. - def visitAcosFunc(self, ctx:MathExprParser.AcosFuncContext): + def visitAcosFunc(self, ctx: MathExprParser.AcosFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#AtanFunc. - def visitAtanFunc(self, ctx:MathExprParser.AtanFuncContext): + def visitAtanFunc(self, ctx: MathExprParser.AtanFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#SinhFunc. - def visitSinhFunc(self, ctx:MathExprParser.SinhFuncContext): + def visitSinhFunc(self, ctx: MathExprParser.SinhFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#CoshFunc. - def visitCoshFunc(self, ctx:MathExprParser.CoshFuncContext): + def visitCoshFunc(self, ctx: MathExprParser.CoshFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#TanhFunc. - def visitTanhFunc(self, ctx:MathExprParser.TanhFuncContext): + def visitTanhFunc(self, ctx: MathExprParser.TanhFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#AsinhFunc. - def visitAsinhFunc(self, ctx:MathExprParser.AsinhFuncContext): + def visitAsinhFunc(self, ctx: MathExprParser.AsinhFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#AcoshFunc. - def visitAcoshFunc(self, ctx:MathExprParser.AcoshFuncContext): + def visitAcoshFunc(self, ctx: MathExprParser.AcoshFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#AtanhFunc. - def visitAtanhFunc(self, ctx:MathExprParser.AtanhFuncContext): + def visitAtanhFunc(self, ctx: MathExprParser.AtanhFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#AbsFunc. - def visitAbsFunc(self, ctx:MathExprParser.AbsFuncContext): + def visitAbsFunc(self, ctx: MathExprParser.AbsFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#SqrtFunc. - def visitSqrtFunc(self, ctx:MathExprParser.SqrtFuncContext): + def visitSqrtFunc(self, ctx: MathExprParser.SqrtFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#LnFunc. - def visitLnFunc(self, ctx:MathExprParser.LnFuncContext): + def visitLnFunc(self, ctx: MathExprParser.LnFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#LogFunc. - def visitLogFunc(self, ctx:MathExprParser.LogFuncContext): + def visitLogFunc(self, ctx: MathExprParser.LogFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#ExpFunc. - def visitExpFunc(self, ctx:MathExprParser.ExpFuncContext): + def visitExpFunc(self, ctx: MathExprParser.ExpFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#TNormFunc. - def visitTNormFunc(self, ctx:MathExprParser.TNormFuncContext): + def visitTNormFunc(self, ctx: MathExprParser.TNormFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#SNormFunc. - def visitSNormFunc(self, ctx:MathExprParser.SNormFuncContext): + def visitSNormFunc(self, ctx: MathExprParser.SNormFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#FloorFunc. - def visitFloorFunc(self, ctx:MathExprParser.FloorFuncContext): + def visitFloorFunc(self, ctx: MathExprParser.FloorFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#CeilFunc. - def visitCeilFunc(self, ctx:MathExprParser.CeilFuncContext): + def visitCeilFunc(self, ctx: MathExprParser.CeilFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#RoundFunc. - def visitRoundFunc(self, ctx:MathExprParser.RoundFuncContext): + def visitRoundFunc(self, ctx: MathExprParser.RoundFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#GammaFunc. - def visitGammaFunc(self, ctx:MathExprParser.GammaFuncContext): + def visitGammaFunc(self, ctx: MathExprParser.GammaFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#sigmoidFunc. - def visitSigmoidFunc(self, ctx:MathExprParser.SigmoidFuncContext): + def visitSigmoidFunc(self, ctx: MathExprParser.SigmoidFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#sfftFunc. - def visitSfftFunc(self, ctx:MathExprParser.SfftFuncContext): + def visitSfftFunc(self, ctx: MathExprParser.SfftFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#sifftFunc. - def visitSifftFunc(self, ctx:MathExprParser.SifftFuncContext): + def visitSifftFunc(self, ctx: MathExprParser.SifftFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#anglFunc. - def visitAnglFunc(self, ctx:MathExprParser.AnglFuncContext): + def visitAnglFunc(self, ctx: MathExprParser.AnglFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#printFunc. - def visitPrintFunc(self, ctx:MathExprParser.PrintFuncContext): + def visitPrintFunc(self, ctx: MathExprParser.PrintFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#FractFunc. - def visitFractFunc(self, ctx:MathExprParser.FractFuncContext): + def visitFractFunc(self, ctx: MathExprParser.FractFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#ReluFunc. - def visitReluFunc(self, ctx:MathExprParser.ReluFuncContext): + def visitReluFunc(self, ctx: MathExprParser.ReluFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#SoftplusFunc. - def visitSoftplusFunc(self, ctx:MathExprParser.SoftplusFuncContext): + def visitSoftplusFunc(self, ctx: MathExprParser.SoftplusFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#GeluFunc. - def visitGeluFunc(self, ctx:MathExprParser.GeluFuncContext): + def visitGeluFunc(self, ctx: MathExprParser.GeluFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#SignFunc. - def visitSignFunc(self, ctx:MathExprParser.SignFuncContext): + def visitSignFunc(self, ctx: MathExprParser.SignFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#PrintShapeFunc. - def visitPrintShapeFunc(self, ctx:MathExprParser.PrintShapeFuncContext): + def visitPrintShapeFunc(self, ctx: MathExprParser.PrintShapeFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#PowFunc. - def visitPowFunc(self, ctx:MathExprParser.PowFuncContext): + def visitPowFunc(self, ctx: MathExprParser.PowFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#Atan2Func. - def visitAtan2Func(self, ctx:MathExprParser.Atan2FuncContext): + def visitAtan2Func(self, ctx: MathExprParser.Atan2FuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#TMinFunc. - def visitTMinFunc(self, ctx:MathExprParser.TMinFuncContext): + def visitTMinFunc(self, ctx: MathExprParser.TMinFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#TMaxFunc. - def visitTMaxFunc(self, ctx:MathExprParser.TMaxFuncContext): + def visitTMaxFunc(self, ctx: MathExprParser.TMaxFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#StepFunc. - def visitStepFunc(self, ctx:MathExprParser.StepFuncContext): + def visitStepFunc(self, ctx: MathExprParser.StepFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#ClampFunc. - def visitClampFunc(self, ctx:MathExprParser.ClampFuncContext): + def visitClampFunc(self, ctx: MathExprParser.ClampFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#LerpFunc. - def visitLerpFunc(self, ctx:MathExprParser.LerpFuncContext): + def visitLerpFunc(self, ctx: MathExprParser.LerpFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#SmoothstepFunc. - def visitSmoothstepFunc(self, ctx:MathExprParser.SmoothstepFuncContext): + def visitSmoothstepFunc(self, ctx: MathExprParser.SmoothstepFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#RangeFunc. - def visitRangeFunc(self, ctx:MathExprParser.RangeFuncContext): + def visitRangeFunc(self, ctx: MathExprParser.RangeFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#SwapFunc. - def visitSwapFunc(self, ctx:MathExprParser.SwapFuncContext): + def visitSwapFunc(self, ctx: MathExprParser.SwapFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#SMinFunc. - def visitSMinFunc(self, ctx:MathExprParser.SMinFuncContext): + def visitSMinFunc(self, ctx: MathExprParser.SMinFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#SMaxFunc. - def visitSMaxFunc(self, ctx:MathExprParser.SMaxFuncContext): + def visitSMaxFunc(self, ctx: MathExprParser.SMaxFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#MapFunc. - def visitMapFunc(self, ctx:MathExprParser.MapFuncContext): + def visitMapFunc(self, ctx: MathExprParser.MapFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#ConvFunc. - def visitConvFunc(self, ctx:MathExprParser.ConvFuncContext): + def visitConvFunc(self, ctx: MathExprParser.ConvFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#PermuteFunc. - def visitPermuteFunc(self, ctx:MathExprParser.PermuteFuncContext): + def visitPermuteFunc(self, ctx: MathExprParser.PermuteFuncContext): return self.visitChildren(ctx) - # Visit a parse tree produced by MathExprParser#ReshapeFunc. - def visitReshapeFunc(self, ctx:MathExprParser.ReshapeFuncContext): + def visitReshapeFunc(self, ctx: MathExprParser.ReshapeFuncContext): return self.visitChildren(ctx) - -del MathExprParser \ No newline at end of file +del MathExprParser diff --git a/more_math/Parser/UnifiedMathVisitor.py b/more_math/Parser/UnifiedMathVisitor.py index 21ec61f..a491a8c 100644 --- a/more_math/Parser/UnifiedMathVisitor.py +++ b/more_math/Parser/UnifiedMathVisitor.py @@ -4,22 +4,28 @@ import torch.nn.functional as F from .MathExprVisitor import MathExprVisitor from ..helper_functions import generate_dim_variables, getIndexTensorAlongDim + class UnifiedMathVisitor(MathExprVisitor): def __init__(self, variables, shape=None, device=None): self.variables = variables self.spatial_variables = variables.copy() self.shape = shape if shape is not None else () if device is None: - self.device = next((v.device for v in variables.values() if isinstance(v, torch.Tensor)), torch.device("cpu")) + self.device = next((v.device for v in variables.values() if isinstance(v, torch.Tensor)), torch.device("cpu")) else: - self.device = device + self.device = device - def _is_tensor(self, val): return isinstance(val, torch.Tensor) - def _is_list(self, val): return isinstance(val, (list, tuple)) + def _is_tensor(self, val): + return isinstance(val, torch.Tensor) + + def _is_list(self, val): + return isinstance(val, (list, tuple)) def _promote_to_tensor(self, val): - if self._is_tensor(val): return val - if self._is_list(val): return torch.tensor(val, device=self.device) + if self._is_tensor(val): + return val + if self._is_list(val): + return torch.tensor(val, device=self.device) return torch.tensor(val, device=self.device) def _bin_op(self, a, b, torch_op, scalar_op): @@ -27,17 +33,20 @@ class UnifiedMathVisitor(MathExprVisitor): Generic binary operation handler. """ # one of them is a list and one is tensor - if self._is_tensor(a) and self._is_list(b): return torch.cat([self._bin_op(a, x, torch_op, scalar_op) for x in b], dim=0) - if self._is_list(a) and self._is_tensor(b): return torch.cat([self._bin_op(x, b, torch_op, scalar_op) for x in a], dim=0) + if self._is_tensor(a) and self._is_list(b): + return torch.cat([self._bin_op(a, x, torch_op, scalar_op) for x in b], dim=0) + if self._is_list(a) and self._is_tensor(b): + return torch.cat([self._bin_op(x, b, torch_op, scalar_op) for x in a], dim=0) if self._is_list(a) and not self._is_tensor(b): if self._is_list(b): - if len(a) != len(b): raise ValueError("List length mismatch") + if len(a) != len(b): + raise ValueError("List length mismatch") return [self._bin_op(x, y, torch_op, scalar_op) for x, y in zip(a, b)] return [self._bin_op(x, b, torch_op, scalar_op) for x in a] if not self._is_tensor(a) and self._is_list(b): - return [self._bin_op(a, x, torch_op, scalar_op) for x in b] + return [self._bin_op(a, x, torch_op, scalar_op) for x in b] if self._is_tensor(a) or self._is_tensor(b): if torch_op: @@ -59,14 +68,16 @@ class UnifiedMathVisitor(MathExprVisitor): def visitNumberExp(self, ctx): val_str = ctx.getText() - if '.' in val_str or 'e' in val_str: + if "." in val_str or "e" in val_str: return float(val_str) return int(val_str) def visitConstantExp(self, ctx): name = ctx.getText().lower() - if name == "pi": return math.pi - if name == "e": return math.e + if name == "pi": + return math.pi + if name == "e": + return math.e raise ValueError(f"Unknown constant: {name}") def visitVariableExp(self, ctx): @@ -89,39 +100,43 @@ class UnifiedMathVisitor(MathExprVisitor): # Binary Ops def visitAddExp(self, ctx): - return self._bin_op(self.visit(ctx.addExpr()), self.visit(ctx.mulExpr()), - torch.add, lambda a,b: a+b) + return self._bin_op(self.visit(ctx.addExpr()), self.visit(ctx.mulExpr()), torch.add, lambda a, b: a + b) def visitSubExp(self, ctx): - return self._bin_op(self.visit(ctx.addExpr()), self.visit(ctx.mulExpr()), - torch.sub, lambda a,b: a-b) + return self._bin_op(self.visit(ctx.addExpr()), self.visit(ctx.mulExpr()), torch.sub, lambda a, b: a - b) def visitMulExp(self, ctx): - return self._bin_op(self.visit(ctx.mulExpr()), self.visit(ctx.powExpr()), - torch.mul, lambda a,b: a*b) + return self._bin_op(self.visit(ctx.mulExpr()), self.visit(ctx.powExpr()), torch.mul, lambda a, b: a * b) def visitDivExp(self, ctx): - return self._bin_op(self.visit(ctx.mulExpr()), self.visit(ctx.powExpr()), - torch.div, lambda a,b: a/b) + return self._bin_op(self.visit(ctx.mulExpr()), self.visit(ctx.powExpr()), torch.div, lambda a, b: a / b) def visitModExp(self, ctx): - return self._bin_op(self.visit(ctx.mulExpr()), self.visit(ctx.powExpr()), - torch.fmod, lambda a,b: a%b) + return self._bin_op(self.visit(ctx.mulExpr()), self.visit(ctx.powExpr()), torch.fmod, lambda a, b: a % b) def visitPowExp(self, ctx): - return self._bin_op(self.visit(ctx.unaryExpr()), self.visit(ctx.powExpr()), - torch.pow, math.pow) - + return self._bin_op(self.visit(ctx.unaryExpr()), self.visit(ctx.powExpr()), torch.pow, math.pow) def _bool_op(self, a, b, torch_op, scalar_op): return self._bin_op(a, b, torch_op, scalar_op) - def visitNeExp(self, ctx): return self._bool_op(self.visit(ctx.compExpr()), self.visit(ctx.addExpr()), torch.ne, lambda a,b: float(a!=b)) - def visitEqExp(self, ctx): return self._bool_op(self.visit(ctx.compExpr()), self.visit(ctx.addExpr()), torch.eq, lambda a,b: float(a==b)) - def visitGtExp(self, ctx): return self._bool_op(self.visit(ctx.compExpr()), self.visit(ctx.addExpr()), torch.gt, lambda a,b: float(a>b)) - def visitLtExp(self, ctx): return self._bool_op(self.visit(ctx.compExpr()), self.visit(ctx.addExpr()), torch.lt, lambda a,b: float(a=b)) - def visitLeExp(self, ctx): return self._bool_op(self.visit(ctx.compExpr()), self.visit(ctx.addExpr()), torch.le, lambda a,b: float(a<=b)) + def visitNeExp(self, ctx): + return self._bool_op(self.visit(ctx.compExpr()), self.visit(ctx.addExpr()), torch.ne, lambda a, b: float(a != b)) + + def visitEqExp(self, ctx): + return self._bool_op(self.visit(ctx.compExpr()), self.visit(ctx.addExpr()), torch.eq, lambda a, b: float(a == b)) + + def visitGtExp(self, ctx): + return self._bool_op(self.visit(ctx.compExpr()), self.visit(ctx.addExpr()), torch.gt, lambda a, b: float(a > b)) + + def visitLtExp(self, ctx): + return self._bool_op(self.visit(ctx.compExpr()), self.visit(ctx.addExpr()), torch.lt, lambda a, b: float(a < b)) + + def visitGeExp(self, ctx): + return self._bool_op(self.visit(ctx.compExpr()), self.visit(ctx.addExpr()), torch.ge, lambda a, b: float(a >= b)) + + def visitLeExp(self, ctx): + return self._bool_op(self.visit(ctx.compExpr()), self.visit(ctx.addExpr()), torch.le, lambda a, b: float(a <= b)) # Functions def _func_dispatch(self, arg, torch_fn, scalar_fn): @@ -131,55 +146,107 @@ class UnifiedMathVisitor(MathExprVisitor): return torch_fn(arg) return scalar_fn(arg) - def visitSinFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), torch.sin, math.sin) - def visitCosFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), torch.cos, math.cos) - def visitTanFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), torch.tan, math.tan) - def visitAsinFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), torch.asin, math.asin) - def visitAcosFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), torch.acos, math.acos) - def visitAtanFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), torch.atan, math.atan) - def visitSinhFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), torch.sinh, math.sinh) - def visitCoshFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), torch.cosh, math.cosh) - def visitTanhFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), torch.tanh, math.tanh) - def visitAsinhFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), torch.asinh, math.asinh) - def visitAcoshFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), torch.acosh, math.acosh) - def visitAtanhFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), torch.atanh, math.atanh) + def visitSinFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), torch.sin, math.sin) + + def visitCosFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), torch.cos, math.cos) + + def visitTanFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), torch.tan, math.tan) + + def visitAsinFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), torch.asin, math.asin) + + def visitAcosFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), torch.acos, math.acos) + + def visitAtanFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), torch.atan, math.atan) + + def visitSinhFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), torch.sinh, math.sinh) + + def visitCoshFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), torch.cosh, math.cosh) + + def visitTanhFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), torch.tanh, math.tanh) + + def visitAsinhFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), torch.asinh, math.asinh) + + def visitAcoshFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), torch.acosh, math.acosh) + + def visitAtanhFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), torch.atanh, math.atanh) + + def visitAbsFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), torch.abs, abs) - def visitAbsFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), torch.abs, abs) def visitAbsExp(self, ctx): val = self.visit(ctx.expr()) - if self._is_list(val): return torch.linalg.norm(self._promote_to_tensor(val)) - if self._is_tensor(val): return torch.linalg.norm(val) + if self._is_list(val): + return torch.linalg.norm(self._promote_to_tensor(val)) + if self._is_tensor(val): + return torch.linalg.norm(val) return abs(val) - def visitSqrtFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), torch.sqrt, math.sqrt) - def visitLnFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), torch.log, math.log) - def visitLogFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), torch.log10, math.log10) - def visitExpFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), torch.exp, math.exp) + def visitSqrtFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), torch.sqrt, math.sqrt) - def visitFloorFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), torch.floor, math.floor) - def visitCeilFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), torch.ceil, math.ceil) - def visitRoundFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), torch.round, round) + def visitLnFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), torch.log, math.log) - def visitSignFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), torch.sign, lambda x: math.copysign(1.0, x)) + def visitLogFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), torch.log10, math.log10) + + def visitExpFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), torch.exp, math.exp) + + def visitFloorFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), torch.floor, math.floor) + + def visitCeilFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), torch.ceil, math.ceil) + + def visitRoundFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), torch.round, round) + + def visitSignFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), torch.sign, lambda x: math.copysign(1.0, x)) def visitFractFunc(self, ctx): val = self.visit(ctx.expr()) - if self._is_list(val): return [x - math.floor(x) for x in val] - if self._is_tensor(val): return val - torch.floor(val) + if self._is_list(val): + return [x - math.floor(x) for x in val] + if self._is_tensor(val): + return val - torch.floor(val) return val - math.floor(val) def visitGammaFunc(self, ctx): - torch_gamma = getattr(torch.special, 'gamma', None) + torch_gamma = getattr(torch.special, "gamma", None) if torch_gamma is None: torch_gamma = lambda x: torch.exp(torch.lgamma(x)) return self._func_dispatch(self.visit(ctx.expr()), torch_gamma, math.gamma) - def visitSigmoidFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), torch.sigmoid, lambda x: 1.0 / (1.0 + math.exp(-x))) - def visitReluFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), torch.relu, lambda x: max(0.0, x)) - def visitSoftplusFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), F.softplus, lambda x: math.log(1.0 + math.exp(x))) - def visitGeluFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), F.gelu, lambda x: 0.5 * x * (1 + math.tanh(math.sqrt(2 / math.pi) * (x + 0.044715 * math.pow(x, 3))))) + def visitSigmoidFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), torch.sigmoid, lambda x: 1.0 / (1.0 + math.exp(-x))) - def visitAnglFunc(self, ctx): return self._func_dispatch(self.visit(ctx.expr()), torch.angle, lambda x: math.atan2(0, x) if x < 0 else 0) + def visitReluFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), torch.relu, lambda x: max(0.0, x)) + + def visitSoftplusFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), F.softplus, lambda x: math.log(1.0 + math.exp(x))) + + def visitGeluFunc(self, ctx): + return self._func_dispatch( + self.visit(ctx.expr()), F.gelu, lambda x: 0.5 * x * (1 + math.tanh(math.sqrt(2 / math.pi) * (x + 0.044715 * math.pow(x, 3)))) + ) + + def visitAnglFunc(self, ctx): + return self._func_dispatch(self.visit(ctx.expr()), torch.angle, lambda x: math.atan2(0, x) if x < 0 else 0) def visitPrintFunc(self, ctx): val = self.visit(ctx.expr()) @@ -188,25 +255,37 @@ class UnifiedMathVisitor(MathExprVisitor): def visitTNormFunc(self, ctx): val = self.visit(ctx.expr()) - if self._is_tensor(val): return F.normalize(val, p=2, dim=-1) + if self._is_tensor(val): + return F.normalize(val, p=2, dim=-1) return 1.0 if val != 0 else 0.0 def visitSNormFunc(self, ctx): val = self.visit(ctx.expr()) - if self._is_tensor(val): return torch.linalg.norm(val) + if self._is_tensor(val): + return torch.linalg.norm(val) return abs(val) # Two-argument functions - def visitPowFunc(self, ctx): return self._bin_op(self.visit(ctx.expr(0)), self.visit(ctx.expr(1)), torch.pow, math.pow) - def visitAtan2Func(self, ctx): return self._bin_op(self.visit(ctx.expr(0)), self.visit(ctx.expr(1)), torch.atan2, math.atan2) - def visitTMinFunc(self, ctx): return self._bin_op(self.visit(ctx.expr(0)), self.visit(ctx.expr(1)), torch.minimum, min) - def visitTMaxFunc(self, ctx): return self._bin_op(self.visit(ctx.expr(0)), self.visit(ctx.expr(1)), torch.maximum, max) + def visitPowFunc(self, ctx): + return self._bin_op(self.visit(ctx.expr(0)), self.visit(ctx.expr(1)), torch.pow, math.pow) + + def visitAtan2Func(self, ctx): + return self._bin_op(self.visit(ctx.expr(0)), self.visit(ctx.expr(1)), torch.atan2, math.atan2) + + def visitTMinFunc(self, ctx): + return self._bin_op(self.visit(ctx.expr(0)), self.visit(ctx.expr(1)), torch.minimum, min) + + def visitTMaxFunc(self, ctx): + return self._bin_op(self.visit(ctx.expr(0)), self.visit(ctx.expr(1)), torch.maximum, max) def visitStepFunc(self, ctx): # step(x, edge) = 1 if x >= edge else 0 - return self._bin_op(self.visit(ctx.expr(0)), self.visit(ctx.expr(1)), - lambda x, edge: torch.where(x >= edge, 1.0, 0.0), - lambda x, edge: 1.0 if x >= edge else 0.0) + return self._bin_op( + self.visit(ctx.expr(0)), + self.visit(ctx.expr(1)), + lambda x, edge: torch.where(x >= edge, 1.0, 0.0), + lambda x, edge: 1.0 if x >= edge else 0.0, + ) # Three-argument functions def visitClampFunc(self, ctx): @@ -217,7 +296,7 @@ class UnifiedMathVisitor(MathExprVisitor): if any(self._is_tensor(x) for x in [val, min_v, max_v]): return torch.clamp(self._promote_to_tensor(val), self._promote_to_tensor(min_v), self._promote_to_tensor(max_v)) if self._is_list(val): - return [max(min(x, max_v), min_v) for x in val] #TODO: what if min_v or max_v is list + return [max(min(x, max_v), min_v) for x in val] # TODO: what if min_v or max_v is list return max(min(val, max_v), min_v) def visitLerpFunc(self, ctx): @@ -249,11 +328,20 @@ class UnifiedMathVisitor(MathExprVisitor): return list(torch.arange(self.visit(ctx.expr(0)), self.visit(ctx.expr(1)), self.visit(ctx.expr(2)))) # Helpers for visiting generic exprs - def visitFunc1Exp(self, ctx): return self.visitChildren(ctx) - def visitFunc2Exp(self, ctx): return self.visitChildren(ctx) - def visitFuncNExp(self, ctx): return self.visitChildren(ctx) - def visitAtomExp(self, ctx): return self.visitChildren(ctx) - def visitExpr(self, ctx): return self.visitChildren(ctx) + def visitFunc1Exp(self, ctx): + return self.visitChildren(ctx) + + def visitFunc2Exp(self, ctx): + return self.visitChildren(ctx) + + def visitFuncNExp(self, ctx): + return self.visitChildren(ctx) + + def visitAtomExp(self, ctx): + return self.visitChildren(ctx) + + def visitExpr(self, ctx): + return self.visitChildren(ctx) def visitSMinFunc(self, ctx): vals = [self.visit(e) for e in ctx.expr()] @@ -262,15 +350,18 @@ class UnifiedMathVisitor(MathExprVisitor): return min(vals) promoted = [self._promote_to_tensor(x) for x in vals] - if len(promoted) == 1: return torch.min(promoted[0]) + if len(promoted) == 1: + return torch.min(promoted[0]) return torch.min(torch.stack(torch.broadcast_tensors(*promoted))) def visitSMaxFunc(self, ctx): args = [self.visit(e) for e in ctx.expr()] if len(args) == 1: # Check if list or scalar - if not self._is_tensor(args[0]) and not self._is_list(args[0]): return args[0] - if self._is_list(args[0]): return max(args[0]) # max of list + if not self._is_tensor(args[0]) and not self._is_list(args[0]): + return args[0] + if self._is_list(args[0]): + return max(args[0]) # max of list return torch.max(args[0]) # Global max of single tensor # Multiple args @@ -278,7 +369,8 @@ class UnifiedMathVisitor(MathExprVisitor): return max(args) promoted = [self._promote_to_tensor(x) for x in args] - if len(promoted) == 1: return torch.max(promoted[0]) + if len(promoted) == 1: + return torch.max(promoted[0]) return torch.max(torch.stack(torch.broadcast_tensors(*promoted))) def _fold_nd(self, tsr, spatial_dims): @@ -294,10 +386,10 @@ class UnifiedMathVisitor(MathExprVisitor): new_batch = 1 for i in range(fold_count + 1): new_batch *= tsr.shape[i] - tsr = tsr.reshape(new_batch, *tsr.shape[fold_count+1:]) + tsr = tsr.reshape(new_batch, *tsr.shape[fold_count + 1 :]) folded = True else: - folded = (added_dims > 0) + folded = added_dims > 0 return tsr, original_shape, added_dims, folded def _unfold_nd(self, tsr, original_shape, added_dims, folded): @@ -315,20 +407,22 @@ class UnifiedMathVisitor(MathExprVisitor): tsr = self._promote_to_tensor(self.visit(ctx.expr(0))) dims = self.visit(ctx.expr(1)) if isinstance(dims, torch.Tensor): - dims = dims.flatten().long().tolist() + dims = dims.flatten().long().tolist() return tsr.permute(*dims) def visitReshapeFunc(self, ctx): tsr = self._promote_to_tensor(self.visit(ctx.expr(0))) new_shape = self.visit(ctx.expr(1)) if isinstance(new_shape, torch.Tensor): - new_shape = new_shape.flatten().long().tolist() + new_shape = new_shape.flatten().long().tolist() return tsr.reshape(*new_shape) def visitPrintShapeFunc(self, ctx): tsr = self.visit(ctx.expr()) - if hasattr(tsr, 'shape'): print(tsr.shape) - else: print(f"Scalar/List: {tsr}") + if hasattr(tsr, "shape"): + print(tsr.shape) + else: + print(f"Scalar/List: {tsr}") return tsr def visitSfftFunc(self, ctx): @@ -346,10 +440,10 @@ class UnifiedMathVisitor(MathExprVisitor): self.variables = self.variables.copy() device = self.device - shape_to_use = self.shape if self.shape else (1,1,1,1) + shape_to_use = self.shape if self.shape else (1, 1, 1, 1) ndim = len(shape_to_use) - dim_names = ['x', 'y', 'z', 'w', 'v', 'u'] + dim_names = ["x", "y", "z", "w", "v", "u"] k_components = [] for i in range(ndim): @@ -361,23 +455,23 @@ class UnifiedMathVisitor(MathExprVisitor): values = values.view(*view_shape).expand(*shape_to_use) if i < len(dim_names): - var_name = f'K{dim_names[i]}' + var_name = f"K{dim_names[i]}" self.variables[var_name] = values - self.variables[f'F{dim_names[i]}'] = float(size_d) + self.variables[f"F{dim_names[i]}"] = float(size_d) - self.variables[f'K_dim{dim_idx}'] = values - self.variables[f'F_dim{dim_idx}'] = float(size_d) + self.variables[f"K_dim{dim_idx}"] = values + self.variables[f"F_dim{dim_idx}"] = float(size_d) k_components.append(values) k_sq_sum = torch.zeros(shape_to_use, device=device) for k_val in k_components: - k_sq_sum = k_sq_sum + k_val ** 2 + k_sq_sum = k_sq_sum + k_val**2 - self.variables['K'] = torch.sqrt(k_sq_sum) - self.variables['frequency'] = self.variables['K'] + self.variables["K"] = torch.sqrt(k_sq_sum) + self.variables["frequency"] = self.variables["K"] - if 'Kx' in self.variables: - self.variables['frequency_count'] = self.variables.get('Fx', 1.0) + if "Kx" in self.variables: + self.variables["frequency_count"] = self.variables.get("Fx", 1.0) self.variables = self.variables | generate_dim_variables(k_sq_sum) @@ -398,9 +492,12 @@ class UnifiedMathVisitor(MathExprVisitor): i = int(idx1_t.flatten()[0].item()) if isinstance(idx1_t, torch.Tensor) else int(idx1_t) j = int(idx2_t.flatten()[0].item()) if isinstance(idx2_t, torch.Tensor) else int(idx2_t) - while dim < 0: dim += tsr.ndim - while i < 0: i += tsr.shape[dim] - while j < 0: j += tsr.shape[dim] + while dim < 0: + dim += tsr.ndim + while i < 0: + i += tsr.shape[dim] + while j < 0: + j += tsr.shape[dim] indices = torch.arange(tsr.shape[dim], device=tsr.device) val_i = indices[i].clone() @@ -410,7 +507,8 @@ class UnifiedMathVisitor(MathExprVisitor): return torch.index_select(tsr, dim, indices) def _normalize_coord(self, coord, size): - if size > 1: return (coord / (size - 1)) * 2.0 - 1.0 + if size > 1: + return (coord / (size - 1)) * 2.0 - 1.0 return torch.zeros_like(coord) def visitMapFunc(self, ctx): @@ -418,14 +516,17 @@ class UnifiedMathVisitor(MathExprVisitor): coords = [self._promote_to_tensor(self.visit(ctx.expr(i))) for i in range(1, len(ctx.expr()))] num_coords = len(coords) - if num_coords == 0: return tensor - if num_coords > 3: raise ValueError("map() supports max 3 mapping functions.") + if num_coords == 0: + return tensor + if num_coords > 3: + raise ValueError("map() supports max 3 mapping functions.") spatial_in_shape = tensor.shape[-num_coords:] leading_shape = tensor.shape[:-num_coords] batch_size = 1 - for s in leading_shape: batch_size *= s + for s in leading_shape: + batch_size *= s input_view = tensor.reshape(batch_size, 1, *spatial_in_shape) norm_coords_list = [] @@ -441,14 +542,15 @@ class UnifiedMathVisitor(MathExprVisitor): grid_view = grid.reshape(batch_size, *grid_spatial_shape[-(num_coords):], num_coords) except RuntimeError: grid_view = grid.expand(batch_size, *([-1] * len(grid_spatial_shape)), -1) - grid_view = grid_view.reshape(batch_size, *grid_view.shape[-(num_coords+1):-1], num_coords) + grid_view = grid_view.reshape(batch_size, *grid_view.shape[-(num_coords + 1) : -1], num_coords) if num_coords == 1: input_final = input_view.reshape(batch_size, 1, 1, -1) gv = grid_view - while gv.ndim < 3: gv = gv.unsqueeze(1) + while gv.ndim < 3: + gv = gv.unsqueeze(1) y_zeros = torch.zeros_like(gv[..., :1]) - grid_final = torch.cat([gv, y_zeros], dim=-1).unsqueeze(1) # [B, 1, 1, 2] + grid_final = torch.cat([gv, y_zeros], dim=-1).unsqueeze(1) # [B, 1, 1, 2] output = F.grid_sample(input_final, grid_final, align_corners=True) elif num_coords == 2: grid_final = grid_view.reshape(batch_size, *grid_view.shape[-3:-1], 2) @@ -476,18 +578,18 @@ class UnifiedMathVisitor(MathExprVisitor): p_high = p_total - p_low pads.extend([p_low, p_high]) - padded_input = torch.nn.functional.pad(conv_input, tuple(pads), mode='constant', value=0) + padded_input = torch.nn.functional.pad(conv_input, tuple(pads), mode="constant", value=0) actual_kernel_sizes = kernel_sizes[::-1] if kernel_val.numel() == 1: kernel_val = kernel_val.expand(tuple(actual_kernel_sizes)) elif kernel_val.ndim != spatial_dims_count: - kernel_val = kernel_val.reshape(tuple(actual_kernel_sizes)) + kernel_val = kernel_val.reshape(tuple(actual_kernel_sizes)) final_kernel = kernel_val.unsqueeze(0).unsqueeze(0) final_kernel = final_kernel.to(conv_input.dtype) - final_kernel = final_kernel.repeat(in_channels, 1, *([1]*spatial_dims_count)) + final_kernel = final_kernel.repeat(in_channels, 1, *([1] * spatial_dims_count)) conv_fn = F.conv1d if spatial_dims_count == 1 else (F.conv2d if spatial_dims_count == 2 else F.conv3d) @@ -499,33 +601,35 @@ class UnifiedMathVisitor(MathExprVisitor): tensor = self._promote_to_tensor(input_raw) input_ndim = tensor.ndim num_args = len(ctx.expr()) - if num_args < 3: raise ValueError("conv() requires at least 3 arguments") + if num_args < 3: + raise ValueError("conv() requires at least 3 arguments") kernel_arg_idx = num_args - 1 spatial_dims_count = num_args - 2 if spatial_dims_count not in [1, 2, 3]: - raise ValueError(f"conv() supports 1D, 2D, or 3D. Found {spatial_dims_count}") + raise ValueError(f"conv() supports 1D, 2D, or 3D. Found {spatial_dims_count}") kernel_sizes = [] for i in range(1, 1 + spatial_dims_count): val = self.visit(ctx.expr(i)) - if isinstance(val, torch.Tensor): val = int(val.flatten()[0].item()) + if isinstance(val, torch.Tensor): + val = int(val.flatten()[0].item()) kernel_sizes.append(val) # Prepare context for kernel - coords = [torch.arange(s, device=self.device).float() - (s//2) for s in kernel_sizes] - grid = torch.meshgrid(*coords, indexing='ij') + coords = [torch.arange(s, device=self.device).float() - (s // 2) for s in kernel_sizes] + grid = torch.meshgrid(*coords, indexing="ij") - dim_names = ['x','y','z'] + dim_names = ["x", "y", "z"] old_vars = self.variables self.variables = self.variables.copy() for i in range(spatial_dims_count): - self.variables[f'k{dim_names[i].lower()}'] = grid[i] - self.variables[f'k{dim_names[i].upper()}'] = grid[i] + self.variables[f"k{dim_names[i].lower()}"] = grid[i] + self.variables[f"k{dim_names[i].upper()}"] = grid[i] - kernel_var_names = ['kW', 'kH', 'kD'] - kernel_var_full = ['kernel_width', 'kernel_height', 'kernel_depth'] + kernel_var_names = ["kW", "kH", "kD"] + kernel_var_full = ["kernel_width", "kernel_height", "kernel_depth"] for i in range(spatial_dims_count): size_val = float(kernel_sizes[i]) self.variables[kernel_var_names[i]] = size_val @@ -543,27 +647,29 @@ class UnifiedMathVisitor(MathExprVisitor): is_channels_first = False if tensor.ndim == spatial_dims_count + 2: c_front = tensor.shape[1] - c_back = tensor.shape[-1] + c_back = tensor.shape[-1] if c_front <= 4 and c_front < c_back: is_channels_first = True elif c_back <= 4 and c_back < c_front: is_channels_first = False else: - is_channels_first = (c_back > 4) + is_channels_first = c_back > 4 if is_channels_first: if spatial_dims_count == 1 and tensor.ndim == 3: - tensor = tensor.permute(0, 2, 1) + tensor = tensor.permute(0, 2, 1) elif spatial_dims_count == 2 and tensor.ndim == 4: - tensor = tensor.permute(0, 2, 3, 1) + tensor = tensor.permute(0, 2, 3, 1) elif spatial_dims_count == 3: - if tensor.ndim == 4: tensor = tensor.unsqueeze(-1) - elif tensor.ndim == 5: tensor = tensor.permute(0, 2, 3, 4, 1) + if tensor.ndim == 4: + tensor = tensor.unsqueeze(-1) + elif tensor.ndim == 5: + tensor = tensor.permute(0, 2, 3, 4, 1) if tensor.ndim == spatial_dims_count + 1: - tensor = tensor.unsqueeze(-1) # Add C=1 + tensor = tensor.unsqueeze(-1) # Add C=1 elif tensor.ndim == spatial_dims_count: - tensor = tensor.unsqueeze(0).unsqueeze(-1) # Add B=1, C=1 + tensor = tensor.unsqueeze(0).unsqueeze(-1) # Add B=1, C=1 in_channels = tensor.size(-1) batch_end_idx = tensor.ndim - 1 - spatial_dims_count @@ -572,7 +678,8 @@ class UnifiedMathVisitor(MathExprVisitor): channels_shape = (tensor.shape[-1],) total_batch = 1 - for s in batch_shape: total_batch *= s + for s in batch_shape: + total_batch *= s flat_input = tensor.reshape(total_batch, *spatial_shape, in_channels) permute_order = [0, spatial_dims_count + 1] + list(range(1, spatial_dims_count + 1)) @@ -580,22 +687,21 @@ class UnifiedMathVisitor(MathExprVisitor): result = self._apply_conv_internal(conv_input, kernel_val, kernel_sizes, spatial_dims_count) - result_permute = [0] + list(range(2, 2+spatial_dims_count)) + [1] + result_permute = [0] + list(range(2, 2 + spatial_dims_count)) + [1] out_flat = result.permute(*result_permute) final_shape = batch_shape + spatial_shape + channels_shape out = out_flat.reshape(final_shape) if is_channels_first: - if spatial_dims_count == 1 and out.ndim == 3: - out = out.permute(0, 2, 1) - elif spatial_dims_count == 2 and out.ndim == 4: - out = out.permute(0, 3, 1, 2) - elif spatial_dims_count == 3: - if out.ndim == 5 and out.shape[-1] == 1 and input_ndim == 4: - out = out.squeeze(-1) - elif out.ndim == 5: - out = out.permute(0, 4, 1, 2, 3) + if spatial_dims_count == 1 and out.ndim == 3: + out = out.permute(0, 2, 1) + elif spatial_dims_count == 2 and out.ndim == 4: + out = out.permute(0, 3, 1, 2) + elif spatial_dims_count == 3: + if out.ndim == 5 and out.shape[-1] == 1 and input_ndim == 4: + out = out.squeeze(-1) + elif out.ndim == 5: + out = out.permute(0, 4, 1, 2, 3) return out - diff --git a/more_math/SpectrogramToAudioNode.py b/more_math/SpectrogramToAudioNode.py index c94d427..ce18886 100644 --- a/more_math/SpectrogramToAudioNode.py +++ b/more_math/SpectrogramToAudioNode.py @@ -1,13 +1,15 @@ import torch from comfy_api.latest import io -windows = {'bartlet':torch.bartlett_window, 'blackman':torch.blackman_window, 'hamming':torch.hamming_window,'hann':torch.hann_window} +windows = {"bartlet": torch.bartlett_window, "blackman": torch.blackman_window, "hamming": torch.hamming_window, "hann": torch.hann_window} + class SpectrogramToAudio(io.ComfyNode): """ Converts an Image spectrogram back to Audio. Red is real part and blue is imaginary. Green is ignored. """ + @classmethod def define_schema(cls) -> io.Schema: return io.Schema( @@ -21,7 +23,6 @@ class SpectrogramToAudio(io.ComfyNode): io.Int.Input(id="window_length", default=1024, min=16, tooltip="Window length in samples"), io.Int.Input(id="hop_length", default=256, min=1, tooltip="Stride of the window (hop length) in samples"), io.Combo.Input(id="window_type", default="hann", options=list(windows.keys()), tooltip="Type of window function to apply"), - ], outputs=[ io.Audio.Output(id="audio", tooltip="Output audio"), @@ -29,19 +30,24 @@ class SpectrogramToAudio(io.ComfyNode): ) @classmethod - def execute(cls, image, channel_count, sample_rate, window_length, hop_length,window_type): + def execute(cls, image, channel_count, sample_rate, window_length, hop_length, window_type): B, H, W, _ = image.shape bucket_count = H // channel_count n_fft = (bucket_count - 1) * 2 real = image[..., 0].reshape(B * channel_count, bucket_count, W) imag = image[..., 2].reshape(B * channel_count, bucket_count, W) stft_complex = torch.complex(real, imag) - window = windows[window_type](window_length,device = image.device) + window = windows[window_type](window_length, device=image.device) waveform = torch.istft( - stft_complex, n_fft=n_fft, hop_length=hop_length, win_length=window_length, - window=window, center=True, normalized=False, onesided=True + stft_complex, + n_fft=n_fft, + hop_length=hop_length, + win_length=window_length, + window=window, + center=True, + normalized=False, + onesided=True, ) waveform = waveform.reshape(B, channel_count, -1) return ({"waveform": waveform, "sample_rate": sample_rate},) - diff --git a/more_math/VaeMathNode.py b/more_math/VaeMathNode.py index eaa5808..a84670d 100644 --- a/more_math/VaeMathNode.py +++ b/more_math/VaeMathNode.py @@ -4,10 +4,12 @@ import copy from .modelLikeCommon import calculate_patches from .helper_functions import comonLazy + class VAEMathNode(io.ComfyNode): """ This node enables the use of math expressions on VAE weights. """ + @classmethod def define_schema(cls) -> io.Schema: return io.Schema( @@ -16,13 +18,13 @@ class VAEMathNode(io.ComfyNode): category="More math", inputs=[ io.Vae.Input(id="a", tooltip="Main VAE (base)"), - io.Vae.Input(id="b", optional=True,lazy=True, tooltip="Optional 2nd VAE"), - io.Vae.Input(id="c", optional=True,lazy=True, tooltip="Optional 3rd VAE"), - io.Vae.Input(id="d", optional=True,lazy=True, tooltip="Optional 4th VAE"), - io.Float.Input(id="w", default=0.0,lazy=True, optional=True, force_input=True), - io.Float.Input(id="x", default=0.0,lazy=True, optional=True, force_input=True), - io.Float.Input(id="y", default=0.0,lazy=True, optional=True, force_input=True), - io.Float.Input(id="z", default=0.0,lazy=True, optional=True, force_input=True), + io.Vae.Input(id="b", optional=True, lazy=True, tooltip="Optional 2nd VAE"), + io.Vae.Input(id="c", optional=True, lazy=True, tooltip="Optional 3rd VAE"), + io.Vae.Input(id="d", optional=True, lazy=True, tooltip="Optional 4th VAE"), + io.Float.Input(id="w", default=0.0, lazy=True, optional=True, force_input=True), + io.Float.Input(id="x", default=0.0, lazy=True, optional=True, force_input=True), + io.Float.Input(id="y", default=0.0, lazy=True, optional=True, force_input=True), + io.Float.Input(id="z", default=0.0, lazy=True, optional=True, force_input=True), io.String.Input(id="Model", default="a*(1-w)+b*w", tooltip="Expression to apply on weights"), ], outputs=[ @@ -31,9 +33,11 @@ class VAEMathNode(io.ComfyNode): ) tooltip = cleandoc(__doc__) + @classmethod - def check_lazy_status(cls, Model, a, b=[], c=[], d=[],w=0,x=0,y=0,z=0): - return comonLazy(Model, a, b, c, d,w,x,y,z) + def check_lazy_status(cls, Model, a, b=[], c=[], d=[], w=0, x=0, y=0, z=0): + return comonLazy(Model, a, b, c, d, w, x, y, z) + @classmethod def execute(cls, Model, a, b=None, c=None, d=None, w=0.0, x=0.0, y=0.0, z=0.0) -> io.NodeOutput: patcher_a = a.patcher diff --git a/more_math/VideoMathNode.py b/more_math/VideoMathNode.py index 4a2cc43..1b20986 100644 --- a/more_math/VideoMathNode.py +++ b/more_math/VideoMathNode.py @@ -11,16 +11,17 @@ from .helper_functions import generate_dim_variables, getIndexTensorAlongDim, ev from .MathNodeBase import MathNodeBase + class VideoMathNode(MathNodeBase): """ Enables math expressions on Video (images + audio). - + Inputs: a, b, c, d: Video inputs (b, c, d default to zero if not provided) w, x, y, z: Float variables for expressions Audio: Expression for audio component Images: Expression for image component - + Outputs: VIDEO: Result of applying expressions to input videos """ @@ -53,7 +54,7 @@ class VideoMathNode(MathNodeBase): @classmethod def execute(cls, Audio, Images, a, b=None, c=None, d=None, w=0.0, x=0.0, y=0.0, z=0.0) -> io.NodeOutput: ac = a.get_components() - + bc = b.get_components() if b is not None else make_zero_like(ac) cc = c.get_components() if c is not None else make_zero_like(ac) dc = d.get_components() if d is not None else make_zero_like(ac) @@ -65,45 +66,72 @@ class VideoMathNode(MathNodeBase): imgs_d = dc.images.permute(0, 3, 1, 2) img_vars = { - 'a': imgs_a, 'b': imgs_b, 'c': imgs_c, 'd': imgs_d, - 'w': w, 'x': x, 'y': y, 'z': z, - 'X': getIndexTensorAlongDim(imgs_a, 3), - 'Y': getIndexTensorAlongDim(imgs_a, 2), - 'B': getIndexTensorAlongDim(imgs_a, 0), 'frame': getIndexTensorAlongDim(imgs_a, 0), - 'C': getIndexTensorAlongDim(imgs_a, 1), 'channel': getIndexTensorAlongDim(imgs_a, 1), - 'W': imgs_a.shape[3], 'width': imgs_a.shape[3], - 'H': imgs_a.shape[2], 'height': imgs_a.shape[2], - 'R': float(ac.frame_rate), 'frame_rate': float(ac.frame_rate), - 'T': imgs_a.shape[0], 'frame_count': imgs_a.shape[0], - 'N': imgs_a.shape[1], 'channel_count': imgs_a.shape[1], + "a": imgs_a, + "b": imgs_b, + "c": imgs_c, + "d": imgs_d, + "w": w, + "x": x, + "y": y, + "z": z, + "X": getIndexTensorAlongDim(imgs_a, 3), + "Y": getIndexTensorAlongDim(imgs_a, 2), + "B": getIndexTensorAlongDim(imgs_a, 0), + "frame": getIndexTensorAlongDim(imgs_a, 0), + "C": getIndexTensorAlongDim(imgs_a, 1), + "channel": getIndexTensorAlongDim(imgs_a, 1), + "W": imgs_a.shape[3], + "width": imgs_a.shape[3], + "H": imgs_a.shape[2], + "height": imgs_a.shape[2], + "R": float(ac.frame_rate), + "frame_rate": float(ac.frame_rate), + "T": imgs_a.shape[0], + "frame_count": imgs_a.shape[0], + "N": imgs_a.shape[1], + "channel_count": imgs_a.shape[1], } | generate_dim_variables(imgs_a) result_imgs = eval_tensor_expr(Images, img_vars, imgs_a.shape) result_imgs = result_imgs.permute(0, 2, 3, 1) # Back to B, H, W, C # Process audio - audio_a = ac.audio['waveform'] - audio_b = bc.audio['waveform'] - audio_c = cc.audio['waveform'] - audio_d = dc.audio['waveform'] + audio_a = ac.audio["waveform"] + audio_b = bc.audio["waveform"] + audio_c = cc.audio["waveform"] + audio_d = dc.audio["waveform"] audio_vars = { - 'a': audio_a, 'b': audio_b, 'c': audio_c, 'd': audio_d, - 'w': w, 'x': x, 'y': y, 'z': z, - 'B': getIndexTensorAlongDim(audio_a, 0), 'batch': getIndexTensorAlongDim(audio_a, 0), - 'C': getIndexTensorAlongDim(audio_a, 1), 'channel': getIndexTensorAlongDim(audio_a, 1), - 'S': getIndexTensorAlongDim(audio_a, 2), 'sample': getIndexTensorAlongDim(audio_a, 2), - 'R': ac.audio['sample_rate'], 'sample_rate': ac.audio['sample_rate'], - 'T': audio_a.shape[2], 'sample_count': audio_a.shape[2], - 'N': audio_a.shape[1], 'channel_count': audio_a.shape[1], + "a": audio_a, + "b": audio_b, + "c": audio_c, + "d": audio_d, + "w": w, + "x": x, + "y": y, + "z": z, + "B": getIndexTensorAlongDim(audio_a, 0), + "batch": getIndexTensorAlongDim(audio_a, 0), + "C": getIndexTensorAlongDim(audio_a, 1), + "channel": getIndexTensorAlongDim(audio_a, 1), + "S": getIndexTensorAlongDim(audio_a, 2), + "sample": getIndexTensorAlongDim(audio_a, 2), + "R": ac.audio["sample_rate"], + "sample_rate": ac.audio["sample_rate"], + "T": audio_a.shape[2], + "sample_count": audio_a.shape[2], + "N": audio_a.shape[1], + "channel_count": audio_a.shape[1], } | generate_dim_variables(audio_a) result_audio = eval_tensor_expr(Audio, audio_vars, audio_a.shape) - output = VideoFromComponents(VideoComponents( - images=result_imgs, - audio={'waveform': result_audio, 'sample_rate': ac.audio['sample_rate']}, - frame_rate=ac.frame_rate, - metadata=ac.metadata - )) + output = VideoFromComponents( + VideoComponents( + images=result_imgs, + audio={"waveform": result_audio, "sample_rate": ac.audio["sample_rate"]}, + frame_rate=ac.frame_rate, + metadata=ac.metadata, + ) + ) return (output,) diff --git a/more_math/helper_functions.py b/more_math/helper_functions.py index 48d01e0..86b58e4 100644 --- a/more_math/helper_functions.py +++ b/more_math/helper_functions.py @@ -7,18 +7,20 @@ from .Parser.MathExprLexer import MathExprLexer from .Parser.MathExprParser import MathExprParser - class ThrowingErrorListener(ErrorListener): """Error listener that raises ValueError on syntax errors.""" + def syntaxError(self, recognizer, offendingSymbol, line, column, msg, e): raise ValueError(f"Syntax error in expression at line {line}, col {column}: {msg}") -def as_tensor(value,shape): - if isinstance(value,torch.Tensor): + +def as_tensor(value, shape): + if isinstance(value, torch.Tensor): return value - if isinstance(value,(float,int)): + if isinstance(value, (float, int)): value = (value,) - return torch.broadcast_to(torch.Tensor(value),shape) + return torch.broadcast_to(torch.Tensor(value), shape) + def parse_expr(expr: str): """Parse a math expression and return the parse tree.""" @@ -33,6 +35,7 @@ def parse_expr(expr: str): def eval_tensor_expr(expr: str, variables: dict, shape: tuple, device=None): """Parse and evaluate a tensor math expression.""" from .Parser.UnifiedMathVisitor import UnifiedMathVisitor + tree = parse_expr(expr) visitor = UnifiedMathVisitor(variables, shape, device=device) return visitor.visit(tree) @@ -41,6 +44,7 @@ def eval_tensor_expr(expr: str, variables: dict, shape: tuple, device=None): def eval_tensor_expr_with_tree(tree, variables: dict, shape: tuple, device=None): """Evaluate a pre-parsed expression tree with UnifiedMathVisitor.""" from .Parser.UnifiedMathVisitor import UnifiedMathVisitor + visitor = UnifiedMathVisitor(variables, shape, device=device) return visitor.visit(tree) @@ -48,14 +52,17 @@ def eval_tensor_expr_with_tree(tree, variables: dict, shape: tuple, device=None) def eval_float_expr(expr: str, variables: dict): """Parse and evaluate a float math expression.""" from .Parser.UnifiedMathVisitor import UnifiedMathVisitor + tree = parse_expr(expr) # Float eval context often has no shape. Pass None/Empty. visitor = UnifiedMathVisitor(variables, shape=None) return visitor.visit(tree) + def eval_float_expr_with_tree(tree, variables: dict): """Evaluate a pre-parsed expression tree with UnifiedMathVisitor.""" from .Parser.UnifiedMathVisitor import UnifiedMathVisitor + visitor = UnifiedMathVisitor(variables, shape=None) return visitor.visit(tree) @@ -72,7 +79,7 @@ def getIndexTensorAlongDim(tensor, dim): def comonLazy(expr, a, b=None, c=None, d=None, w=0.0, x=0.0, y=0.0, z=0.0): """Determine which lazy inputs are needed based on expression variables.""" - variables = {'a': a, 'b': b, 'c': c, 'd': d, 'w': w, 'x': x, 'y': y, 'z': z} + variables = {"a": a, "b": b, "c": c, "d": d, "w": w, "x": x, "y": y, "z": z} need_eval = [] input_stream = InputStream(expr) lexer = MathExprLexer(input_stream) @@ -83,14 +90,16 @@ def comonLazy(expr, a, b=None, c=None, d=None, w=0.0, x=0.0, y=0.0, z=0.0): need_eval.append(token.text) return need_eval + def generate_dim_variables(tensor: torch.Tensor): """Generate index and size tensors for each dimension of the input tensor.""" variables = {} for dim, size in enumerate(tensor.shape): - variables[f'D{dim}'] = getIndexTensorAlongDim(tensor, dim) - variables[f'S{dim}'] = torch.full(tensor.shape, fill_value=size, dtype=torch.float32, device=tensor.device) + variables[f"D{dim}"] = getIndexTensorAlongDim(tensor, dim) + variables[f"S{dim}"] = torch.full(tensor.shape, fill_value=size, dtype=torch.float32, device=tensor.device) return variables + def make_zero_like(ref): """ Create a zero-initialized version of the reference object, maintaining its structure. @@ -109,31 +118,23 @@ def make_zero_like(ref): # Ensure it's a tensor-like structure if torch.is_tensor(ref_tensor): ref_pooled = ref[0][1].get("pooled_output") - return [[ - torch.zeros_like(ref_tensor), - {"pooled_output": torch.zeros_like(ref_pooled) if ref_pooled is not None else None} - ]] + return [[torch.zeros_like(ref_tensor), {"pooled_output": torch.zeros_like(ref_pooled) if ref_pooled is not None else None}]] # Audio or Latent: dict if isinstance(ref, dict): - if 'waveform' in ref: # Audio - return { - 'waveform': torch.zeros_like(ref['waveform']), - 'sample_rate': ref['sample_rate'] - } - if 'samples' in ref: # Latent - return { - 'samples': torch.zeros_like(ref['samples']) - } + if "waveform" in ref: # Audio + return {"waveform": torch.zeros_like(ref["waveform"]), "sample_rate": ref["sample_rate"]} + if "samples" in ref: # Latent + return {"samples": torch.zeros_like(ref["samples"])} # VideoComponents or other objects with images/audio attributes - if hasattr(ref, 'images') and hasattr(ref, 'audio'): + if hasattr(ref, "images") and hasattr(ref, "audio"): # Dynamically create same type (e.g. VideoComponents) return type(ref)( images=torch.zeros_like(ref.images), - audio={'waveform': torch.zeros_like(ref.audio['waveform']), 'sample_rate': ref.audio['sample_rate']}, + audio={"waveform": torch.zeros_like(ref.audio["waveform"]), "sample_rate": ref.audio["sample_rate"]}, frame_rate=ref.frame_rate, - metadata=None + metadata=None, ) return None @@ -151,4 +152,4 @@ def freq_to_time(element: torch.Tensor) -> torch.Tensor: if element.ndim < 2: raise ValueError("IFFT requires at least 2 dimensions (Batch, Channel)") dims = tuple(range(2, element.ndim)) - return torch.fft.ifftn(element, dim=dims).real \ No newline at end of file + return torch.fft.ifftn(element, dim=dims).real diff --git a/more_math/modelLikeCommon.py b/more_math/modelLikeCommon.py index f44df75..12ce40a 100644 --- a/more_math/modelLikeCommon.py +++ b/more_math/modelLikeCommon.py @@ -1,7 +1,7 @@ import torch import comfy.utils -from .helper_functions import getIndexTensorAlongDim, parse_expr, eval_tensor_expr_with_tree,as_tensor +from .helper_functions import getIndexTensorAlongDim, parse_expr, eval_tensor_expr_with_tree, as_tensor def calculate_patches(Model, a, b=None, c=None, d=None, w=0.0, x=0.0, y=0.0, z=0.0): @@ -31,19 +31,27 @@ def calculate_patches(Model, a, b=None, c=None, d=None, w=0.0, x=0.0, y=0.0, z=0 # Build variables variables = { - 'a': tens_a, 'b': tens_b, 'c': tens_c, 'd': tens_d, - 'w': w, 'x': x, 'y': y, 'z': z, - 'L': i, 'layer': i, - 'LC': layer_count, 'layer_count': layer_count, + "a": tens_a, + "b": tens_b, + "c": tens_c, + "d": tens_d, + "w": w, + "x": x, + "y": y, + "z": z, + "L": i, + "layer": i, + "LC": layer_count, + "layer_count": layer_count, } # Add dimension index tensors for dim_idx in range(tens_a.ndim): idx_tensor = getIndexTensorAlongDim(tens_a, dim_idx) - variables[f'D{dim_idx}'] = idx_tensor - variables[f'dim_{dim_idx}'] = idx_tensor + variables[f"D{dim_idx}"] = idx_tensor + variables[f"dim_{dim_idx}"] = idx_tensor - result_tensor = as_tensor(eval_tensor_expr_with_tree(tree, variables, tens_a.shape),tens_a.shape) + result_tensor = as_tensor(eval_tensor_expr_with_tree(tree, variables, tens_a.shape), tens_a.shape) # Calculate patch (diff from original) diff = result_tensor - tens_a @@ -54,4 +62,4 @@ def calculate_patches(Model, a, b=None, c=None, d=None, w=0.0, x=0.0, y=0.0, z=0 pbar.update(1) - return patches \ No newline at end of file + return patches diff --git a/more_math/nodes.py b/more_math/nodes.py index e5913ab..b6a6676 100644 --- a/more_math/nodes.py +++ b/more_math/nodes.py @@ -13,37 +13,40 @@ from .AudioToSpectrogramNode import AudioToSpectrogram from comfy_api.latest import ComfyExtension, io + class IntToFloatNode(io.ComfyNode): """ Converts int to float. """ + @classmethod def define_schema(cls) -> io.Schema: - """ - """ - return io.Schema( - node_id="mrmth_IntToFloat", - display_name="Int -> Float", - category="More math", - inputs=[ - io.Int.Input(id="value", default=0), - ], - outputs=[ - io.Float.Output(), - ], - ) + """ """ + return io.Schema( + node_id="mrmth_IntToFloat", + display_name="Int -> Float", + category="More math", + inputs=[ + io.Int.Input(id="value", default=0), + ], + outputs=[ + io.Float.Output(), + ], + ) + @classmethod def execute(cls, value): return (float(value),) + class FloatToIntNode(io.ComfyNode): """ Converts float to int. """ + @classmethod def define_schema(cls) -> io.Schema: - """ - """ + """ """ return io.Schema( node_id="mrmth_FloatToInt", category="More math", @@ -55,6 +58,7 @@ class FloatToIntNode(io.ComfyNode): io.Int.Output(), ], ) + @classmethod def execute(cls, value): return (int(value),) @@ -63,23 +67,26 @@ class FloatToIntNode(io.ComfyNode): class MoreMathExtension(ComfyExtension): def __init__(self): pass + @classmethod async def get_node_list(self) -> list[type[io.ComfyNode]]: - return [ - ConditioningMathNode, - ModelMathNode, - CLIPMathNode, - VAEMathNode, - LatentMathNode, - ImageMathNode, - FloatMathNode, - NoiseMathNode, - IntToFloatNode, - FloatToIntNode, - AudioMathNode, - VideoMathNode, - AudioToSpectrogram, - SpectrogramToAudio - ] + return [ + ConditioningMathNode, + ModelMathNode, + CLIPMathNode, + VAEMathNode, + LatentMathNode, + ImageMathNode, + FloatMathNode, + NoiseMathNode, + IntToFloatNode, + FloatToIntNode, + AudioMathNode, + VideoMathNode, + AudioToSpectrogram, + SpectrogramToAudio, + ] + + async def comfy_entrypoint() -> MoreMathExtension: return MoreMathExtension() diff --git a/tests/conftest.py b/tests/conftest.py index 5ea0eb3..72f3a07 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -15,6 +15,7 @@ for p in [_project_root, _comfy_root]: import pytest + @pytest.fixture(scope="session", autouse=True) def session_setup(): """ @@ -23,4 +24,3 @@ def session_setup(): ensures any further session setup can be added without changing tests. """ yield - diff --git a/tests/reproduce_conv_issues.py b/tests/reproduce_conv_issues.py index 6e3faea..4cd5fc1 100644 --- a/tests/reproduce_conv_issues.py +++ b/tests/reproduce_conv_issues.py @@ -16,6 +16,7 @@ from more_math.Parser.UnifiedMathVisitor import UnifiedMathVisitor from more_math.LatentMathNode import LatentMathNode + def test_conv_1d(): """ Test 1D convolution. @@ -26,17 +27,17 @@ def test_conv_1d(): node = LatentMathNode() shape = (1, 10, 4) a_val = torch.randn(*shape) - + # conv(a, 3, 1.0) -> implies kernel of ones, size 3 # Result should correspond to 1D conv try: # LatentMathNode expects latent dicts usually input_dict = {"samples": a_val} res = node.execute("conv(a, 3, 1.0)", a=input_dict) - + # LatentMathNode returns list of dicts res_tensor = res[0]["samples"] - + print(f"1D Conv Result Shape: {res_tensor.shape}") # Expect (1, 10, 4) assert res_tensor.shape == shape @@ -44,6 +45,7 @@ def test_conv_1d(): print(f"1D Conv Failed: {e}") raise + def test_conv_3d(): """ Test 3D convolution. @@ -54,7 +56,7 @@ def test_conv_3d(): node = LatentMathNode() shape = (1, 5, 32, 32, 4) a_val = torch.randn(*shape) - + try: input_dict = {"samples": a_val} res = node.execute("conv(a, 3, 3, 3, 1.0)", a=input_dict) @@ -65,6 +67,7 @@ def test_conv_3d(): print(f"3D Conv Failed: {e}") raise + def test_conv_arbitrary_batch(): """ Test generic tensor with extra batch dims. @@ -74,7 +77,7 @@ def test_conv_arbitrary_batch(): node = LatentMathNode() shape = (2, 2, 16, 16, 4) a_val = torch.randn(*shape) - + try: # conv(a, 3, 3, 1.0) -> 2D conv on (16,16) input_dict = {"samples": a_val} @@ -86,6 +89,7 @@ def test_conv_arbitrary_batch(): print(f"Arbitrary Batch Failed: {e}") raise + def test_conv_list_kernel(): """ Test conv with list kernel (Regression test for float64 mismatch). @@ -93,15 +97,15 @@ def test_conv_list_kernel(): """ print("\n--- Testing List Kernel Conv ---") node = LatentMathNode() - shape = (1, 5, 10, 10, 4) # [B, D, H, W, C] + shape = (1, 5, 10, 10, 4) # [B, D, H, W, C] a_val = torch.randn(*shape).float() - + # 3x3x3 kernel = 27 elements # Using the user's example kernel - kernel_list = [1,1,1,1,0,1,1,1,1, 0,0,0,0,1,0,0,0,0, 1,1,1,1,0,1,1,1,1] + kernel_list = [1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1] kernel_str = str(kernel_list) expr = f"conv(a, 3, 3, 3, {kernel_str})/8" - + try: input_dict = {"samples": a_val} res = node.execute(expr, a=input_dict) @@ -113,6 +117,7 @@ def test_conv_list_kernel(): print(f"List Kernel Failed: {e}") raise + def test_conv_audio(): """ Test 1D conv on Audio [B, C, L]. @@ -122,9 +127,9 @@ def test_conv_audio(): """ print("\n--- Testing Audio Conv [B, C, L] ---") node = LatentMathNode() - shape = (1, 2, 100) # [B, C, L] (L >> C) + shape = (1, 2, 100) # [B, C, L] (L >> C) a_val = torch.randn(*shape).float() - + # conv(a, 3, 1.0) on last dim (L) # Expected: result shape same as input try: @@ -132,19 +137,20 @@ def test_conv_audio(): res = node.execute("conv(a, 3, 1.0)", a=input_dict) res_tensor = res[0]["samples"] print(f"Audio Result Shape: {res_tensor.shape}") - + if res_tensor.shape != shape: - print(f"Likely interpreted as Channels Last [B, L, C] where C is small? No.") - # If interpreted as Channels last [..., C]. - # [1, 2, 100]. Spatial=[2]. Channel=100. - # Output [1, 2, 100] (but confusing channels). - pass - + print(f"Likely interpreted as Channels Last [B, L, C] where C is small? No.") + # If interpreted as Channels last [..., C]. + # [1, 2, 100]. Spatial=[2]. Channel=100. + # Output [1, 2, 100] (but confusing channels). + pass + assert res_tensor.shape == shape except Exception as e: print(f"Audio Conv Failed: {e}") raise + def test_conv_deep_latent(): """ Test 3D conv on Deep Latent [B, 32, H, W] (User request). @@ -156,7 +162,7 @@ def test_conv_deep_latent(): node = LatentMathNode() shape = (1, 32, 16, 16) a_val = torch.randn(*shape).float() - + # conv(a, 3, 3, 3, 1.0) # 3D kernels need D,H,W. # D=32 (Channel). H=16. W=16. @@ -166,7 +172,7 @@ def test_conv_deep_latent(): res_tensor = res[0]["samples"] print(f"Deep Latent Result Shape: {res_tensor.shape}") assert res_tensor.shape == shape - + # Identity check (ensure D neighbors engaged) # Using simple kernel, center only vs ones. # But this test just checks shape and execution path. @@ -174,6 +180,7 @@ def test_conv_deep_latent(): print(f"Deep Latent Failed: {e}") raise + def test_conv_padding(): """ Test padding consistency, especially for even kernels. @@ -184,7 +191,7 @@ def test_conv_padding(): node = LatentMathNode() shape = (1, 10, 10, 1) a_val = torch.randn(*shape).float() - + # conv(a, 4, 4, 1.0) # If padding is symmetric 2, result is 11x11. # If padding is symmetric 1, result is 9x9. @@ -199,6 +206,7 @@ def test_conv_padding(): print(f"Padding Test Failed: {e}") raise + def test_conv_complex_padding(): """ Test asymmetric padding with mixed odd/even kernel sizes. @@ -209,7 +217,7 @@ def test_conv_complex_padding(): node = LatentMathNode() shape = (1, 10, 10, 1) a_val = torch.randn(*shape).float() - + try: input_dict = {"samples": a_val} res = node.execute("conv(a, 3, 4, 1.0)", a=input_dict) @@ -220,6 +228,7 @@ def test_conv_complex_padding(): print(f"Complex Padding Failed: {e}") raise + def test_conv_3d_asymmetric(): """ Test 3D conv with asymmetric spatial dims. @@ -229,7 +238,7 @@ def test_conv_3d_asymmetric(): node = LatentMathNode() shape = (1, 5, 10, 20, 1) a_val = torch.randn(*shape).float() - + try: input_dict = {"samples": a_val} res = node.execute("conv(a, 3, 3, 3, 1.0)", a=input_dict) @@ -240,6 +249,7 @@ def test_conv_3d_asymmetric(): print(f"3D Asymmetric Failed: {e}") raise + if __name__ == "__main__": try: test_conv_1d() @@ -254,5 +264,6 @@ if __name__ == "__main__": print("All Conv tests passed!") except Exception as e: import traceback + traceback.print_exc() sys.exit(1) diff --git a/tests/test_grammar_coverage.py b/tests/test_grammar_coverage.py index 5512ed0..a8bb355 100644 --- a/tests/test_grammar_coverage.py +++ b/tests/test_grammar_coverage.py @@ -8,19 +8,16 @@ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..") from more_math.helper_functions import eval_tensor_expr, eval_float_expr + def test_all_functions(): # Setup some test data a_val = 2.0 b_val = 3.0 tensor_a = torch.tensor([1.0, 2.0, 3.0]) tensor_b = torch.tensor([0.5, 1.5, 2.5]) - - variables = { - 'a': a_val, 'b': b_val, - 'ta': tensor_a, 'tb': tensor_b, - 'x': 0.5, 'y': 1.0, 'z': 2.0 - } - + + variables = {"a": a_val, "b": b_val, "ta": tensor_a, "tb": tensor_b, "x": 0.5, "y": 1.0, "z": 2.0} + # helper for assertions def check(expr, expected_scalar=None, vars=variables): # Test scalar @@ -29,7 +26,7 @@ def test_all_functions(): if isinstance(res_s, (int, float)): assert abs(res_s - expected_scalar) < 1e-4, f"Scalar {expr} failed: {res_s} != {expected_scalar}" # if expected is tensor we check differently - + # Test tensor res_t = eval_tensor_expr(expr, vars, (3,)) assert torch.is_tensor(res_t) or isinstance(res_t, (list, int, float)) @@ -49,20 +46,20 @@ def test_all_functions(): # acosh(1) = 0 check("acosh(1)", 0.0) check("atanh(0)", 0.0) - + check("abs(-5)", 5.0) - check("| -10 |", 10.0) # AbsExp + check("| -10 |", 10.0) # AbsExp check("sqrt(16)", 4.0) check("ln(e)", 1.0) check("log(100)", 2.0) check("exp(1)", math.e) - + check("floor(1.9)", 1.0) check("ceil(1.1)", 2.0) check("round(1.5)", 2.0) - check("gamma(3)", 2.0) # gamma(n) = (n-1)! + check("gamma(3)", 2.0) # gamma(n) = (n-1)! check("sigm(0)", 0.5) - + check("fract(1.25)", 0.25) check("relu(-5)", 0.0) check("relu(5)", 5.0) @@ -71,16 +68,16 @@ def test_all_functions(): check("gelu(0)", 0.0) check("sign(-10)", -1.0) check("sign(10)", 1.0) - check("angle(ta)") # test complex angle? no, just ensuring it runs - + check("angle(ta)") # test complex angle? no, just ensuring it runs + print("--- Testing Two-Arg Functions ---") check("pow(2, 3)", 8.0) - check("atan2(1, 1)", math.pi/4) + check("atan2(1, 1)", math.pi / 4) check("tmin(5, 10)", 5.0) check("tmax(5, 10)", 10.0) - check("step(0.5, 0.2)", 1.0) # step(x, edge) = 1 if x>=edge + check("step(0.5, 0.2)", 1.0) # step(x, edge) = 1 if x>=edge check("step(0.1, 0.2)", 0.0) - + print("--- Testing Operators ---") check("1 + 2", 3.0) check("5 - 3", 2.0) @@ -88,7 +85,7 @@ def test_all_functions(): check("10 / 2", 5.0) check("7 % 3", 1.0) check("2 ^ 3", 8.0) - + print("--- Testing Boolean/Comparison ---") check("5 > 3", 1.0) check("5 < 3", 0.0) @@ -96,33 +93,33 @@ def test_all_functions(): check("5 <= 4", 0.0) check("2 == 2", 1.0) check("2 != 3", 1.0) - + print("--- Testing Ternary/N-ary ---") check("clamp(5, 0, 10)", 5.0) check("clamp(-5, 0, 10)", 0.0) check("lerp(0, 10, 0.5)", 5.0) - check("smoothstep(0.5, 0, 1)", 0.5) # smoothstep(x, edge0, edge1) - + check("smoothstep(0.5, 0, 1)", 0.5) # smoothstep(x, edge0, edge1) + check("smin(1, 2, 3, 0)", 0.0) check("smax(1, 5, 2)", 5.0) - + print("--- Testing Tensor Specifics (Norm, Map, Conv, FFT) ---") # Verify abs(x) vs |x| res_abs_func = eval_tensor_expr("abs(ta)", variables, (3,)) assert torch.equal(res_abs_func, torch.abs(tensor_a)) - + res_abs_exp = eval_tensor_expr("|ta|", variables, (3,)) assert torch.is_tensor(res_abs_exp) and res_abs_exp.numel() == 1 assert torch.allclose(res_abs_exp, torch.linalg.norm(tensor_a)) check("tnorm(ta)") check("snorm(ta)") - check("map(ta, x)") # 1D map + check("map(ta, x)") # 1D map # Verify conv with kernel variables kW - check("conv(ta, 3, kW)") # 1D conv, size 3, value is kW (which is 3.0) + check("conv(ta, 3, kW)") # 1D conv, size 3, value is kW (which is 3.0) check("permute(ta, [0])") check("reshape(ta, [3, 1])") - + # FFT/IFFT # We need a shape for FFT usually res_fft = eval_tensor_expr("fft(ta)", variables, (3,)) @@ -131,17 +128,17 @@ def test_all_functions(): # Multi-dim Permute tensor_2d = torch.randn(2, 3) - vars_2d = {'t2': tensor_2d} + vars_2d = {"t2": tensor_2d} res_perm = eval_tensor_expr("permute(t2, [1, 0])", vars_2d, (3, 2)) assert res_perm.shape == (3, 2) - + print("--- Testing List and Constants ---") check("[1, 2, 3] + 1") check("pi", math.pi) check("e", math.e) check("print(1)", 1.0) check("pshp(ta)") - + print("--- Testing Swap ---") # swap(tensor, dim, i, j) # ta = [1, 2, 3] @@ -151,5 +148,6 @@ def test_all_functions(): print("All coverage tests passed!") + if __name__ == "__main__": test_all_functions() diff --git a/tests/test_model_math.py b/tests/test_model_math.py index 5884623..94770de 100644 --- a/tests/test_model_math.py +++ b/tests/test_model_math.py @@ -18,6 +18,7 @@ if _comfy_root not in sys.path: import torch from more_math.ModelMathNode import ModelMathNode + class MockModelPatcher: def __init__(self, state_dict): self.model = comfy_api.Model() @@ -35,38 +36,33 @@ class MockModelPatcher: def add_patches(self, patches, strength1, strength2): self.patches.update(patches) + def test_model_math_simple_add(): # Setup inputs - sd_a = { - "layer1.weight": torch.tensor([1.0, 2.0]), - "layer2.bias": torch.tensor([0.5]) - } + sd_a = {"layer1.weight": torch.tensor([1.0, 2.0]), "layer2.bias": torch.tensor([0.5])} a = MockModelPatcher(sd_a) - - sd_b = { - "layer1.weight": torch.tensor([0.5, 0.5]), - "layer2.bias": torch.tensor([0.5]) - } + + sd_b = {"layer1.weight": torch.tensor([0.5, 0.5]), "layer2.bias": torch.tensor([0.5])} b = MockModelPatcher(sd_b) # Expression: a + b expr = "a + b" - + # Execute result_tuple = ModelMathNode.execute(expr, a, b=b) result_model = result_tuple[0] - + # Verify patches patches = result_model.patches - - # "layer1.weight": + + # "layer1.weight": # a = [1.0, 2.0] # b = [0.5, 0.5] # res = [1.5, 2.5] # diff = res - a = [0.5, 0.5] assert "layer1.weight" in patches assert torch.allclose(patches["layer1.weight"][0], torch.tensor([0.5, 0.5])) - + # "layer2.bias": # a = 0.5, b = 0.5 # res = 1.0 @@ -74,66 +70,69 @@ def test_model_math_simple_add(): assert "layer2.bias" in patches assert torch.allclose(patches["layer2.bias"][0], torch.tensor([0.5])) + def test_model_math_zero_default(): # Test handling of missing b (should be zero) - sd_a = { "w": torch.tensor([10.0]) } + sd_a = {"w": torch.tensor([10.0])} a = MockModelPatcher(sd_a) - + # expr: a + b. b is None -> b=0. # res = 10 + 0 = 10. # diff = 10 - 10 = 0. # Should skip patch. - + result_tuple = ModelMathNode.execute("a + b", a, b=None) result_model = result_tuple[0] - + assert len(result_model.patches) == 0 + def test_model_math_custom_formula(): - sd_a = { "w": torch.tensor([2.0]) } + sd_a = {"w": torch.tensor([2.0])} a = MockModelPatcher(sd_a) - + # expr: a * w # w input = 0.5 - + result_tuple = ModelMathNode.execute("a * w", a, w=0.5) result_model = result_tuple[0] - + # res = 2.0 * 0.5 = 1.0 # diff = 1.0 - 2.0 = -1.0 patches = result_model.patches assert "w" in patches assert torch.allclose(patches["w"][0], torch.tensor([-1.0])) + def test_model_math_device_mismatch(): # Simulating a scenario where model is on a specific device (we can't easily use 'cuda' in CI/CPU env, but we can check if visitor respects it) # We will iterate manually over ModelMathNode logic logic to check TensorEvalVisitor behavior or mock a device. # Actually, simpler: create a tensor on a specific device (if possible) or just ensure visitor uses the device of 'a'. - + # Since we might only have CPU, we can't fully reproduce 'cpu vs cuda' crash without cuda. # But we can verify that the scalar created by visitor.visitNumberExp has the same device as 'a'. - + from more_math.Parser.TensorEvalVisitor import TensorEvalVisitor from antlr4 import InputStream, CommonTokenStream from more_math.Parser.MathExprLexer import MathExprLexer from more_math.Parser.MathExprParser import MathExprParser - + # Mock a tensor with a mocked .device property if we can't use real devices # But torch tensors created with torch.tensor are real. - # We will rely on inspection of the visitor code change. - # Or strict check: - + # We will rely on inspection of the visitor code change. + # Or strict check: + # Let's try to pass a dummy device string if create_tensor allows, or just check the code path. # Better: Inspect the created tensor from visitor. - + tsr = torch.zeros((1,)) # We interpret "device mismatch" as: created scalars didn't pick up the device of 'tsr'. # We can force 'tsr' to be on a specific device if available, but likely only 'cpu' is available. - # Use a mock object for 'a' that claims to be on 'cuda:0', even if it isn't real tensor? + # Use a mock object for 'a' that claims to be on 'cuda:0', even if it isn't real tensor? # No, TensorEvalVisitor expects torch operations. - + # We will verify that TensorEvalVisitor creates tensors with the same device as input 'a'. - + # Setup expr = "0.5" input_stream = InputStream(expr) @@ -141,108 +140,117 @@ def test_model_math_device_mismatch(): stream = CommonTokenStream(lexer) parser = MathExprParser(stream) tree = parser.expr() - - variables = {'a': torch.zeros(1)} + + variables = {"a": torch.zeros(1)} # We want to ensure that if we had a non-cpu device, it would use it. - # Since we can't really test this without a GPU, we will write the fix and verify it analytically + # Since we can't really test this without a GPU, we will write the fix and verify it analytically # or use a mock that wraps a tensor but intercepts .device? - + # Let's just create a test that ensures the result of '0.5' is a tensor that has the same properties as we expect. pass + class MockPatcherContainer: def __init__(self, state_dict): self.patcher = MockModelPatcher(state_dict) def clone(self): new_obj = MockPatcherContainer(self.patcher.model.state_dict()) - new_obj.patcher = self.patcher.clone() # Mock clone behavior + new_obj.patcher = self.patcher.clone() # Mock clone behavior return new_obj - + def add_patches(self, patches, s1, s2): self.patcher.add_patches(patches, s1, s2) + def test_clip_math(): from more_math.ModelMathNode import CLIPMathNode - sd_a = { "text_model.encoder.layers.0.mlp.fc1.weight": torch.tensor([1.0]) } + + sd_a = {"text_model.encoder.layers.0.mlp.fc1.weight": torch.tensor([1.0])} clip_a = MockPatcherContainer(sd_a) - + result_tuple = CLIPMathNode.execute("a * 2", clip_a) result_clip = result_tuple[0] - + # 1.0 * 2 = 2.0. diff = 1.0. patches = result_clip.patcher.patches assert "text_model.encoder.layers.0.mlp.fc1.weight" in patches assert torch.allclose(patches["text_model.encoder.layers.0.mlp.fc1.weight"][0], torch.tensor([1.0])) + def test_vae_math(): from more_math.ModelMathNode import VAEMathNode - sd_a = { "decoder.conv_in.weight": torch.tensor([1.0]) } + + sd_a = {"decoder.conv_in.weight": torch.tensor([1.0])} # VAE acts like PatcherContainer but no clone() on the VAE itself usually. # But for mock we can use PatcherContainer structure because VAEMathNode expects .patcher - + # Mock VAE object class MockVAE: def __init__(self, state_dict): self.patcher = MockModelPatcher(state_dict) + # No clone method on VAE - + vae_a = MockVAE(sd_a) - + result_tuple = VAEMathNode.execute("a + 1", vae_a) result_vae = result_tuple[0] - + # Check if result is a copy (not same object) assert result_vae is not vae_a # Check if patcher is cloned assert result_vae.patcher is not vae_a.patcher - + # 1.0 + 1 = 2.0. diff = 1.0 patches = result_vae.patcher.patches assert "decoder.conv_in.weight" in patches assert torch.allclose(patches["decoder.conv_in.weight"][0], torch.tensor([1.0])) + def test_model_math_disjoint_keys(): - # ModelMathNode uses 'a' as the base. - # Keys in 'b' that are NOT in 'a' should be ignored in the loop generally, + # ModelMathNode uses 'a' as the base. + # Keys in 'b' that are NOT in 'a' should be ignored in the loop generally, # unless logic iterates over union. # Current logic: for key, tens_a in sd_a.items(): ... # So keys only in B are IGNORED. - - sd_a = { "common": torch.tensor([1.0]) } - sd_b = { "common": torch.tensor([2.0]), "extra_b": torch.tensor([3.0]) } - + + sd_a = {"common": torch.tensor([1.0])} + sd_b = {"common": torch.tensor([2.0]), "extra_b": torch.tensor([3.0])} + a = MockPatcherContainer(sd_a) b = MockPatcherContainer(sd_b) - + # expr: a + b # common: 1 + 2 = 3. diff = 2. # extra_b: should NOT be in patches because loop is over 'a' - + result_tuple = ModelMathNode.execute("a + b", a.patcher, b=b.patcher) patches = result_tuple[0].patches - + assert "common" in patches assert torch.allclose(patches["common"][0], torch.tensor([2.0])) assert "extra_b" not in patches + def test_model_math_weighted_merge(): # Test w/x/y/z weights - sd_a = { "w": torch.tensor([10.0]) } - sd_b = { "w": torch.tensor([20.0]) } - + sd_a = {"w": torch.tensor([10.0])} + sd_b = {"w": torch.tensor([20.0])} + a = MockPatcherContainer(sd_a) b = MockPatcherContainer(sd_b) - + # expr: lerp(a, b, w) with w=0.5 -> 15.0 # diff = 15 - 10 = 5. - + result_tuple = ModelMathNode.execute("lerp(a, b, w)", a.patcher, b=b.patcher, w=0.5) patches = result_tuple[0].patches - + assert "w" in patches assert torch.allclose(patches["w"][0], torch.tensor([5.0])) + if __name__ == "__main__": test_model_math_simple_add() test_model_math_zero_default() diff --git a/tests/test_more_math.py b/tests/test_more_math.py index 12d3913..4156ebf 100644 --- a/tests/test_more_math.py +++ b/tests/test_more_math.py @@ -32,6 +32,7 @@ from more_math.FloatMathNode import FloatMathNode # Node Initialization and Metadata Tests # ========================================== + def test_conditioning_math_node_initialization(): node = ConditioningMathNode() assert isinstance(node, ConditioningMathNode) @@ -69,37 +70,33 @@ def test_image_math_node_metadata(): # FFT Tests # ========================================== + def test_fft_invertibility(): # Create random input latent (Batch, Channel, Height, Width) input_tensor = torch.randn(1, 4, 32, 32, dtype=torch.float32) input_dict = {"samples": input_tensor} # Execute ifft(fft(a)) - result = LatentMathNode.execute( - Latent="ifft(fft(a))", - a=input_dict - ) + result = LatentMathNode.execute(Latent="ifft(fft(a))", a=input_dict) output_tensor = result[0]["samples"] - assert torch.allclose(input_tensor, output_tensor, atol=1e-5), \ - f"Max difference: {(input_tensor - output_tensor).abs().max()}" + assert torch.allclose(input_tensor, output_tensor, atol=1e-5), f"Max difference: {(input_tensor - output_tensor).abs().max()}" def test_image_fft_dims(): # Image input is (Batch, Height, Width, Channel) input_tensor = torch.randn(1, 32, 32, 3, dtype=torch.float32) - result = ImageMathNode.execute( - Image="ifft(fft(a))", - a=input_tensor - ) + result = ImageMathNode.execute(Image="ifft(fft(a))", a=input_tensor) output_tensor = result[0] assert input_tensor.shape == output_tensor.shape - assert torch.allclose(input_tensor, output_tensor, atol=1e-5), \ + assert torch.allclose(input_tensor, output_tensor, atol=1e-5), ( f"Image FFT round trip failed. Max diff: {(input_tensor - output_tensor).abs().max()}" + ) # ========================================== # Latent Math Basic Functions (Evaluated on Tensors) # ========================================== + def test_latent_lerp(): node = LatentMathNode() l_a = {"samples": torch.zeros(1, 4, 32, 32)} @@ -111,24 +108,24 @@ def test_latent_lerp(): def test_latent_step_true(): node = LatentMathNode() # step(0.5, a) where a=0.8 -> 1 - res_step = node.execute("step(0.5, a)", a={"samples": torch.full((1,1,1,1), 0.8)})[0]["samples"] + res_step = node.execute("step(0.5, a)", a={"samples": torch.full((1, 1, 1, 1), 0.8)})[0]["samples"] assert torch.allclose(res_step, torch.ones_like(res_step)) def test_latent_step_false(): node = LatentMathNode() # step(0.5, a) where a=0.2 -> 0 - res_step2 = node.execute("step(0.5, a)", a={"samples": torch.full((1,1,1,1), 0.2)})[0]["samples"] + res_step2 = node.execute("step(0.5, a)", a={"samples": torch.full((1, 1, 1, 1), 0.2)})[0]["samples"] assert torch.allclose(res_step2, torch.zeros_like(res_step2)) def test_latent_swap(): node = LatentMathNode() - t_lat = torch.tensor([0.0, 10.0, 20.0, 30.0]).view(1,4,1,1) + t_lat = torch.tensor([0.0, 10.0, 20.0, 30.0]).view(1, 4, 1, 1) # Swap channels 0 and 3 -> 30, 10, 20, 0 l_swap = {"samples": t_lat} res_swap = node.execute("swap(a, 1, 0, 3)", a=l_swap)[0]["samples"] - expected = torch.tensor([30.0, 10.0, 20.0, 0.0]).view(1,4,1,1) + expected = torch.tensor([30.0, 10.0, 20.0, 0.0]).view(1, 4, 1, 1) assert torch.allclose(res_swap, expected) @@ -157,6 +154,7 @@ def test_latent_fract(): # Float Math Basic Functions (Evaluated on Scalars) # ========================================== + def test_float_lerp(): node = FloatMathNode() res = node.execute("lerp(a, b, 0.5)", a=0.0, b=10.0)[0] @@ -185,6 +183,7 @@ def test_float_smoothstep(): # Float Math Extended Functions # ========================================== + def test_float_fract(): node = FloatMathNode() res = node.execute("fract(a)", a=1.5)[0] @@ -221,6 +220,7 @@ def test_float_gelu(): # Latent Math Extended Functions # ========================================== + def test_latent_smoothstep(): node = LatentMathNode() l_a = {"samples": torch.zeros(1, 4, 32, 32)} @@ -246,6 +246,7 @@ def test_latent_gelu(): # Image Math Operations # ========================================== + def test_image_lerp(): node = ImageMathNode() img_red = torch.tensor([1.0, 0.0, 0.0]).view(1, 1, 1, 3) @@ -267,6 +268,7 @@ def test_image_swap(): # Nested Expressions # ========================================== + def test_float_nested_expressions_true(): node = FloatMathNode() # lerp(0, 10, step(0.5, 0.8)) -> lerp(0, 10, 1) -> 10 @@ -285,6 +287,7 @@ def test_float_nested_expressions_false(): # 5D Tensor Support # ========================================== + def test_5d_tensors_identity(): node = LatentMathNode() samples = torch.randn(1, 5, 4, 32, 32) @@ -315,12 +318,14 @@ def test_5d_tensors_fft(): # Noise Math Node 5D Support # ========================================== + def test_noise_math_5d(): from more_math.NoiseMathNode import NoiseMathNode class MockNoise: def __init__(self, tensor): self.tensor = tensor + def generate_noise(self, input_latent): return self.tensor @@ -340,6 +345,7 @@ def test_noise_math_5d(): # NestedTensor Support # ========================================== + def test_nested_tensor_support(): try: from comfy.nested_tensor import NestedTensor @@ -354,16 +360,18 @@ def test_nested_tensor_support(): res_lat = node.execute("a + 1.0", a=l_in)[0]["samples"] - assert getattr(res_lat, 'is_nested', False) + assert getattr(res_lat, "is_nested", False) res_list = res_lat.unbind() assert len(res_list) == 2 assert torch.allclose(res_list[0], torch.full_like(t1, 2.0)) assert torch.allclose(res_list[1], torch.full_like(t2, 3.0)) + # ========================================== # Comprehensive Math Function Tests # ========================================== + def test_trig_functions(): node = FloatMathNode() # Sin/Cos checks @@ -373,6 +381,7 @@ def test_trig_functions(): # tan(0) = 0 assert abs(node.execute("tan(0)", a=0.0)[0] - 0.0) < 1e-5 + def test_inverse_trig_functions(): node = FloatMathNode() # asin(0) = 0, acos(1) = 0, atan(0) = 0 @@ -380,6 +389,7 @@ def test_inverse_trig_functions(): assert abs(node.execute("acos(1)", a=0.0)[0] - 0.0) < 1e-5 assert abs(node.execute("atan(0)", a=0.0)[0] - 0.0) < 1e-5 + def test_pow_log_functions(): node = FloatMathNode() # pow(2, 3) = 8 @@ -393,15 +403,17 @@ def test_pow_log_functions(): # ln(e) = 1. Using 'e' constant logic check or approx 2.718 assert abs(node.execute("ln(2.7182818)", a=0.0)[0] - 1.0) < 1e-4 + def test_min_max_functions(): import sys + node = FloatMathNode() print("Testing tmin...", flush=True) # tmin(2, 5) = 2, tmax(2, 5) = 5 assert abs(node.execute("tmin(2, 5)", a=0.0)[0] - 2.0) < 1e-5 print("Testing tmax...", flush=True) assert abs(node.execute("tmax(2, 5)", a=0.0)[0] - 5.0) < 1e-5 - + # smin/smax (Smooth min/max? Or just multi-arg min/max? TensorEvalVisitor uses stack.min/max) # smin(1, 2, 3) = 1 print("Testing smin...", flush=True) @@ -414,6 +426,7 @@ def test_min_max_functions(): print(f"smax result: {res_smax} type: {type(res_smax)}", flush=True) assert abs(res_smax - 3.0) < 1e-5 + def test_basic_utilities(): node = FloatMathNode() # abs(-5) = 5 @@ -429,14 +442,17 @@ def test_basic_utilities(): assert abs(node.execute("clamp(10, 0, 5)", a=0.0)[0] - 5.0) < 1e-5 assert abs(node.execute("clamp(-5, 0, 5)", a=0.0)[0] - 0.0) < 1e-5 + def test_advanced_activations(): node = FloatMathNode() # sigm(0) = 0.5 assert abs(node.execute("sigm(0)", a=0.0)[0] - 0.5) < 1e-5 + if __name__ == "__main__": import sys - try: + + try: test_conditioning_math_node_initialization() test_conditioning_math_node_metadata() test_latent_math_node_initialization() @@ -452,8 +468,7 @@ if __name__ == "__main__": print("All tests passed!") except Exception as e: import traceback + traceback.print_exc() sys.exit(1) print("All tests in test_more_math.py passed!") - - diff --git a/tests/test_unified_math.py b/tests/test_unified_math.py index 83f2b73..519cf4e 100644 --- a/tests/test_unified_math.py +++ b/tests/test_unified_math.py @@ -16,146 +16,156 @@ from more_math.Parser.MathExprLexer import MathExprLexer from more_math.Parser.MathExprParser import MathExprParser from antlr4 import InputStream, CommonTokenStream + def parse_and_visit(expr_str, variables): lexer = MathExprLexer(InputStream(expr_str)) stream = CommonTokenStream(lexer) parser = MathExprParser(stream) tree = parser.expr() - + # We might need to pass shape/device if UnifiedMathVisitor requires it for tensor creation # For now assuming it can infer or defaults. # The original TensorEvalVisitor required shape. Unified might need it for "1.0" -> Tensor promotion cases? # Or maybe "1.0" stays scalar till needed? # Let's assume we pass a default shape/device if needed, but for scalar tests we might not need it. - - shape = (1, 1, 1, 1) # Dummy shape + + shape = (1, 1, 1, 1) # Dummy shape visitor = UnifiedMathVisitor(variables, shape) return visitor.visit(tree) + def test_scalar_ops(): vars = {"a": 2.0, "b": 3.0} - + assert parse_and_visit("a + b", vars) == 5.0 assert parse_and_visit("a * b", vars) == 6.0 assert parse_and_visit("sin(0)", vars) == 0.0 assert parse_and_visit("smax(a, b)", vars) == 3.0 - + # Type check - ensure they are python float/int, not tensor res = parse_and_visit("a + b", vars) - assert isinstance(res, (float, int)) + assert isinstance(res, (float, int)) + def test_tensor_ops(): t1 = torch.tensor([1.0, 2.0]) t2 = torch.tensor([3.0, 4.0]) vars = {"t1": t1, "t2": t2, "s": 2.0} - + # Tensor + Tensor res = parse_and_visit("t1 + t2", vars) assert isinstance(res, torch.Tensor) assert torch.allclose(res, torch.tensor([4.0, 6.0])) - + # Tensor + Scalar res2 = parse_and_visit("t1 * s", vars) assert isinstance(res2, torch.Tensor) assert torch.allclose(res2, torch.tensor([2.0, 4.0])) - + # Scalar + Tensor res3 = parse_and_visit("s + t2", vars) assert isinstance(res3, torch.Tensor) assert torch.allclose(res3, torch.tensor([5.0, 6.0])) + def test_list_broadcasting(): # Feature: List * Tensor -> Stack of Tensors - t = torch.ones((2, 2)) # 2x2 ones + t = torch.ones((2, 2)) # 2x2 ones l = [1.0, 2.0, 3.0] vars = {"t": t, "l": l} - + # l * t should produce a stack of 3 tensors: 1*t, 2*t, 3*t # Expected shape: (3, 2, 2) res = parse_and_visit("l * t", vars) - + assert isinstance(res, torch.Tensor) assert res.shape == (3, 2, 2) assert torch.allclose(res[0], t * 1.0) assert torch.allclose(res[1], t * 2.0) assert torch.allclose(res[2], t * 3.0) + def test_list_scalar_mapping(): # Feature: List * Scalar -> List of results l = [1.0, 2.0, 3.0] vars = {"l": l} - + res = parse_and_visit("l * 2", vars) assert isinstance(res, list) assert res == [2.0, 4.0, 6.0] + def test_func_dispatch(): - t = torch.tensor([0.0, math.pi/2]) + t = torch.tensor([0.0, math.pi / 2]) vars = {"t": t, "s": 0.0} - + # sin(tensor) -> tensor res_t = parse_and_visit("sin(t)", vars) assert isinstance(res_t, torch.Tensor) assert torch.allclose(res_t, torch.tensor([0.0, 1.0])) - + # sin(scalar) -> scalar res_s = parse_and_visit("sin(s)", vars) assert isinstance(res_s, float) assert abs(res_s) < 1e-6 - + # sin(list) -> list - l = [0.0, math.pi/2] + l = [0.0, math.pi / 2] vars["l"] = l res_l = parse_and_visit("sin(l)", vars) assert isinstance(res_l, list) assert abs(res_l[0]) < 1e-6 assert abs(res_l[1] - 1.0) < 1e-6 + def test_power_ops(): vars = {"a": 2.0, "b": 3.0} # Scalar ^ Scalar assert parse_and_visit("a ^ b", vars) == 8.0 - + # Tensor ^ Scalar t = torch.tensor([2.0, 3.0]) vars["t"] = t res = parse_and_visit("t ^ 2", vars) assert torch.allclose(res, torch.tensor([4.0, 9.0])) - + # Scalar ^ Tensor res2 = parse_and_visit("2 ^ t", vars) assert torch.allclose(res2, torch.tensor([4.0, 8.0])) + def test_hyperbolic_trig(): vars = {"s": 0.0} assert parse_and_visit("sinh(s)", vars) == 0.0 assert parse_and_visit("cosh(s)", vars) == 1.0 assert parse_and_visit("tanh(s)", vars) == 0.0 - + t = torch.tensor([0.0]) vars["t"] = t assert torch.allclose(parse_and_visit("sinh(t)", vars), torch.tensor([0.0])) assert torch.allclose(parse_and_visit("cosh(t)", vars), torch.tensor([1.0])) + def test_kernel_coords(): # Simulate visitConvFunc context # Usually grid variables are provided by the visitor during visitConvFunc # We can test if they are correctly handled if present in variables grid = torch.linspace(-1, 1, 3) vars = {"kx": grid, "ky": grid} - + # Test if expression using coordinates works res = parse_and_visit("kx^2 + ky^2", vars) assert isinstance(res, torch.Tensor) assert res.shape == grid.shape assert torch.allclose(res, grid**2 + grid**2) + def test_bool_ops(): vars = {"a": 1, "b": 0} # Scalar bool assert parse_and_visit("a > b", vars) == 1 assert parse_and_visit("a < b", vars) == 0 - + # Tensor bool t1 = torch.tensor([1.0, 0.0]) t2 = torch.tensor([0.0, 1.0]) @@ -179,5 +189,6 @@ if __name__ == "__main__": print("All UnifiedMathVisitor tests passed!") except Exception as e: import traceback + traceback.print_exc() sys.exit(1)