105 lines
3.7 KiB
Python
105 lines
3.7 KiB
Python
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)
|
|
|
|
|
|
|
|
|