| OLD | NEW |
| 1 # Copyright 2013 the V8 project authors. All rights reserved. | 1 # Copyright 2013 the V8 project authors. All rights reserved. |
| 2 # Redistribution and use in source and binary forms, with or without | 2 # Redistribution and use in source and binary forms, with or without |
| 3 # modification, are permitted provided that the following conditions are | 3 # modification, are permitted provided that the following conditions are |
| 4 # met: | 4 # met: |
| 5 # | 5 # |
| 6 # * Redistributions of source code must retain the above copyright | 6 # * Redistributions of source code must retain the above copyright |
| 7 # notice, this list of conditions and the following disclaimer. | 7 # notice, this list of conditions and the following disclaimer. |
| 8 # * Redistributions in binary form must reproduce the above | 8 # * Redistributions in binary form must reproduce the above |
| 9 # copyright notice, this list of conditions and the following | 9 # copyright notice, this list of conditions and the following |
| 10 # disclaimer in the documentation and/or other materials provided | 10 # disclaimer in the documentation and/or other materials provided |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 import unittest | 28 import unittest |
| 29 from regex_parser import RegexParser | 29 from regex_parser import RegexParser |
| 30 from nfa import NfaBuilder | 30 from nfa import NfaBuilder |
| 31 from dfa import Dfa | 31 from dfa import Dfa |
| 32 | 32 |
| 33 def dfa_from_nfa(nfa): |
| 34 (start_name, dfa_nodes) = nfa.compute_dfa() |
| 35 return Dfa(start_name, dfa_nodes) |
| 36 |
| 33 def build_automata(string): | 37 def build_automata(string): |
| 34 graph = RegexParser.parse(string) | 38 nfa = NfaBuilder().nfa(RegexParser.parse(string)) |
| 35 nfa = NfaBuilder().nfa(graph) | 39 return (nfa, dfa_from_nfa(nfa)) |
| 36 (start_name, dfa_nodes, end_nodes) = nfa.compute_dfa() | |
| 37 dfa = Dfa(start_name, dfa_nodes, end_nodes) | |
| 38 return (nfa, dfa) | |
| 39 | 40 |
| 40 class AutomataTestCase(unittest.TestCase): | 41 class AutomataTestCase(unittest.TestCase): |
| 41 | 42 |
| 42 # (pattern, should match, shouldn't match) | 43 # (pattern, should match, should not match) |
| 43 __test_data = [ | 44 __test_data = [ |
| 44 ("a", ["a"], ["b", ""]), | 45 ("a", ["a"], ["b", ""]), |
| 45 ("ab", ["ab"], ["bb", ""]), | 46 ("ab", ["ab"], ["bb", ""]), |
| 46 ("a+b", ["ab", "aab", "aaab"], ["a", "b", ""]), | 47 ("a+b", ["ab", "aab", "aaab"], ["a", "b", ""]), |
| 47 ("a?b", ["ab", "b"], ["a", "c", ""]), | 48 ("a?b", ["ab", "b"], ["a", "c", ""]), |
| 48 ("a*b", ["ab", "aaab", "b"], ["a", "c", ""]), | 49 ("a*b", ["ab", "aaab", "b"], ["a", "c", ""]), |
| 49 ("a|b", ["a", "b"], ["ab", "c", ""]), | 50 ("a|b", ["a", "b"], ["ab", "c", ""]), |
| 50 (".", ["a", "b"], ["", "aa"]), | 51 (".", ["a", "b"], ["", "aa"]), |
| 51 (".*", ["", "a", "abcaabbcc"], []), | 52 (".*", ["", "a", "abcaabbcc"], []), |
| 52 ("a.b", ["aab", "abb", "acb"], ["ab", ""]), | 53 ("a.b", ["aab", "abb", "acb"], ["ab", ""]), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 64 for string in not_matches: | 65 for string in not_matches: |
| 65 self.assertFalse(nfa.matches(string)) | 66 self.assertFalse(nfa.matches(string)) |
| 66 self.assertFalse(dfa.matches(string)) | 67 self.assertFalse(dfa.matches(string)) |
| 67 | 68 |
| 68 def test_can_construct_dot(self): | 69 def test_can_construct_dot(self): |
| 69 for (regex, matches, not_matches) in self.__test_data: | 70 for (regex, matches, not_matches) in self.__test_data: |
| 70 (nfa, dfa) = build_automata(regex) | 71 (nfa, dfa) = build_automata(regex) |
| 71 nfa.to_dot() | 72 nfa.to_dot() |
| 72 dfa.to_dot() | 73 dfa.to_dot() |
| 73 | 74 |
| 75 def test_actions(self): |
| 76 left_action = ("LEFT_ACTION",) |
| 77 right_action = ("RIGHT_ACTION",) |
| 78 left = RegexParser.parse("left") |
| 79 right = RegexParser.parse("right") |
| 80 left = NfaBuilder.add_action(left, left_action) |
| 81 right = NfaBuilder.add_action(right, right_action) |
| 82 composite = ('ONE_OR_MORE', NfaBuilder.or_graphs([left, right])) |
| 83 nfa = NfaBuilder().nfa(composite) |
| 84 dfa = dfa_from_nfa(nfa) |
| 85 def verify(string, expected): |
| 86 actions = list(dfa.collect_actions(string)) |
| 87 assertEqual(len(expected), len(actions)) |
| 88 for i, action in enumerate(actions): |
| 89 assertEqual(action[i], expected[i]) |
| 90 def verify_miss(string, expected): |
| 91 verify(string, expected + [('MISS',)]) |
| 92 def verify_hit(string, expected): |
| 93 verify(string, expected + [('TERMINATE',)]) |
| 94 (l, r) = left_action, right_action |
| 95 verify_hit("left", [l]) |
| 96 verify_miss("lefta", [l]) |
| 97 verify_hit("leftrightleftright", [l, r, l, r]) |
| 98 verify_miss("leftrightleftrightx", [l, r, l, r]) |
| 99 |
| 74 if __name__ == '__main__': | 100 if __name__ == '__main__': |
| 75 unittest.main() | 101 unittest.main() |
| OLD | NEW |