Commit e71ba9bd authored by Kateřina Sloupová's avatar Kateřina Sloupová
Browse files

EFA removed, DFA and NFA divided, fja_checker prepared for regex related homework

parent bbf32586
Pipeline #57282 failed with stage
in 19 seconds
......@@ -6,7 +6,7 @@ start: init production* final;
init: (INIT EQUALS statename | );
production: LEFT_PARENTHESIS statename COMMA statename RIGHT_PARENTHESIS EQUALS stateset;
production: LEFT_PARENTHESIS statename COMMA (statename | EPSILON) RIGHT_PARENTHESIS EQUALS stateset;
stateset: LEFT_BRACKET (statename (COMMA statename)* | ) RIGHT_BRACKET;
......@@ -26,6 +26,7 @@ LEFT_BRACKET : '{';
RIGHT_BRACKET : '}';
COMMA : ',';
FINAL : ('final');
EPSILON : ('ε' | '\\''e');
STATE : [a-zA-Z0-9]+;
/* Characters to be ignored */
......
......@@ -8,27 +8,29 @@ import sys
def serializedATN():
with StringIO() as buf:
buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\f")
buf.write(":\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7")
buf.write("\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\3\2\3\2\3\2\3\2\3\2")
buf.write("\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3")
buf.write("\t\3\t\3\t\3\t\3\t\3\n\6\n\60\n\n\r\n\16\n\61\3\13\6\13")
buf.write("\65\n\13\r\13\16\13\66\3\13\3\13\2\2\f\3\3\5\4\7\5\t\6")
buf.write("\13\7\r\b\17\t\21\n\23\13\25\f\3\2\4\5\2\62;C\\c|\5\2")
buf.write("\13\f\17\17\"\"\2;\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2")
buf.write("\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21")
buf.write("\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\3\27\3\2\2\2\5\34\3")
buf.write("\2\2\2\7\36\3\2\2\2\t \3\2\2\2\13\"\3\2\2\2\r$\3\2\2\2")
buf.write("\17&\3\2\2\2\21(\3\2\2\2\23/\3\2\2\2\25\64\3\2\2\2\27")
buf.write("\30\7k\2\2\30\31\7p\2\2\31\32\7k\2\2\32\33\7v\2\2\33\4")
buf.write("\3\2\2\2\34\35\7?\2\2\35\6\3\2\2\2\36\37\7*\2\2\37\b\3")
buf.write("\2\2\2 !\7+\2\2!\n\3\2\2\2\"#\7}\2\2#\f\3\2\2\2$%\7\177")
buf.write("\2\2%\16\3\2\2\2&\'\7.\2\2\'\20\3\2\2\2()\7h\2\2)*\7k")
buf.write("\2\2*+\7p\2\2+,\7c\2\2,-\7n\2\2-\22\3\2\2\2.\60\t\2\2")
buf.write("\2/.\3\2\2\2\60\61\3\2\2\2\61/\3\2\2\2\61\62\3\2\2\2\62")
buf.write("\24\3\2\2\2\63\65\t\3\2\2\64\63\3\2\2\2\65\66\3\2\2\2")
buf.write("\66\64\3\2\2\2\66\67\3\2\2\2\678\3\2\2\289\b\13\2\29\26")
buf.write("\3\2\2\2\5\2\61\66\3\b\2\2")
buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\r")
buf.write("A\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7")
buf.write("\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\3\2\3\2\3\2")
buf.write("\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3")
buf.write("\b\3\t\3\t\3\t\3\t\3\t\3\t\3\n\3\n\3\n\5\n\64\n\n\3\13")
buf.write("\6\13\67\n\13\r\13\16\138\3\f\6\f<\n\f\r\f\16\f=\3\f\3")
buf.write("\f\2\2\r\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f")
buf.write("\27\r\3\2\4\5\2\62;C\\c|\5\2\13\f\17\17\"\"\2C\2\3\3\2")
buf.write("\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2")
buf.write("\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2")
buf.write("\25\3\2\2\2\2\27\3\2\2\2\3\31\3\2\2\2\5\36\3\2\2\2\7 ")
buf.write("\3\2\2\2\t\"\3\2\2\2\13$\3\2\2\2\r&\3\2\2\2\17(\3\2\2")
buf.write("\2\21*\3\2\2\2\23\63\3\2\2\2\25\66\3\2\2\2\27;\3\2\2\2")
buf.write("\31\32\7k\2\2\32\33\7p\2\2\33\34\7k\2\2\34\35\7v\2\2\35")
buf.write("\4\3\2\2\2\36\37\7?\2\2\37\6\3\2\2\2 !\7*\2\2!\b\3\2\2")
buf.write("\2\"#\7+\2\2#\n\3\2\2\2$%\7}\2\2%\f\3\2\2\2&\'\7\177\2")
buf.write("\2\'\16\3\2\2\2()\7.\2\2)\20\3\2\2\2*+\7h\2\2+,\7k\2\2")
buf.write(",-\7p\2\2-.\7c\2\2./\7n\2\2/\22\3\2\2\2\60\64\7\u03b7")
buf.write("\2\2\61\62\7^\2\2\62\64\7g\2\2\63\60\3\2\2\2\63\61\3\2")
buf.write("\2\2\64\24\3\2\2\2\65\67\t\2\2\2\66\65\3\2\2\2\678\3\2")
buf.write("\2\28\66\3\2\2\289\3\2\2\29\26\3\2\2\2:<\t\3\2\2;:\3\2")
buf.write("\2\2<=\3\2\2\2=;\3\2\2\2=>\3\2\2\2>?\3\2\2\2?@\b\f\2\2")
buf.write("@\30\3\2\2\2\6\2\638=\3\b\2\2")
return buf.getvalue()
......@@ -46,8 +48,9 @@ class NFALexer(Lexer):
RIGHT_BRACKET = 6
COMMA = 7
FINAL = 8
STATE = 9
WS = 10
EPSILON = 9
STATE = 10
WS = 11
channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ]
......@@ -58,11 +61,11 @@ class NFALexer(Lexer):
symbolicNames = [ "<INVALID>",
"INIT", "EQUALS", "LEFT_PARENTHESIS", "RIGHT_PARENTHESIS", "LEFT_BRACKET",
"RIGHT_BRACKET", "COMMA", "FINAL", "STATE", "WS" ]
"RIGHT_BRACKET", "COMMA", "FINAL", "EPSILON", "STATE", "WS" ]
ruleNames = [ "INIT", "EQUALS", "LEFT_PARENTHESIS", "RIGHT_PARENTHESIS",
"LEFT_BRACKET", "RIGHT_BRACKET", "COMMA", "FINAL", "STATE",
"WS" ]
"LEFT_BRACKET", "RIGHT_BRACKET", "COMMA", "FINAL", "EPSILON",
"STATE", "WS" ]
grammarFileName = "NFA.g4"
......
......@@ -11,25 +11,26 @@ else:
def serializedATN():
with StringIO() as buf:
buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\f")
buf.write(":\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\3\2")
buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\r")
buf.write("=\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\3\2")
buf.write("\3\2\7\2\21\n\2\f\2\16\2\24\13\2\3\2\3\2\3\3\3\3\3\3\3")
buf.write("\3\5\3\34\n\3\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\5\3\5")
buf.write("\3\5\3\5\7\5*\n\5\f\5\16\5-\13\5\3\5\5\5\60\n\5\3\5\3")
buf.write("\5\3\6\3\6\3\6\3\6\3\7\3\7\3\7\2\2\b\2\4\6\b\n\f\2\2\2")
buf.write("\67\2\16\3\2\2\2\4\33\3\2\2\2\6\35\3\2\2\2\b%\3\2\2\2")
buf.write("\n\63\3\2\2\2\f\67\3\2\2\2\16\22\5\4\3\2\17\21\5\6\4\2")
buf.write("\20\17\3\2\2\2\21\24\3\2\2\2\22\20\3\2\2\2\22\23\3\2\2")
buf.write("\2\23\25\3\2\2\2\24\22\3\2\2\2\25\26\5\n\6\2\26\3\3\2")
buf.write("\2\2\27\30\7\3\2\2\30\31\7\4\2\2\31\34\5\f\7\2\32\34\3")
buf.write("\2\2\2\33\27\3\2\2\2\33\32\3\2\2\2\34\5\3\2\2\2\35\36")
buf.write("\7\5\2\2\36\37\5\f\7\2\37 \7\t\2\2 !\5\f\7\2!\"\7\6\2")
buf.write("\2\"#\7\4\2\2#$\5\b\5\2$\7\3\2\2\2%/\7\7\2\2&+\5\f\7\2")
buf.write("\'(\7\t\2\2(*\5\f\7\2)\'\3\2\2\2*-\3\2\2\2+)\3\2\2\2+")
buf.write(",\3\2\2\2,\60\3\2\2\2-+\3\2\2\2.\60\3\2\2\2/&\3\2\2\2")
buf.write("/.\3\2\2\2\60\61\3\2\2\2\61\62\7\b\2\2\62\t\3\2\2\2\63")
buf.write("\64\7\n\2\2\64\65\7\4\2\2\65\66\5\b\5\2\66\13\3\2\2\2")
buf.write("\678\7\13\2\28\r\3\2\2\2\6\22\33+/")
buf.write("\3\5\3\34\n\3\3\4\3\4\3\4\3\4\3\4\5\4#\n\4\3\4\3\4\3\4")
buf.write("\3\4\3\5\3\5\3\5\3\5\7\5-\n\5\f\5\16\5\60\13\5\3\5\5\5")
buf.write("\63\n\5\3\5\3\5\3\6\3\6\3\6\3\6\3\7\3\7\3\7\2\2\b\2\4")
buf.write("\6\b\n\f\2\2\2;\2\16\3\2\2\2\4\33\3\2\2\2\6\35\3\2\2\2")
buf.write("\b(\3\2\2\2\n\66\3\2\2\2\f:\3\2\2\2\16\22\5\4\3\2\17\21")
buf.write("\5\6\4\2\20\17\3\2\2\2\21\24\3\2\2\2\22\20\3\2\2\2\22")
buf.write("\23\3\2\2\2\23\25\3\2\2\2\24\22\3\2\2\2\25\26\5\n\6\2")
buf.write("\26\3\3\2\2\2\27\30\7\3\2\2\30\31\7\4\2\2\31\34\5\f\7")
buf.write("\2\32\34\3\2\2\2\33\27\3\2\2\2\33\32\3\2\2\2\34\5\3\2")
buf.write("\2\2\35\36\7\5\2\2\36\37\5\f\7\2\37\"\7\t\2\2 #\5\f\7")
buf.write("\2!#\7\13\2\2\" \3\2\2\2\"!\3\2\2\2#$\3\2\2\2$%\7\6\2")
buf.write("\2%&\7\4\2\2&\'\5\b\5\2\'\7\3\2\2\2(\62\7\7\2\2).\5\f")
buf.write("\7\2*+\7\t\2\2+-\5\f\7\2,*\3\2\2\2-\60\3\2\2\2.,\3\2\2")
buf.write("\2./\3\2\2\2/\63\3\2\2\2\60.\3\2\2\2\61\63\3\2\2\2\62")
buf.write(")\3\2\2\2\62\61\3\2\2\2\63\64\3\2\2\2\64\65\7\b\2\2\65")
buf.write("\t\3\2\2\2\66\67\7\n\2\2\678\7\4\2\289\5\b\5\29\13\3\2")
buf.write("\2\2:;\7\f\2\2;\r\3\2\2\2\7\22\33\".\62")
return buf.getvalue()
......@@ -48,7 +49,7 @@ class NFAParser ( Parser ):
symbolicNames = [ "<INVALID>", "INIT", "EQUALS", "LEFT_PARENTHESIS",
"RIGHT_PARENTHESIS", "LEFT_BRACKET", "RIGHT_BRACKET",
"COMMA", "FINAL", "STATE", "WS" ]
"COMMA", "FINAL", "EPSILON", "STATE", "WS" ]
RULE_start = 0
RULE_init = 1
......@@ -68,8 +69,9 @@ class NFAParser ( Parser ):
RIGHT_BRACKET=6
COMMA=7
FINAL=8
STATE=9
WS=10
EPSILON=9
STATE=10
WS=11
def __init__(self, input:TokenStream, output:TextIO = sys.stdout):
super().__init__(input, output)
......@@ -235,6 +237,9 @@ class NFAParser ( Parser ):
return self.getTypedRuleContext(NFAParser.StatesetContext,0)
def EPSILON(self):
return self.getToken(NFAParser.EPSILON, 0)
def getRuleIndex(self):
return NFAParser.RULE_production
......@@ -261,13 +266,25 @@ class NFAParser ( Parser ):
self.statename()
self.state = 29
self.match(NFAParser.COMMA)
self.state = 30
self.statename()
self.state = 31
self.match(NFAParser.RIGHT_PARENTHESIS)
self.state = 32
self._errHandler.sync(self)
token = self._input.LA(1)
if token in [NFAParser.STATE]:
self.state = 30
self.statename()
pass
elif token in [NFAParser.EPSILON]:
self.state = 31
self.match(NFAParser.EPSILON)
pass
else:
raise NoViableAltException(self)
self.state = 34
self.match(NFAParser.RIGHT_PARENTHESIS)
self.state = 35
self.match(NFAParser.EQUALS)
self.state = 33
self.state = 36
self.stateset()
except RecognitionException as re:
localctx.exception = re
......@@ -324,23 +341,23 @@ class NFAParser ( Parser ):
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
self.state = 35
self.state = 38
self.match(NFAParser.LEFT_BRACKET)
self.state = 45
self.state = 48
self._errHandler.sync(self)
token = self._input.LA(1)
if token in [NFAParser.STATE]:
self.state = 36
self.state = 39
self.statename()
self.state = 41
self.state = 44
self._errHandler.sync(self)
_la = self._input.LA(1)
while _la==NFAParser.COMMA:
self.state = 37
self.state = 40
self.match(NFAParser.COMMA)
self.state = 38
self.state = 41
self.statename()
self.state = 43
self.state = 46
self._errHandler.sync(self)
_la = self._input.LA(1)
......@@ -350,7 +367,7 @@ class NFAParser ( Parser ):
else:
raise NoViableAltException(self)
self.state = 47
self.state = 50
self.match(NFAParser.RIGHT_BRACKET)
except RecognitionException as re:
localctx.exception = re
......@@ -397,11 +414,11 @@ class NFAParser ( Parser ):
self.enterRule(localctx, 8, self.RULE_final)
try:
self.enterOuterAlt(localctx, 1)
self.state = 49
self.state = 52
self.match(NFAParser.FINAL)
self.state = 50
self.state = 53
self.match(NFAParser.EQUALS)
self.state = 51
self.state = 54
self.stateset()
except RecognitionException as re:
localctx.exception = re
......@@ -441,7 +458,7 @@ class NFAParser ( Parser ):
self.enterRule(localctx, 10, self.RULE_statename)
try:
self.enterOuterAlt(localctx, 1)
self.state = 53
self.state = 56
self.match(NFAParser.STATE)
except RecognitionException as re:
localctx.exception = re
......
......@@ -28,8 +28,8 @@ POS_ITER : '^+';
CONCAT : '.';
UNION : '+';
ALPHABET : [a-zA-Z0-9];
EPSILON : 'ε';
EMPTYSET : '∅';
EPSILON : ('ε' | '\\''e');
EMPTYSET : ('∅' | '\\''0');
/* Characters to be ignored */
WS : [ \r\t\n]+ -> skip ;
......@@ -9,24 +9,26 @@ import sys
def serializedATN():
with StringIO() as buf:
buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\f")
buf.write("\64\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t")
buf.write("\67\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t")
buf.write("\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\3\2\3\2\3\3\3\3\3")
buf.write("\4\3\4\3\4\5\4\37\n\4\3\5\3\5\3\5\3\6\3\6\3\7\3\7\3\b")
buf.write("\3\b\3\t\3\t\3\n\3\n\3\13\6\13/\n\13\r\13\16\13\60\3\13")
buf.write("\3\13\2\2\f\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25")
buf.write("\f\3\2\4\5\2\62;C\\c|\5\2\13\f\17\17\"\"\2\65\2\3\3\2")
buf.write("\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2")
buf.write("\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2")
buf.write("\25\3\2\2\2\3\27\3\2\2\2\5\31\3\2\2\2\7\36\3\2\2\2\t ")
buf.write("\3\2\2\2\13#\3\2\2\2\r%\3\2\2\2\17\'\3\2\2\2\21)\3\2\2")
buf.write("\2\23+\3\2\2\2\25.\3\2\2\2\27\30\7*\2\2\30\4\3\2\2\2\31")
buf.write("\32\7+\2\2\32\6\3\2\2\2\33\37\7,\2\2\34\35\7`\2\2\35\37")
buf.write("\7,\2\2\36\33\3\2\2\2\36\34\3\2\2\2\37\b\3\2\2\2 !\7`")
buf.write("\2\2!\"\7-\2\2\"\n\3\2\2\2#$\7\60\2\2$\f\3\2\2\2%&\7-")
buf.write("\2\2&\16\3\2\2\2\'(\t\2\2\2(\20\3\2\2\2)*\7\u03b7\2\2")
buf.write("*\22\3\2\2\2+,\7\u2207\2\2,\24\3\2\2\2-/\t\3\2\2.-\3\2")
buf.write("\2\2/\60\3\2\2\2\60.\3\2\2\2\60\61\3\2\2\2\61\62\3\2\2")
buf.write("\2\62\63\b\13\2\2\63\26\3\2\2\2\5\2\36\60\3\b\2\2")
buf.write("\3\b\3\t\3\t\3\t\5\t-\n\t\3\n\3\n\3\13\6\13\62\n\13\r")
buf.write("\13\16\13\63\3\13\3\13\2\2\f\3\3\5\4\7\5\t\6\13\7\r\b")
buf.write("\17\t\21\n\23\13\25\f\3\2\4\5\2\62;C\\c|\5\2\13\f\17\17")
buf.write("\"\"\29\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2")
buf.write("\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2")
buf.write("\2\23\3\2\2\2\2\25\3\2\2\2\3\27\3\2\2\2\5\31\3\2\2\2\7")
buf.write("\36\3\2\2\2\t \3\2\2\2\13#\3\2\2\2\r%\3\2\2\2\17\'\3\2")
buf.write("\2\2\21,\3\2\2\2\23.\3\2\2\2\25\61\3\2\2\2\27\30\7*\2")
buf.write("\2\30\4\3\2\2\2\31\32\7+\2\2\32\6\3\2\2\2\33\37\7,\2\2")
buf.write("\34\35\7`\2\2\35\37\7,\2\2\36\33\3\2\2\2\36\34\3\2\2\2")
buf.write("\37\b\3\2\2\2 !\7`\2\2!\"\7-\2\2\"\n\3\2\2\2#$\7\60\2")
buf.write("\2$\f\3\2\2\2%&\7-\2\2&\16\3\2\2\2\'(\t\2\2\2(\20\3\2")
buf.write("\2\2)-\7\u03b7\2\2*+\7^\2\2+-\7g\2\2,)\3\2\2\2,*\3\2\2")
buf.write("\2-\22\3\2\2\2./\7\u2207\2\2/\24\3\2\2\2\60\62\t\3\2\2")
buf.write("\61\60\3\2\2\2\62\63\3\2\2\2\63\61\3\2\2\2\63\64\3\2\2")
buf.write("\2\64\65\3\2\2\2\65\66\b\13\2\2\66\26\3\2\2\2\6\2\36,")
buf.write("\63\3\b\2\2")
return buf.getvalue()
......@@ -52,7 +54,7 @@ class RegExLexer(Lexer):
modeNames = [ "DEFAULT_MODE" ]
literalNames = [ "<INVALID>",
"'('", "')'", "'^+'", "'.'", "'+'", "'\u03B5'", "'\u2205'" ]
"'('", "')'", "'^+'", "'.'", "'+'", "'\u2205'" ]
symbolicNames = [ "<INVALID>",
"LEFT_PAR", "RIGHT_PAR", "ITER", "POS_ITER", "CONCAT", "UNION",
......
from parser import Parser
from common import State, Character, Eps, Terminal, Nonterminal
from automata import Composition as comp
from dfa import Composition as comp
from typing import Set, Dict, Tuple, Union
from copy import deepcopy
from antlr4 import RecognitionException
from reg import RegGrammar, DFA, NFA, EFA, RegEx
from reg import RegGrammar, DFA, NFA, RegEx
def make_dfa(states: Set[str], characters: Set[str],
......@@ -82,7 +82,7 @@ def nfa_e():
transition: Dict[Tuple[State, Union[Character, Eps]], Set[State]] = \
{(q0, e): {q1}, (q1, a): {q0}, (q1, d): {q3}, (q1, e): {q2},
(q2, a): {q3}, (q3, e): {q4}, (q4, b): {q3}, (q4, c): {q2}}
nfae = EFA({q0, q1, q2, q3, q4}, {a, b, c, d}, transition, q0, {q2})
nfae = NFA({q0, q1, q2, q3, q4}, {a, b, c, d}, transition, q0, {q2})
return nfae
def dfa_eq(str1, str2):
......@@ -99,13 +99,13 @@ def dfa_eq(str1, str2):
def regex_test(str):
parser = Parser()
ast = parser.str_to_reg(str)
str1 = parser.reg_to_str(ast)
ast = parser.str_to_regex(str)
str1 = parser.regex_to_str(ast)
#ast1 = parser.str_to_reg(str1)
print(str)
print(str1)
#print(parser.reg_to_str(ast1))
efa = ast.reg_to_efa()
efa = ast.regex_to_efa()
print(parser.nfa_to_str(efa))
def main():
......@@ -224,11 +224,11 @@ def main():
dfa_4 = make_dfa({"q_0", "q_1"}, {"a"}, {("q_0", "a"): "q_1", ("q_1", "a"): "q_1"}, "q_0", {"q_1"})
print(parser.dfa_to_str(dfa_4, True))
print()
dfareg = dfa_4.dfa_to_reg()
dfareg = dfa_4.dfa_to_reggrammar()
print("DFA transformed to REG:")
print(parser.gra_to_str(dfareg, True))
print(parser.reggrammar_to_str(dfareg, True))
print()
regdfa = dfareg.reg_to_nfa()
regdfa = dfareg.reggrammar_to_nfa()
print("REG transformed to NFA:")
print(parser.nfa_to_str(regdfa, True))
print()
......@@ -251,7 +251,7 @@ def main():
print(parser.dfa_to_str(det, True))
print("__________________________________")
print("NFAE.eliminate_epsilon()")
print("NFA.eliminate_epsilon()")
print("Elimination of epsilon steps in NFA.")
nfae = nfa_e()
print(parser.nfa_to_str(nfae))
......@@ -269,8 +269,8 @@ def main():
print()
print("Try equality of automata from strings:")
str1 = "init=0 (0, a)=1 (0, b)=2 (1, a)=1 (2,b)=2 final={1,2}"
str2 = "init=q1 (q1, a)=q2 (q1, b)=q3 (q2,a)=q2 (q3,b)=q4 (q4,b)=q4 final={q3,q4,q2}"
print(dfa_eq(str1, str2))
str2 = "init=q0 (q0, a)=q1 (q0, b)=q2 (q1,a)=q1 (q2,b)=q3 (q3,b)=q3 final={q1, q2, q3}"
print(dfa_eq(str1, str2).left_counterexample, dfa_eq(str1, str2).right_counterexample)
print()
print("Input of parser.str_to_nfa:")
......@@ -279,6 +279,12 @@ def main():
print("Output of parser.nfa_to_str should be identical:")
print(parser.nfa_to_str(nfa_p))
print()
print("Parsing EFA:")
print("init=0 (0,x)={1} (0,\e)={2} (1,x)={1} (1,y)={1} (2,\e)={0,1,2} (2,b)={1,2} final={2,3}")
efa_p = parser.str_to_nfa("init=0 (0,x)={1} (0,\e)={2} (1,x)={1} (1,y)={1} (2,\e)={0,1,2} (2,b)={1,2} final={2,3}")
print("Output of parser.nfa_to_str should be identical:")
print(parser.nfa_to_str(efa_p))
print()
print("Testing regex")
regex_test("(c.(b.b*.(c+ab)+cb)*.(ε+a))+b")
......
......@@ -5,7 +5,7 @@ import enum
from copy import deepcopy
from collections import deque
from string import ascii_uppercase
from common import Character, State, Eps, Terminal, Nonterminal
from common import Character, State, Terminal, Nonterminal
class Composition(Enum):
......@@ -317,7 +317,7 @@ class DFA:
i += 1
return dfa
def dfa_to_reg(self) -> Any:
def dfa_to_reggrammar(self) -> Any:
from grammars import RegGrammar
nonterminals: Set[Nonterminal] = set()
......@@ -420,116 +420,4 @@ class DFA:
def is_canonical(self) -> bool:
canonic = self.canonize()
return DFA.is_part_identical(self, canonic)
class NFA:
Transition = Dict[Tuple[State, Character], Set[State]]
type_var = TypeVar('type_var')
def __init__(self, states: Set[State],
characters: Set[Character],
transition: Transition,
init: State,
final: Set[State]):
self.states = states
self.characters = characters
self.transition = transition
self.init = init
self.final = final
def determinize(self) -> DFA:
states: Set[FrozenSet[State]] = set()
states.add(frozenset({self.init}))
transition = {}
final = set()
done: Set[FrozenSet[State]] = set()
while len(states.difference(done)) > 0:
subset = (states.difference(done)).pop() # arbitrary element from set
if len(subset.intersection(self.final)) > 0:
final.add(subset)
for character in self.characters:
new_subset: Set[State] = set()
for state in subset:
if (state, character) in self.transition:
new_subset = new_subset.union(self.transition[state, character])
states.add(frozenset(new_subset))
transition[subset, character] = frozenset(new_subset)
done.add(subset)
new_states: Set[State] = set()
new_transition: Dict[Tuple[State, Character], State] = dict()
new_final: Set[State] = set()
for state_set in states:
new_states.add(self.unset(state_set))
for state_set in final:
new_final.add(self.unset(state_set))
for state_set, character in transition:
new_transition[self.unset(state_set), character] = self.unset(transition[state_set, character])
return DFA(new_states, self.characters, new_transition, self.init, new_final)
def unset(self, states: FrozenSet[State]) -> State:
return State('_'.join(set(map(lambda x: x.name, sorted(states, key=lambda x: x.name)))))
class EFA:
Transition = Dict[Tuple[State, Union[Character, Eps]], Set[State]]
type_var = TypeVar('type_var')
def __init__(self, states: Set[State],
characters: Set[Character],
transition: Transition,
init: State,
final: Set[State]):
self.states = states
self.characters = characters
self.transition = transition
self.init = init
self.final = final
def eliminate_epsilon(self) -> NFA:
surroundings: Dict[State, Set[State]] = {}
for state in self.states:
surroundings[state] = self.epsilon_surroundings(state)
new_transition: Dict[Tuple[State, Character], Set[State]] = {}
for state in self.states:
for character in self.characters:
reached_states = set()
if (state, character) in self.transition:
reached_states.update(self.transition[state, character])
for eps_state in surroundings[state]:
if (eps_state, character) in self.transition:
reached_states.update(self.transition[eps_state, character])
if len(reached_states) > 0:
new_transition[state, character] = deepcopy(reached_states)
for reached in reached_states:
new_transition[state, character].update(surroundings[reached])
new_final = deepcopy(self.final)
if surroundings[self.init].intersection(self.final):
new_final.add(self.init)
return NFA(self.states, self.characters, new_transition, self.init, new_final)
def epsilon_surroundings(self, state: State) -> Set[State]:
reached: Deque[State] = deque([state])
reachable: Set[State] = {state}
eps = Eps()
while len(reached) > 0:
actual = reached.popleft()
if (actual, eps) in self.transition:
for dest_state in self.transition[actual, eps]:
if dest_state not in reachable:
reached.append(dest_state)
reachable.add(dest_state)
return reachable
\ No newline at end of file
return DFA.is_part_identical(self, canonic)
\ No newline at end of file
from typing import Tuple
import reg
import sys
import signal
def parse_transform(string: str, automaton_type: str) -> reg.DFA:
def get_task(string: str) -> Tuple[str, str]:
assert len(string) >= 7, "Teacher solution could not be parsed correctly."
teacher_type, task = string.split("-", 1)
if len(task) > 3:
task, _ = task.split("-", 1)
assert len(teacher_type) == 3 and len(task) == 3, "Teacher solution could not be parsed correctly."
return (teacher_type, task)
def dfa_transform(string: str, automaton_type: str) -> reg.DFA:
try:
parser = reg.Parser()
if automaton_type == "DFA":
if automaton_type in {"DFA", "TOT", "MIN", "TOC", "MIC"}:
automaton = parser.str_to_dfa(string)
elif automaton_type == "NFA":
automaton = parser.str_to_nfa(string).determinize()
elif automaton_type == "EFA":
automaton = parser.str_to_nfa(string).eliminate_epsilon().determinize()
elif automaton_type == "GRA":
automaton = parser.str_to_reggrammar(string).reggrammar_to_nfa().determinize()
elif automaton_type == "REG":
# test prints
# regex = parser.str_to_regex(string)
# efa = regex.regex_to_efa()
# nfa = efa.eliminate_epsilon()
# dfa = nfa.determinize()
# print(parser.regex_to_str(regex))
# print(parser.nfa_to_str(efa))
# print(parser.nfa_to_str(nfa))
# print(parser.dfa_to_str(dfa))
automaton = parser.str_to_regex(string).regex_to_efa().eliminate_epsilon().determinize()
return automaton
except reg.Parser.ParsingError as message:
print("Parsing error:", message)
except reg.ParsingError as ex:
print("Chyba při parsování.")
exit(1)
except Exception as ex:
print("Chyba při parsování.")
exit(1)