def lift_raw(term, filename=None, source=None, debug=False): if not plyplus.is_stree(term): return six.text_type(term) if term.head in DONT_LIFT: return term if term.head in DONT_DESCEND: children = term.tail else: children = [lift_raw(t, filename, source, debug) for t in term.tail] location = SourceLocation(filename, term, source) try: lifter = LIFT[term.head] except KeyError: raise Exception('no lifter found for %s' % term.head) try: return lifter(location, *children) except (ParseError, AssertionError): raise except Exception as e: if debug: raise # If some other error occurred, attach filename and line number # information to it. raise ParseError(e, location)
def __init__(self, filename, term, full_source): assert plyplus.is_stree(term) or isinstance(term, plyplus.ParseError) self._filename = filename self._lineno = None self._min_col = None self._max_col = None self.term = term self.full_source = full_source # We defer narrowing the location because this can be expensive and # typically goes unused unless we hit a parse error. self.precise = False
def _locate(self): ''' Find the exact location we are referencing. ''' if plyplus.is_stree(self.term): # First, force plyplus to calculate what it thinks the term's # location is. self.term.calc_position() plyplus_line = self.term.min_line self._min_col = self.term.min_col self._max_col = self.term.max_col else: assert isinstance(self.term, plyplus.ParseError) # Try to extract the line number from a plyplus error. m = re.search( r'^Syntax error in input at \'(?P<token>[^\']*)\' ' r'\(type [^\)]*\) line\s+(?P<line>\d+)' r'(?:\s+col\s+(?P<col>\d+))?$', str(self.term), flags=re.MULTILINE) if m is not None: plyplus_line = int(m.group('line')) if m.group('col') is not None: self._min_col = int(m.group('col')) if len(m.group('token')) > 0: self._max_col = self._min_col + len(m.group('token')) \ - 1 else: plyplus_line = None if plyplus_line is None: # We have no opportunity to find a more precise location. self.precise = True return if self.full_source is None: self._lineno = plyplus_line self.precise = True return # Now parse the original source only looking for CPP line directives, # to adjust our understanding of the location if necessary. current_filename = self._filename current_lineno = 1 for line_index, line in enumerate(self.full_source.split('\n')): if line_index + 1 == plyplus_line: # We've reached the line this term is on. self._filename = current_filename self._lineno = current_lineno self.precise = True return m = LINE_DIRECTIVE.match(line) if m is not None: # The current line is a line directive. if m.group('filename') is not None: current_filename = m.group('filename') current_lineno = int(m.group('lineno')) else: # Standard (CAmkES) line. current_lineno += 1 else: assert False, \ 'term line number points outside its containing source ' \ '(plyplus bug?)'
print ast ast.to_png_with_pydot("ast_posttransform.png") sys.exit(0) if arg.latex: print docpreamble print tikzheader styles.push(elem="tikzpicture") print blind_insert #Apply transformation to AST if one is defined if transformer: ast = transformer.transform(ast) ast.calc_parents() #Apply sequence of postparse functions for postfunc in postparse_funcs: result = postfunc(ast) if is_stree(result): ast = result ast.calc_parents() styles.pop() print tikzfooter if arg.latex: print docpostamble