import sys #TODO: dodać parentices class AbstractInterpreter: def __init__(self): pass def isValid(formula:str)->bool: raise NotImplementedError class SimpleInterpreter(AbstractInterpreter): def __init__(self): pass def isValid(self,formula)->bool: print("is valid?") variables = {} f=[] def isBlacklisted(char): return char in ['\n', '\t', ' '] def isSign(char): logic_signs = ['=', '>', '&', '|', '!', '(', ')'] return char in logic_signs def isVariable(char): return not isSign(char) def isNegation(char): return char == '!' #print(vars(formula)) for i,char in enumerate(formula.s): if isBlacklisted(char): return False print(char) prev = formula.s[i-1] if i>0 else None #None, gdy jesteśmy na pierwszym znaku if isSign(char): if (not isNegation(char)): if isSign(prev) and not isNegation(prev): # tylko negacje mogą się powtarzać po innym znaku return False else: if isVariable(prev): # obrona przed a!>b return False else: #if current char is a variable if isVariable(prev) and prev is not None: #Obrona abc>d print("previous is also a variable"); return False return True class RegexInterpreter(AbstractInterpreter): def __init__(self): #check if grep is available import subprocess r=subprocess.run("grep") def isValid(self,formula)->bool: make_reg = lambda formula,pattern: 'echo "{0}" | grep -P "{1}"'.format(formula,pattern) def check_assertion(formula, pattern): result = subprocess.run([make_reg(formula,pattern)], shell=True, stdout=subprocess.PIPE) return len(result.stdout)>0 result = subprocess.run([make_reg(formula,'^(\((?:[^()]++|(?1))*\))$')], shell=True, stdout=subprocess.PIPE) isValid = len(result.stdout)>0 if not isValid: return False #assertions assertions = ['(?:[>|&|\|=][\(\)]*){2,}','\((?:[>|&|\|=][\(\)]*)','[a-z]{2,}','\((?:[>|&|\|=|!])?\)'] for assertion in assertions: if not check_assertion(formula,assertion): return False return True # (?:[>|&|\|=][\(\)]*){2,} - czy powtarzają się jakieś operatory obok siebie? # echo "formuła" | grep -P "regex" - to jeżeli coś zwróci to znaczy, że mamy dopasowanie #najpierw sprawdzamy, czy parentices są ok #^(\((?:[^()]++|(?1))*\))$ - powinno zwrócić cały nasz string #potem sprawdzamy czy dopasuje cokolwiek co może być nie tak # \((?:[>|&|\|=][\(\)]*) - (>b) # [a-z]{2,} - czy powtarzają się jakieś lierki obok siebie? # \((?:[>|&|\|=|!])?\) - czy istnieją puste nawiasy, bądź nawiasy z samym operatorem? class Formula: def __init__(self, formula_string:str, interpreter:AbstractInterpreter): self.s = formula_string self.__i = interpreter if not self.isValid(self.__i): assert "formula in invalid!" else: print("given formula is valid") def isValid(self, interpreter)->bool: return interpreter.isValid(self) #g = RegexInterpreter() i = SimpleInterpreter() print(sys.argv) if sys.argv[1] == '-f': #open from file print("opening from file") g = open(sys.argv[1], 'r') u = g.readlines() for l in u: Formula(l,i) else: Formula( sys.argv[1],i)