Created
October 20, 2018 18:19
-
-
Save funvit/f3fe079b6b4f85b03a67ad38e679e417 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import logging | |
| class SomeSyntaxError(Exception): pass | |
| class SyntaxError(SomeSyntaxError): | |
| bracket = None | |
| idx = -1 | |
| def __init__(self, bracket, idx): | |
| assert isinstance(bracket, str) | |
| assert isinstance(idx, int) | |
| self.bracket = bracket | |
| self.idx = idx | |
| def __str__(self): | |
| return 'Wrong bracket "%s" at index %d' % (self.bracket, self.idx) | |
| def check_syntax(text): | |
| """ | |
| Проверяет синтакс скобок. | |
| Не учитывает кавычки! | |
| """ | |
| if not text: | |
| return True | |
| logger = logging.getLogger('Syntaxer') | |
| good_pairs_map = { | |
| '{': '}', | |
| '[': ']', | |
| '(': ')', | |
| } | |
| _opened_brackets_stack = [] | |
| idx = -1 | |
| for c in text: | |
| idx += 1 | |
| if not _opened_brackets_stack: | |
| if c in good_pairs_map.values(): | |
| raise SyntaxError(c, idx) | |
| elif c in good_pairs_map.keys(): | |
| _opened_brackets_stack.append(c) | |
| logger.debug('First opening bracket: %s at %s' % (c, idx)) | |
| continue | |
| else: | |
| if c in good_pairs_map.keys(): | |
| _opened_brackets_stack.append(c) | |
| logger.debug('Next opening bracket with %s at %s' % (c, idx)) | |
| continue | |
| elif c in good_pairs_map.values(): | |
| if c == good_pairs_map.get(_opened_brackets_stack[-1]): | |
| _opened_brackets_stack.pop() | |
| logger.debug('Found closing bracket "%s" at %s' % (c, idx)) | |
| continue | |
| else: | |
| raise SyntaxError(c, idx) | |
| if _opened_brackets_stack: | |
| raise SomeSyntaxError('Not closed brackets: %d' % len(_opened_brackets_stack)) | |
| return True | |
| import unittest | |
| class SyntaxCheckerTest(unittest.TestCase): | |
| def test_ok(self): | |
| self.assertTrue(check_syntax('{()}[]')) | |
| def test_should_fail_on_wrong_closing_bracket(self): | |
| with self.assertRaises(SomeSyntaxError): | |
| check_syntax('{[}}') | |
| def test_should_fail_on_missing_closing_bracket(self): | |
| with self.assertRaises(SomeSyntaxError): | |
| check_syntax('{}[') | |
| def test_should_fail_on_single_opening_bracket(self): | |
| with self.assertRaises(SomeSyntaxError): | |
| check_syntax('{') | |
| def test_should_fail_on_single_close_bracket(self): | |
| with self.assertRaises(SomeSyntaxError): | |
| check_syntax(')') | |
| if __name__ == '__main__': | |
| import sys | |
| if len(sys.argv) >= 2: | |
| if '-d' in sys.argv[1:]: | |
| logging.basicConfig(level=logging.DEBUG) | |
| try: | |
| if check_syntax(sys.argv[-1]): | |
| print('Syntax is ok!') | |
| except SomeSyntaxError as ex: | |
| print(ex) | |
| else: | |
| print('Run with string, -d for debug...') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment