Loading CFG.g4 +1 −1 Original line number Diff line number Diff line Loading @@ -10,7 +10,7 @@ rewrite: (term_or_nonterm+ | EPSILON); term_or_nonterm: (TERMINAL | nonterminal); nonterminal: (CAPS | (LEFT_ANGLE symbol+ RIGHT_ANGLE) | (symbol APOSTROPHE+)); nonterminal: (CAPS | (LEFT_ANGLE symbol+ RIGHT_ANGLE (APOSTROPHE*)) | (symbol APOSTROPHE+)); symbol: (TERMINAL | CAPS | UNDERSCORE); Loading CFGParser.py +40 −27 Original line number Diff line number Diff line Loading @@ -12,29 +12,31 @@ else: def serializedATN(): with StringIO() as buf: buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\r") buf.write("G\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("L\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\3\2\7\2\22\n\2\f\2\16\2\25\13\2\3\2\3\2\3\2\5\2\32") buf.write("\n\2\3\3\3\3\3\3\3\3\3\3\7\3!\n\3\f\3\16\3$\13\3\3\3\3") buf.write("\3\3\4\6\4)\n\4\r\4\16\4*\3\4\5\4.\n\4\3\5\3\5\5\5\62") buf.write("\n\5\3\6\3\6\3\6\6\6\67\n\6\r\6\16\68\3\6\3\6\3\6\3\6") buf.write("\6\6?\n\6\r\6\16\6@\5\6C\n\6\3\7\3\7\3\7\2\2\b\2\4\6\b") buf.write("\n\f\2\3\3\2\6\b\2J\2\23\3\2\2\2\4\33\3\2\2\2\6-\3\2\2") buf.write("\2\b\61\3\2\2\2\nB\3\2\2\2\fD\3\2\2\2\16\17\5\4\3\2\17") buf.write("\20\7\f\2\2\20\22\3\2\2\2\21\16\3\2\2\2\22\25\3\2\2\2") buf.write("\23\21\3\2\2\2\23\24\3\2\2\2\24\26\3\2\2\2\25\23\3\2\2") buf.write("\2\26\31\5\4\3\2\27\32\7\f\2\2\30\32\3\2\2\2\31\27\3\2") buf.write("\2\2\31\30\3\2\2\2\32\3\3\2\2\2\33\34\5\n\6\2\34\"\7\t") buf.write("\2\2\35\36\5\6\4\2\36\37\7\13\2\2\37!\3\2\2\2 \35\3\2") buf.write("\2\2!$\3\2\2\2\" \3\2\2\2\"#\3\2\2\2#%\3\2\2\2$\"\3\2") buf.write("\2\2%&\5\6\4\2&\5\3\2\2\2\')\5\b\5\2(\'\3\2\2\2)*\3\2") buf.write("\2\2*(\3\2\2\2*+\3\2\2\2+.\3\2\2\2,.\7\n\2\2-(\3\2\2\2") buf.write("-,\3\2\2\2.\7\3\2\2\2/\62\7\7\2\2\60\62\5\n\6\2\61/\3") buf.write("\2\2\2\61\60\3\2\2\2\62\t\3\2\2\2\63C\7\b\2\2\64\66\7") buf.write("\3\2\2\65\67\5\f\7\2\66\65\3\2\2\2\678\3\2\2\28\66\3\2") buf.write("\2\289\3\2\2\29:\3\2\2\2:;\7\4\2\2;C\3\2\2\2<>\5\f\7\2") buf.write("=?\7\5\2\2>=\3\2\2\2?@\3\2\2\2@>\3\2\2\2@A\3\2\2\2AC\3") buf.write("\2\2\2B\63\3\2\2\2B\64\3\2\2\2B<\3\2\2\2C\13\3\2\2\2D") buf.write("E\t\2\2\2E\r\3\2\2\2\13\23\31\"*-\618@B") buf.write("\n\5\3\6\3\6\3\6\6\6\67\n\6\r\6\16\68\3\6\3\6\7\6=\n\6") buf.write("\f\6\16\6@\13\6\3\6\3\6\6\6D\n\6\r\6\16\6E\5\6H\n\6\3") buf.write("\7\3\7\3\7\2\2\b\2\4\6\b\n\f\2\3\3\2\6\b\2P\2\23\3\2\2") buf.write("\2\4\33\3\2\2\2\6-\3\2\2\2\b\61\3\2\2\2\nG\3\2\2\2\fI") buf.write("\3\2\2\2\16\17\5\4\3\2\17\20\7\f\2\2\20\22\3\2\2\2\21") buf.write("\16\3\2\2\2\22\25\3\2\2\2\23\21\3\2\2\2\23\24\3\2\2\2") buf.write("\24\26\3\2\2\2\25\23\3\2\2\2\26\31\5\4\3\2\27\32\7\f\2") buf.write("\2\30\32\3\2\2\2\31\27\3\2\2\2\31\30\3\2\2\2\32\3\3\2") buf.write("\2\2\33\34\5\n\6\2\34\"\7\t\2\2\35\36\5\6\4\2\36\37\7") buf.write("\13\2\2\37!\3\2\2\2 \35\3\2\2\2!$\3\2\2\2\" \3\2\2\2\"") buf.write("#\3\2\2\2#%\3\2\2\2$\"\3\2\2\2%&\5\6\4\2&\5\3\2\2\2\'") buf.write(")\5\b\5\2(\'\3\2\2\2)*\3\2\2\2*(\3\2\2\2*+\3\2\2\2+.\3") buf.write("\2\2\2,.\7\n\2\2-(\3\2\2\2-,\3\2\2\2.\7\3\2\2\2/\62\7") buf.write("\7\2\2\60\62\5\n\6\2\61/\3\2\2\2\61\60\3\2\2\2\62\t\3") buf.write("\2\2\2\63H\7\b\2\2\64\66\7\3\2\2\65\67\5\f\7\2\66\65\3") buf.write("\2\2\2\678\3\2\2\28\66\3\2\2\289\3\2\2\29:\3\2\2\2:>\7") buf.write("\4\2\2;=\7\5\2\2<;\3\2\2\2=@\3\2\2\2><\3\2\2\2>?\3\2\2") buf.write("\2?H\3\2\2\2@>\3\2\2\2AC\5\f\7\2BD\7\5\2\2CB\3\2\2\2D") buf.write("E\3\2\2\2EC\3\2\2\2EF\3\2\2\2FH\3\2\2\2G\63\3\2\2\2G\64") buf.write("\3\2\2\2GA\3\2\2\2H\13\3\2\2\2IJ\t\2\2\2J\r\3\2\2\2\f") buf.write("\23\31\"*-\618>EG") return buf.getvalue() Loading Loading @@ -411,9 +413,9 @@ class CFGParser ( Parser ): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) self.state = 64 self.state = 69 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,8,self._ctx) la_ = self._interp.adaptivePredict(self._input,9,self._ctx) if la_ == 1: self.state = 49 self.match(CFGParser.CAPS) Loading @@ -436,18 +438,29 @@ class CFGParser ( Parser ): self.state = 56 self.match(CFGParser.RIGHT_ANGLE) self.state = 60 self._errHandler.sync(self) _la = self._input.LA(1) while _la==CFGParser.APOSTROPHE: self.state = 57 self.match(CFGParser.APOSTROPHE) self.state = 62 self._errHandler.sync(self) _la = self._input.LA(1) pass elif la_ == 3: self.state = 58 self.state = 63 self.symbol() self.state = 60 self.state = 65 self._errHandler.sync(self) _la = self._input.LA(1) while True: self.state = 59 self.state = 64 self.match(CFGParser.APOSTROPHE) self.state = 62 self.state = 67 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==CFGParser.APOSTROPHE): Loading Loading @@ -501,7 +514,7 @@ class CFGParser ( Parser ): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) self.state = 66 self.state = 71 _la = self._input.LA(1) if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << CFGParser.UNDERSCORE) | (1 << CFGParser.TERMINAL) | (1 << CFGParser.CAPS))) != 0)): self._errHandler.recoverInline(self) Loading demo.py +1 −1 Original line number Diff line number Diff line Loading @@ -334,7 +334,7 @@ def main(): grammar_test("S->a|aA|\e\nA->a|b|<aBc_JK50l>\n<aBc_JK50l>->AaBa") grammar_test("S->a|aA|\e;A->a|b") grammar_test("S->a|aA|\e;A->a|bS") grammar_test("S'->a|aA''|\e;A''->a|bS'") grammar_test("S'->a|aA''|\e;A''->a|bS'|<ab_0>''") words = dfa_eq("init=1 (1, a)=2 (2,a)=2 (1,b)=3 final={2,3}", "init=A (A, a)=B (A,b)=C (C,b)=C final={B,C}") Loading parser.py +4 −2 Original line number Diff line number Diff line Loading @@ -326,10 +326,12 @@ class CFGBuilder(CFGListener): def visitNonterminal(self, ctx): if ctx.CAPS(): name = str(ctx.CAPS()) elif ctx.LEFT_ANGLE(): name = '<' + ''.join(map(lambda x: self.visitSymbol(x), ctx.symbol())) + '>' if ctx.APOSTROPHE(): name = name + len(ctx.APOSTROPHE())*"'" elif ctx.APOSTROPHE(): name = self.visitSymbol(ctx.symbol(0)) + len(ctx.APOSTROPHE())*"'" else: name = '<' + ''.join(map(lambda x: self.visitSymbol(x), ctx.symbol())) + '>' nonterminal = Nonterminal(name) self.nonterminals.add(nonterminal) Loading Loading
CFG.g4 +1 −1 Original line number Diff line number Diff line Loading @@ -10,7 +10,7 @@ rewrite: (term_or_nonterm+ | EPSILON); term_or_nonterm: (TERMINAL | nonterminal); nonterminal: (CAPS | (LEFT_ANGLE symbol+ RIGHT_ANGLE) | (symbol APOSTROPHE+)); nonterminal: (CAPS | (LEFT_ANGLE symbol+ RIGHT_ANGLE (APOSTROPHE*)) | (symbol APOSTROPHE+)); symbol: (TERMINAL | CAPS | UNDERSCORE); Loading
CFGParser.py +40 −27 Original line number Diff line number Diff line Loading @@ -12,29 +12,31 @@ else: def serializedATN(): with StringIO() as buf: buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\r") buf.write("G\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("L\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\3\2\7\2\22\n\2\f\2\16\2\25\13\2\3\2\3\2\3\2\5\2\32") buf.write("\n\2\3\3\3\3\3\3\3\3\3\3\7\3!\n\3\f\3\16\3$\13\3\3\3\3") buf.write("\3\3\4\6\4)\n\4\r\4\16\4*\3\4\5\4.\n\4\3\5\3\5\5\5\62") buf.write("\n\5\3\6\3\6\3\6\6\6\67\n\6\r\6\16\68\3\6\3\6\3\6\3\6") buf.write("\6\6?\n\6\r\6\16\6@\5\6C\n\6\3\7\3\7\3\7\2\2\b\2\4\6\b") buf.write("\n\f\2\3\3\2\6\b\2J\2\23\3\2\2\2\4\33\3\2\2\2\6-\3\2\2") buf.write("\2\b\61\3\2\2\2\nB\3\2\2\2\fD\3\2\2\2\16\17\5\4\3\2\17") buf.write("\20\7\f\2\2\20\22\3\2\2\2\21\16\3\2\2\2\22\25\3\2\2\2") buf.write("\23\21\3\2\2\2\23\24\3\2\2\2\24\26\3\2\2\2\25\23\3\2\2") buf.write("\2\26\31\5\4\3\2\27\32\7\f\2\2\30\32\3\2\2\2\31\27\3\2") buf.write("\2\2\31\30\3\2\2\2\32\3\3\2\2\2\33\34\5\n\6\2\34\"\7\t") buf.write("\2\2\35\36\5\6\4\2\36\37\7\13\2\2\37!\3\2\2\2 \35\3\2") buf.write("\2\2!$\3\2\2\2\" \3\2\2\2\"#\3\2\2\2#%\3\2\2\2$\"\3\2") buf.write("\2\2%&\5\6\4\2&\5\3\2\2\2\')\5\b\5\2(\'\3\2\2\2)*\3\2") buf.write("\2\2*(\3\2\2\2*+\3\2\2\2+.\3\2\2\2,.\7\n\2\2-(\3\2\2\2") buf.write("-,\3\2\2\2.\7\3\2\2\2/\62\7\7\2\2\60\62\5\n\6\2\61/\3") buf.write("\2\2\2\61\60\3\2\2\2\62\t\3\2\2\2\63C\7\b\2\2\64\66\7") buf.write("\3\2\2\65\67\5\f\7\2\66\65\3\2\2\2\678\3\2\2\28\66\3\2") buf.write("\2\289\3\2\2\29:\3\2\2\2:;\7\4\2\2;C\3\2\2\2<>\5\f\7\2") buf.write("=?\7\5\2\2>=\3\2\2\2?@\3\2\2\2@>\3\2\2\2@A\3\2\2\2AC\3") buf.write("\2\2\2B\63\3\2\2\2B\64\3\2\2\2B<\3\2\2\2C\13\3\2\2\2D") buf.write("E\t\2\2\2E\r\3\2\2\2\13\23\31\"*-\618@B") buf.write("\n\5\3\6\3\6\3\6\6\6\67\n\6\r\6\16\68\3\6\3\6\7\6=\n\6") buf.write("\f\6\16\6@\13\6\3\6\3\6\6\6D\n\6\r\6\16\6E\5\6H\n\6\3") buf.write("\7\3\7\3\7\2\2\b\2\4\6\b\n\f\2\3\3\2\6\b\2P\2\23\3\2\2") buf.write("\2\4\33\3\2\2\2\6-\3\2\2\2\b\61\3\2\2\2\nG\3\2\2\2\fI") buf.write("\3\2\2\2\16\17\5\4\3\2\17\20\7\f\2\2\20\22\3\2\2\2\21") buf.write("\16\3\2\2\2\22\25\3\2\2\2\23\21\3\2\2\2\23\24\3\2\2\2") buf.write("\24\26\3\2\2\2\25\23\3\2\2\2\26\31\5\4\3\2\27\32\7\f\2") buf.write("\2\30\32\3\2\2\2\31\27\3\2\2\2\31\30\3\2\2\2\32\3\3\2") buf.write("\2\2\33\34\5\n\6\2\34\"\7\t\2\2\35\36\5\6\4\2\36\37\7") buf.write("\13\2\2\37!\3\2\2\2 \35\3\2\2\2!$\3\2\2\2\" \3\2\2\2\"") buf.write("#\3\2\2\2#%\3\2\2\2$\"\3\2\2\2%&\5\6\4\2&\5\3\2\2\2\'") buf.write(")\5\b\5\2(\'\3\2\2\2)*\3\2\2\2*(\3\2\2\2*+\3\2\2\2+.\3") buf.write("\2\2\2,.\7\n\2\2-(\3\2\2\2-,\3\2\2\2.\7\3\2\2\2/\62\7") buf.write("\7\2\2\60\62\5\n\6\2\61/\3\2\2\2\61\60\3\2\2\2\62\t\3") buf.write("\2\2\2\63H\7\b\2\2\64\66\7\3\2\2\65\67\5\f\7\2\66\65\3") buf.write("\2\2\2\678\3\2\2\28\66\3\2\2\289\3\2\2\29:\3\2\2\2:>\7") buf.write("\4\2\2;=\7\5\2\2<;\3\2\2\2=@\3\2\2\2><\3\2\2\2>?\3\2\2") buf.write("\2?H\3\2\2\2@>\3\2\2\2AC\5\f\7\2BD\7\5\2\2CB\3\2\2\2D") buf.write("E\3\2\2\2EC\3\2\2\2EF\3\2\2\2FH\3\2\2\2G\63\3\2\2\2G\64") buf.write("\3\2\2\2GA\3\2\2\2H\13\3\2\2\2IJ\t\2\2\2J\r\3\2\2\2\f") buf.write("\23\31\"*-\618>EG") return buf.getvalue() Loading Loading @@ -411,9 +413,9 @@ class CFGParser ( Parser ): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) self.state = 64 self.state = 69 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,8,self._ctx) la_ = self._interp.adaptivePredict(self._input,9,self._ctx) if la_ == 1: self.state = 49 self.match(CFGParser.CAPS) Loading @@ -436,18 +438,29 @@ class CFGParser ( Parser ): self.state = 56 self.match(CFGParser.RIGHT_ANGLE) self.state = 60 self._errHandler.sync(self) _la = self._input.LA(1) while _la==CFGParser.APOSTROPHE: self.state = 57 self.match(CFGParser.APOSTROPHE) self.state = 62 self._errHandler.sync(self) _la = self._input.LA(1) pass elif la_ == 3: self.state = 58 self.state = 63 self.symbol() self.state = 60 self.state = 65 self._errHandler.sync(self) _la = self._input.LA(1) while True: self.state = 59 self.state = 64 self.match(CFGParser.APOSTROPHE) self.state = 62 self.state = 67 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==CFGParser.APOSTROPHE): Loading Loading @@ -501,7 +514,7 @@ class CFGParser ( Parser ): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) self.state = 66 self.state = 71 _la = self._input.LA(1) if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << CFGParser.UNDERSCORE) | (1 << CFGParser.TERMINAL) | (1 << CFGParser.CAPS))) != 0)): self._errHandler.recoverInline(self) Loading
demo.py +1 −1 Original line number Diff line number Diff line Loading @@ -334,7 +334,7 @@ def main(): grammar_test("S->a|aA|\e\nA->a|b|<aBc_JK50l>\n<aBc_JK50l>->AaBa") grammar_test("S->a|aA|\e;A->a|b") grammar_test("S->a|aA|\e;A->a|bS") grammar_test("S'->a|aA''|\e;A''->a|bS'") grammar_test("S'->a|aA''|\e;A''->a|bS'|<ab_0>''") words = dfa_eq("init=1 (1, a)=2 (2,a)=2 (1,b)=3 final={2,3}", "init=A (A, a)=B (A,b)=C (C,b)=C final={B,C}") Loading
parser.py +4 −2 Original line number Diff line number Diff line Loading @@ -326,10 +326,12 @@ class CFGBuilder(CFGListener): def visitNonterminal(self, ctx): if ctx.CAPS(): name = str(ctx.CAPS()) elif ctx.LEFT_ANGLE(): name = '<' + ''.join(map(lambda x: self.visitSymbol(x), ctx.symbol())) + '>' if ctx.APOSTROPHE(): name = name + len(ctx.APOSTROPHE())*"'" elif ctx.APOSTROPHE(): name = self.visitSymbol(ctx.symbol(0)) + len(ctx.APOSTROPHE())*"'" else: name = '<' + ''.join(map(lambda x: self.visitSymbol(x), ctx.symbol())) + '>' nonterminal = Nonterminal(name) self.nonterminals.add(nonterminal) Loading