1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3 4# 5# Copyright 2017, Data61 6# Commonwealth Scientific and Industrial Research Organisation (CSIRO) 7# ABN 41 687 119 230. 8# 9# This software may be distributed and modified according to the terms of 10# the BSD 2-Clause license. Note that NO WARRANTY is provided. 11# See "LICENSE_BSD2.txt" for details. 12# 13# @TAG(DATA61_BSD) 14# 15 16''' 17Stage 1 parser. The following parser is designed to accept a stage 0 parser, 18whose output it consumes. A stage 1 parser makes the following transformation: 19 20 augmented_input ��� raw_ast 21''' 22 23from __future__ import absolute_import, division, print_function, \ 24 unicode_literals 25from camkes.internal.seven import cmp, filter, map, zip 26 27import os, plyplus, re 28from .base import Parser 29from camkes.ast import SourceLocation 30from .exception import ParseError 31 32GRAMMAR = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'camkes.g') 33 34_parser = None 35def _parse(string): 36 # Construct the parser lazily. 37 global _parser 38 if _parser is None: 39 with open(GRAMMAR, 'rt') as f: 40 _parser = plyplus.Grammar(f.read()) 41 42 # Parse `string` into a plyplus STree. 43 return _parser.parse(string) 44 45class Parse1(Parser): 46 def __init__(self, parse0): 47 self.parse0 = parse0 48 49 def parse_file(self, filename): 50 processed, read = self.parse0.parse_file(filename) 51 try: 52 ast_raw = _parse(processed) 53 except plyplus.ParseError as e: 54 location = SourceLocation(filename, e, processed) 55 e = augment_exception(e) 56 raise ParseError(e, location) 57 return processed, ast_raw, read 58 59 def parse_string(self, string): 60 processed, read = self.parse0.parse_string(string) 61 try: 62 ast_raw = _parse(processed) 63 except plyplus.ParseError as e: 64 location = SourceLocation(None, e, processed) 65 e = augment_exception(e) 66 raise ParseError(e, location) 67 return processed, ast_raw, read 68 69def augment_exception(exc): 70 ''' 71 Bolt on some extra, potentially helpful information to a PlyPlus exception. 72 There are certain common typos that manifest in inscrutable PlyPlus 73 exceptions. This function recognises these and adds a note about the 74 possible root cause. 75 ''' 76 assert isinstance(exc, plyplus.ParseError) 77 if str(exc) == 'Syntax error in input (details unknown): None\nCould ' \ 78 'not create parse tree!': 79 exc = plyplus.ParseError('%s (missing closing brace?)' % str(exc)) 80 return exc 81