def dump_parselet(stream: Writer, parselet: Parselet): # return f'{self.parser_id.name} := {self.combinator} -> {self.result_type}' dump_parselet_id(stream, parselet.parser_id) stream.write(' := ') dump_combinator(stream, parselet.combinator) stream.write(' -> ') dump_type(stream, parselet.result_type)
def dump_grammar(stream: Writer, grammar: Grammar): for pattern in grammar.patterns: if pattern.is_implicit: continue dump_pattern(stream, pattern) stream.write("\n") for parser_id in grammar.parselets.values(): for parselet in grammar.tables[parser_id].parselets: dump_parselet(stream, parselet) stream.write("\n")
def dump_source_string(stream: Writer, location: Location, message: str, content: str = None): stream.write('[') stream.write(str(location)) stream.write('] ') stream.write(message, color=Color.Red) stream.write('\n') if content: lines = select_source_lines(io.StringIO(content), location) else: lines = load_source_lines(location) if lines: dump_source_lines(stream, lines, location)
def dump_combinator(stream: Writer, combinator: NamedCombinator): stream.write(combinator.name, color=Color.Grey) stream.write(':') if isinstance(combinator.combinator, SequenceCombinator): stream.write('( ') dump_combinator(stream, combinator.combinator) stream.write(' )') else: dump_combinator(stream, combinator.combinator)
def dump_source_lines(stream: Writer, strings: DiagnosticLines, location: Location, columns: int = None): """ Convert selected lines to error message, e.g.: ``` 1 : from module import system = : --------------------------^ ``` """ if not columns: try: _, columns = os.popen('stty size', 'r').read().split() except (ValueError, IOError): columns = 80 if not strings: return width = 5 for idx, _ in strings: width = max(len(str(idx)), width) for line, string in strings: s_line = str(line).rjust(width) stream.write(s_line, " : ", color=Color.Cyan) for column, char in enumerate(string): column += 1 is_error = False if location.begin.line == line: is_error = column >= location.begin.column if location.end.line == line: is_error = is_error and column <= location.end.column if is_error: stream.write(char, color=Color.Red) else: stream.write(char, color=Color.Green) stream.write("\n") # write error line if location.begin.line <= line <= location.end.line: stream.write(" " * width) stream.write(" : ", color=Color.Cyan) for column, char in itertools.chain(enumerate(string), ((len(string), None), )): column += 1 is_error = False if location.begin.line == line: is_error = column >= location.begin.column if location.end.line == line: is_error = is_error and column <= location.end.column if is_error: stream.write("^", color=Color.Red) elif char is not None: stream.write(" ") stream.write("\n")
def dump_parselet_id(stream: Writer, parser_id: ParseletID): stream.write(parser_id.name, color=Color.Blue)
def dump_token_id(stream: Writer, token_id: TokenID): stream.write( repr(token_id.name) if token_id.is_implicit else token_id.name, color=Color.Red)
def dump_pattern(stream: Writer, pattern: SyntaxPattern): dump_token_id(stream, pattern.token_id) stream.write(' ::= ') regex_pattern = pattern.pattern.pattern stream.write('r"', regex_pattern, '"', color=Color.Magenta)
def dump_type(stream: Writer, typ: Type): if is_optional_type(typ): stream.write('Optional', color=Color.Green) stream.write('[') dump_type(stream, unpack_type_argument(typ)) stream.write(']') elif is_sequence_type(typ): stream.write('Sequence', color=Color.Green) stream.write('[') dump_type(stream, unpack_type_argument(typ)) stream.write(']') elif is_generic_type(typ): stream.write(get_origin(typ).__name__, color=Color.Green) stream.write('[') for idx, element in enumerate(get_args(typ)): if idx: stream.write(', ') dump_type(stream, element) stream.write(']') else: stream.write(typ.__name__, color=Color.Green)
def dump_combinator(stream: Writer, combinator: SequenceCombinator): for idx, child in enumerate(combinator.combinators): if idx: stream.write(' ') dump_combinator(stream, child)
def dump_combinator(stream: Writer, combinator: RepeatCombinator): stream.write('{ ') dump_combinator(stream, combinator.combinator) stream.write(' }')
def dump_combinator(stream: Writer, combinator: OptionalCombinator): stream.write('[ ') dump_combinator(stream, combinator.combinator) stream.write(' ]')
def dump_combinator(stream: Writer, combinator: ParseletCombinator): dump_parselet_id(stream, combinator.parser_id) if combinator.priority: stream.write('<') stream.write(str(combinator.priority), color=Color.Grey) stream.write('>')