05.11., 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

Commit 3ec7a844 authored by eckhart's avatar eckhart

- ebnf.py: Unused customized error messages now case a warning

parent 5b6deeea
......@@ -601,7 +601,7 @@ class EBNFCompiler(Compiler):
if entry not in symbols and not entry.startswith(":"):
messages.append(Error(('Symbol "%s" is not defined in grammar %s but appears in '
'the transformation table!') % (entry, self.grammar_name),
0, Error.UNDEFINED_SYMBOL_IN_TRANSFORMATION_TABLE))
0, Error.UNDEFINED_SYMBOL_IN_TRANSTABLE_WARNING))
return messages
def verify_compiler(self, compiler):
......@@ -719,6 +719,14 @@ class EBNFCompiler(Compiler):
custom_errors.append((search, message))
definitions.append((symbol + self.ERR_MSG_SUFFIX, repr(custom_errors)))
for symbol in self.directives.error.keys():
if symbol not in self.consumed_custom_errors:
def_node = self.rules[symbol][0]
self.tree.new_error(
def_node, 'Customized error message for symbol "{}" will never be used, '
'because the mandatory marker "§" appears nowhere in its definiendum!'
.format(symbol), Error.UNUSED_ERROR_MSG_WARNING)
# prepare parser class header and docstring and
# add EBNF grammar to the doc string of the parser class
......@@ -1011,8 +1019,6 @@ class EBNFCompiler(Compiler):
custom_args.append('err_msgs=' + current_symbol + self.ERR_MSG_SUFFIX)
self.consumed_custom_errors.add(current_symbol)
compiled = self.non_terminal(node, 'Series', custom_args)
# TODO: Maybe add a warning about ambiguous error messages in case there are several
# Series with mandatory items within the definiens of the same symbol?
node.result = saved_result
return compiled
......
......@@ -73,8 +73,9 @@ class Error:
REDEFINED_DIRECTIVE_WARNING = ErrorCode(110)
REDECLARED_TOKEN_WARNING = ErrorCode(120)
UNUSED_ERROR_MSG_WARNING = ErrorCode(130)
UNDEFINED_SYMBOL_IN_TRANSFORMATION_TABLE = ErrorCode(610)
UNDEFINED_SYMBOL_IN_TRANSTABLE_WARNING = ErrorCode(610)
# error codes
......@@ -86,7 +87,6 @@ class Error:
CAPTURE_STACK_NOT_EMPTY = ErrorCode(1050)
MALFORMED_ERROR_STRING = ErrorCode(1060)
AMBIGUOUS_ERROR_MSG = ErrorCode(1070)
UNUSED_ERROR_MSG = ErrorCode(1080)
def __init__(self, message: str, pos, code: ErrorCode = ERROR,
orig_pos: int = -1, line: int = -1, column: int = -1) -> None:
......@@ -138,6 +138,18 @@ def is_error(code: int) -> bool:
return code >= Error.ERROR
# def Warning(message: str, pos, code: ErrorCode = Error.WARNING,
# orig_pos: int = -1, line: int = -1, column: int = -1) -> Error:
# """
# Syntactic sugar for creating Error-objects that contain only a warning.
# Raises a ValueError if `code` is not within the range for warnings.
# """
# if not is_warning(code):
# raise ValueError("Tried to create a warning with a error code {}. "
# "Warning codes must be smaller than {}".format(code, Error.ERROR))
# return Error(message, pos, code, orig_pos, line, column)
def has_errors(messages: Iterable[Error], level: int = Error.ERROR) -> bool:
"""
Returns True, if at least one entry in `messages` has at
......
......@@ -504,14 +504,10 @@ class TestErrorCustomization:
series = "A" § "B" "C"
other = "X" | "Y" | "Z"
"""
parser = grammar_provider(lang)() # TODO: Here an error should occur!
st = parser("ABC")
assert not st.error_flag
st = parser("Y")
assert not st.error_flag
st = parser("ADC")
assert st.error_flag
print(st.collect_errors())
result, messages, ast = compile_source(lang, None, get_ebnf_grammar(),
get_ebnf_transformer(), get_ebnf_compiler())
assert messages[0].code == Error.UNUSED_ERROR_MSG_WARNING
class TestCustomizedResumeParsing:
def setup(self):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment