better parser + fix for type errors
This commit is contained in:
@@ -30,9 +30,9 @@ def evaluate_tensor_expression(ast, variables):
|
||||
op, operand_expr = ast[1]
|
||||
operand_val = evaluate_tensor_expression(operand_expr, variables)
|
||||
if op == '+':
|
||||
return operand_val
|
||||
return to_tensor(operand_val,variables['a'])
|
||||
elif op == '-':
|
||||
return torch.neg(operand_val)
|
||||
return torch.neg(to_tensor(operand_val,variables['a']))
|
||||
else:
|
||||
raise ValueError(f"Unsupported unary operator: {op}")
|
||||
|
||||
@@ -45,15 +45,15 @@ def evaluate_tensor_expression(ast, variables):
|
||||
if func_name == 'ABS':
|
||||
return torch.abs(arg_vals[0])
|
||||
elif func_name == 'NORM':
|
||||
return torch.nn.functional.normalize(arg_vals[0], p=2, dim=-1)
|
||||
return torch.nn.functional.normalize(to_tensor(arg_vals[0],variables['a']), p=2, dim=-1)
|
||||
elif func_name == 'SQRT':
|
||||
return torch.sqrt(arg_vals[0])
|
||||
return torch.sqrt(to_tensor(arg_vals[0],variables['a']))
|
||||
elif func_name == 'SIN':
|
||||
return torch.sin(arg_vals[0])
|
||||
return torch.sin(to_tensor(arg_vals[0],variables['a']))
|
||||
elif func_name == 'COS':
|
||||
return torch.cos(arg_vals[0])
|
||||
return torch.cos(to_tensor(arg_vals[0],variables['a']))
|
||||
elif func_name == 'TAN':
|
||||
return torch.tan(arg_vals[0])
|
||||
return torch.tan(to_tensor(arg_vals[0],variables['a']))
|
||||
elif func_name == 'MAX':
|
||||
return torch.max(*arg_vals)
|
||||
elif func_name == 'MIN':
|
||||
|
||||
+52
-13
@@ -11,14 +11,25 @@ class Parser:
|
||||
self.pos += 1
|
||||
return token
|
||||
|
||||
def expect(self, expected_type=None, expected_value=None):
|
||||
tok_type, value = self.peek()
|
||||
if expected_type and tok_type != expected_type:
|
||||
raise SyntaxError(
|
||||
f"Expected token type {expected_type}, got {tok_type} ('{value}') at position {self.pos}."
|
||||
)
|
||||
if expected_value and value != expected_value:
|
||||
raise SyntaxError(
|
||||
f"Expected token value '{expected_value}', got '{value}' at position {self.pos}."
|
||||
)
|
||||
return self.consume()
|
||||
|
||||
def parse_expression(self):
|
||||
"""Expression: term (PLUS|MINUS term)*"""
|
||||
left = self.parse_term()
|
||||
while True:
|
||||
tok_type, value = self.peek()
|
||||
if value in ['+', '-']:
|
||||
op = value
|
||||
self.consume() # Consume '+' or '-'
|
||||
self.consume()
|
||||
right = self.parse_term()
|
||||
left = ('BINOP', (op, left, right))
|
||||
else:
|
||||
@@ -26,13 +37,12 @@ class Parser:
|
||||
return left
|
||||
|
||||
def parse_term(self):
|
||||
"""Term: factor (MULT|DIVIDE|POW|MOD factor)*"""
|
||||
left = self.parse_factor()
|
||||
while True:
|
||||
tok_type, value = self.peek()
|
||||
if value in ['*', '/', '^', '%']:
|
||||
op = value
|
||||
self.consume() # Consume '*', '/', '^' nebo '%'
|
||||
self.consume()
|
||||
right = self.parse_factor()
|
||||
left = ('BINOP', (op, left, right))
|
||||
else:
|
||||
@@ -40,7 +50,6 @@ class Parser:
|
||||
return left
|
||||
|
||||
def parse_arguments(self):
|
||||
"""Parse comma-separated argument list for function calls."""
|
||||
args = []
|
||||
if self.peek()[0] == 'OP' and self.peek()[1] == ')':
|
||||
return args # žádné argumenty
|
||||
@@ -49,13 +58,12 @@ class Parser:
|
||||
args.append(arg)
|
||||
tok_type, value = self.peek()
|
||||
if tok_type == 'OP' and value == ',':
|
||||
self.consume() # přeskoč čárku
|
||||
self.consume()
|
||||
else:
|
||||
break
|
||||
return args
|
||||
|
||||
def parse_factor(self):
|
||||
"""Factor: unary_op factor | variable | function_call | number | parenthesis"""
|
||||
tok_type, value = self.peek()
|
||||
|
||||
# Podpora unárních operátorů + a -
|
||||
@@ -68,23 +76,54 @@ class Parser:
|
||||
if tok_type == 'OP' and value == '(':
|
||||
self.consume() # Skip '('
|
||||
expr = self.parse_expression()
|
||||
assert self.peek()[0] == 'OP' and self.peek()[1] == ')', "Missing closing parenthesis"
|
||||
if self.peek()[0] != 'OP' or self.peek()[1] != ')':
|
||||
raise SyntaxError(
|
||||
f"Missing closing parenthesis at position {self.pos}."
|
||||
)
|
||||
self.consume() # Skip ')'
|
||||
return ('PARENTHESIS', expr)
|
||||
|
||||
elif tok_type == 'NAME':
|
||||
func_name = value
|
||||
name = value
|
||||
self.consume()
|
||||
# Podpora matematických konstant
|
||||
if name.lower() == 'pi':
|
||||
return ('LITERAL', 3.141592653589793)
|
||||
if name.lower() == 'e':
|
||||
return ('LITERAL', 2.718281828459045)
|
||||
if self.peek()[0] == 'OP' and self.peek()[1] == '(':
|
||||
self.consume() # Skip '('
|
||||
args = self.parse_arguments()
|
||||
assert self.peek()[0] == 'OP' and self.peek()[1] == ')', "Missing closing parenthesis"
|
||||
if self.peek()[0] != 'OP' or self.peek()[1] != ')':
|
||||
raise SyntaxError(
|
||||
f"Missing closing parenthesis for function '{name}' at position {self.pos}."
|
||||
)
|
||||
self.consume()
|
||||
return ('FUNCTION', (func_name.upper(), args))
|
||||
return ('FUNCTION', (name.upper(), args))
|
||||
else:
|
||||
return ('VARIABLE', func_name)
|
||||
return ('VARIABLE', name)
|
||||
|
||||
elif tok_type == 'NUMBER':
|
||||
num = float(value)
|
||||
try:
|
||||
num = float(value)
|
||||
except Exception:
|
||||
raise SyntaxError(
|
||||
f"Invalid number '{value}' at position {self.pos}."
|
||||
)
|
||||
self.consume()
|
||||
return ('LITERAL', num)
|
||||
|
||||
elif tok_type == 'OP' and value == ')':
|
||||
raise SyntaxError(
|
||||
f"Unexpected right parenthesis ')' at position {self.pos}."
|
||||
)
|
||||
|
||||
elif tok_type == 'ENDMARKER':
|
||||
raise SyntaxError(
|
||||
"Unexpected end of input. Check for missing arguments or closing parentheses."
|
||||
)
|
||||
|
||||
else:
|
||||
raise SyntaxError(
|
||||
f"Unexpected token '{value}' of type {tok_type} at position {self.pos}."
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user