def test_trace_resume_message(self): lang = """ @literalws = right document = alpha [beta] gamma "." alpha = "ALPHA" abc abc = " " | §"a" "b" "c" beta = "BETA" (bac | bca) bac = "b" "a" §"c" bca = "b" "c" §"a" gamma = "GAMMA" §(cab | cba) cab = "c" "a" §"b" cba = "c" "b" §"a" """ gr = grammar_provider(lang)() gr.resume_rules = dict() gr.resume_rules__['alpha'] = [re.compile(r'(?=BETA)')] content = 'ALPHA acb BETA bac GAMMA cab .' # test resume notice resume_notices_on(gr) cst = gr(content) # there should be one error message and one resume notice assert len(cst.errors_sorted) == 2 notices = [e for e in cst.errors_sorted if e.code < WARNING] assert len(notices) == 1, str(notices) notice = str(notices[0]) assert notice.find('Skip') < 0, 'Not a resume-notice: ' + notice assert notice.find('"abc') >= 0, "Wrong parser reported: " + notice set_tracer(gr, None) assert not gr.history_tracking__
def get_grammar() -> ArithmeticGrammar: grammar = _raw_grammar() if get_config_value('resume_notices'): resume_notices_on(grammar) elif get_config_value('history_tracking'): set_tracer(grammar, trace_history) return grammar
def test_trace_resume(self): lang = """ @literalws = right document = alpha [beta] gamma "." alpha = "ALPHA" abc abc = §"a" "b" "c" beta = "BETA" (bac | bca) bac = "b" "a" §"c" bca = "b" "c" §"a" gamma = "GAMMA" §(cab | cba) cab = "c" "a" §"b" cba = "c" "b" §"a" """ gr = grammar_provider(lang)() gr.resume_rules = dict() gr.resume_rules__['alpha'] = [re.compile(r'(?=BETA)')] content = 'ALPHA acb BETA bac GAMMA cab .' cst = gr(content) assert cst.error_flag assert cst.content == content, cst.as_sxpr() assert cst.pick('alpha').content.startswith('ALPHA') # because of resuming, there should be only one error message assert len(cst.errors_sorted) == 1 # test resume notice resume_notices_on(gr) cst = gr(content) # there should be one error message and one resume notice set_tracer(gr, None) assert not gr.history_tracking__
def test_trace_drop(self): lang = r""" @ literalws = right @ drop = strings, whitespace expression = term { ("+" | "-") term} term = factor { ("*"|"/") factor} factor = number | variable | "(" expression ")" | constant | fixed variable = /[a-z]/~ number = /\d+/~ constant = "A" | "B" fixed = "X" """ set_config_value('compiled_EBNF_log', 'test_trace_parser.py') gr = grammar_provider(lang)() all_desc = all_descendants(gr.root_parser__) set_tracer(all_desc, trace_history) # st = gr('2*(3+4)') st = gr('2*(3 + 4*(5 + 6*(7 + 8 + 9*2 - 1/5*1000) + 2) + 5000 + 4000)') serialization = st.serialize() assert '*' not in serialization # same for '/', '+', '-' log_parsing_history(gr, 'trace_drop') history_file = get_history('trace_drop') assert "DROP" in history_file assert "FAIL" in history_file assert "MATCH" in history_file
def get_grammar() -> json_fail_tolerantGrammar: grammar = _raw_grammar() if get_config_value('resume_notices'): resume_notices_on(grammar) elif get_config_value('history_tracking'): set_tracer(grammar, trace_history) return grammar
def test_trace_stopped_early(self): lang = """ @ literalws = right expr = term { ("+"|"-") term } term = factor { ("*"|"/") factor } factor = /[0-9]+/~ | "(" expr ")" """ gr = grammar_provider(lang)() all_desc = all_descendants(gr.root_parser__) set_tracer(all_desc, trace_history) _ = gr('2*(3+4)xxx') log_parsing_history(gr, 'trace_stopped_early') history = get_history('trace_stopped_early') assert history.count('<tr>') == 26
def get_grammar() -> LyrikGrammar: """Returns a thread/process-exclusive LyrikGrammar-singleton.""" THREAD_LOCALS = access_thread_locals() try: grammar = THREAD_LOCALS.Lyrik_00000001_grammar_singleton except AttributeError: THREAD_LOCALS.Lyrik_00000001_grammar_singleton = LyrikGrammar() if hasattr(get_grammar, 'python_src__'): THREAD_LOCALS.Lyrik_00000001_grammar_singleton.python_src__ = get_grammar.python_src__ grammar = THREAD_LOCALS.Lyrik_00000001_grammar_singleton if get_config_value('resume_notices'): resume_notices_on(grammar) elif get_config_value('history_tracking'): set_tracer(grammar, trace_history) return grammar
def test_trace_noskip(self): lang = """ document = series | /.*/ series = "A" "B" §"C" "D" """ gr = grammar_provider(lang)() set_tracer(all_descendants(gr.root_parser__), trace_history) _ = gr('AB_D') for record in gr.history__: if record.status.startswith(record.ERROR): assert record.excerpt == '_D' if record.errors[0].code == PARSER_STOPPED_BEFORE_END: break else: assert False, "Missing Error!" reveal(gr, 'trace_noskip')
def test_trace_simple(self): lang = """ @literalws = right expr = term { ("+"|"-") term } term = factor { ("*"|"/") factor } factor = /[0-9]+/~ | "(" expr ")" """ gr = grammar_provider(lang)() all_desc = all_descendants(gr.root_parser__) set_tracer(all_desc, trace_history) st = gr('2*(3+4)') assert (str(st)) == '2*(3+4)' history = gr.history__ for record in history: if record.status.startswith(record.FAIL): # check if the first failed parser yields an excerpt assert record.excerpt break assert len(history) == 24 log_parsing_history(gr, 'trace_simple') history = get_history('trace_simple') assert history.count( '<tr>') == 25 # same as len(history) + 1 title row