def _play(mid, start, end): """ Play the selection """ if start is None: start = 0 # Trim the midi trimmed = EventStreamSlice(mid, start, end).to_event_stream(repeat_playing=False) # Show info about the clip print "Start tick: %s" % start print "End tick: %s" % end print "First event tick: %s" % _ticks_to_ticks(mid, start) print "Last event tick: %s" % _ticks_to_ticks(mid, end, before=True) start_time = float(_get_time(mid, start)) / 1000.0 print "Start time: %ss" % start_time print "Last event time: %ss" % (float(_get_time(mid, end, before=True)) / 1000.0) print print "Playing MIDI. Hit ctrl+C to stop" # Record playing time timer = ExecutionTimer() try: play_stream(trimmed, block=True) except KeyboardInterrupt: length = timer.get_time() print "\nPlayed for %.2f seconds (stopped ~%.2fs)" % ( length, start_time + length)
def _play(mid, start, end): """ Play the selection """ if start is None: start = 0 # Trim the midi trimmed = EventStreamSlice(mid, start, end).to_event_stream(repeat_playing=False) # Show info about the clip print "Start tick: %s" % start print "End tick: %s" % end print "First event tick: %s" % _ticks_to_ticks(mid, start) print "Last event tick: %s" % _ticks_to_ticks(mid, end, before=True) start_time = float(_get_time(mid, start)) / 1000.0 print "Start time: %ss" % start_time print "Last event time: %ss" % (float(_get_time(mid, end, before=True)) / 1000.0) print print "Playing MIDI. Hit ctrl+C to stop" # Record playing time timer = ExecutionTimer() try: play_stream(trimmed, block=True) except KeyboardInterrupt: length = timer.get_time() print "\nPlayed for %.2f seconds (stopped ~%.2fs)" % (length, start_time + length)
def parse(self, derivations=False, summaries=False, inspect=False): """ Run the parser on the input, using the specified tagger. Runs the CKY parsing algorithm to do chart parsing. For details of chart parsing, see Chart class. If the parser was given a maximum number of iterations, the routine will return as usual after this number is completed, even if no parses have been found. @type derivations: bool @param derivations: store derivation traces, which can subsequently be used to trace all the derivations that led to any given sign in the chart. Overridden by the module option if it's given @type summaries: int/bool @param summaries: output chart summary information to stderr during parsing to track progress. Set to 2 to output some info, but not the full chart. @type inspect: bool @param inspect: launch a graphical chart inspector during the parse to display interactive chart information. @return: a list of signs that span the full input. """ if 'derivations' in self.options and self.options[ 'derivations'] is not None: derivations = self.options['derivations'] # Time excecution if we're showing any summaries time = bool(summaries) # Find out from the tagger how long the input it read in was input_length = self.tagger.input_length # Create and initialise a chart for parsing # Don't initialise the chart with signs - we'll add signs gradually instead chart = self._create_chart([[]] * input_length, derivations=derivations) # Launch a chart inspector if requested if self.options['inspect'] or inspect: # Get a string form of the input to display input_strs = self.tagger.get_string_input() chart.launch_inspector(input=input_strs) # Start dumping the chart if requested if self.options['dump_chart']: # Make the first dump of the empty chart from .chart import dump_chart dump_chart(chart, self.options['dump_chart']) # Stop after a given number of iterations if self.options['max_iter'] == 0: max_iter = None else: max_iter = self.options['max_iter'] if self.options['min_iter'] == -1: # Special case: never stop until we've got all the categories min_iter = None else: min_iter = self.options['min_iter'] required_parses = self.options['parses'] timeout = 60 * self.options['timeout'] check_timeout = timeout > 0 # Make sure the timed out flag is unset to start with self.timed_out = False # This is where progress output will go # Note that it's not the same as logger, which is the main system logger prog_logger = self.logger if check_timeout: prog_logger.info("Due to timeout after %d mins" % self.options['timeout']) ################################################## ### Here is the parser itself. # Keep track of how long since we started for timing out timeout_timer = ExecutionTimer(clock=True) signs_taken = [0] * input_length offset = 0 last_lexicals = [0] * (input_length) try: # Keep adding signs until none left, or we get a full parse, # or we complete the maximum iterations allowed # Keep going if min_iter is None (special value meaning don't stop # when we get a parse while (min_iter is None or (offset < min_iter) \ or len(chart.parses) < required_parses): if max_iter is not None and offset >= max_iter: # Exceded maximum number of iterations: give up prog_logger.info("Reached maximum number of iterations: "\ "continuing to backoff/fail") break prog_logger.info(">>> Parsing iteration: %d" % (offset + 1)) # Get new signs from the tagger added = self._add_signs(offset=offset) # Note whether we added anything new if added: # Apply unary rules to these new signs added_spans = set([(start, end) for (start, end, sign) in added]) for (start, end) in added_spans: chart.apply_unary_rules(start, end) else: # No new signs added by the tagger: no point in continuing prog_logger.info("No new signs added: ending parse") break ##### Main parser loop: produce all possible results # Set end point to each node for end in range(1, input_length + 1): if time: # Start a timer timer = ExecutionTimer() chart.apply_unary_rules(end - 1, end) # Set start point to each node before the end, in reverse order for start in range(end - 2, -1, -1): for middle in range(start + 1, end): chart.apply_binary_rules(start, middle, end) # Check whether the timeout has expired and don't process # any more if it has if check_timeout: # Check whether the timeout has passed if int(timeout_timer.get_time()) > timeout: # Move on to post-parse stuff raise ParserTimeout # Check for new unary rule applications chart.apply_unary_rules(start, end) if summaries: prog_logger.info( "Completed parsing up to node %d / %d (%.2f secs)" % (end, input_length, timer.get_time())) if summaries != 2: prog_logger.info(chart.summary) if self.options['dump_chart']: # Dump an update of the chart to the file dump_chart(chart, self.options['dump_chart']) if summaries: prog_logger.info("Completed parsing to end of sequence") if summaries != 2: prog_logger.info(chart.summary) offset += 1 except ParserTimeout: # The given timeout elapsed: just continue with no parses prog_logger.info("Parse timeout (%d mins) expired: continuing "\ "to backoff/fail" % self.options['timeout']) # Set the timed_out flag so we can check later whether we timed out self.timed_out = True except KeyboardInterrupt: # We pass the interrupt on to a higher level, but first kill # the inspector window, so it doesn't hang around and mess up self.chart.kill_inspector() raise parses = chart.parses if len(parses) == 0 and self.backoff is not None: prog_logger.info("Using backoff model") backoff_results = self.run_backoff() if len(backoff_results) > 0: for res in backoff_results: # Put the semantics result into a sign, with a dummy # syntactic category sign = self.grammar.formalism.Syntax.Sign( self.grammar.formalism.Syntax.DummyCategory(), res) # If the semantics has a probability, put this on the sign if hasattr(res, "probability"): sign.probability = res.probability parses.append(sign) elif len(parses): prog_logger.info("Parse finished with %d results" % len(parses)) else: prog_logger.info("Parse finished with no results") # Close the inspector window if one was opened if not self.options['inspect_persist']: self.chart.kill_inspector() return parses
def parse(self, derivations=False, summaries=False, inspect=False): # Find out from the tagger how long the input it read in was input_length = self.tagger.input_length # Create and initialise a chart for parsing # Don't initialise the chart with signs - we'll add signs gradually instead chart = self._create_chart( [[]]*input_length, derivations=derivations) # Stop after a given number of iterations if self.options['max_iter'] == 0: max_iter = None else: max_iter = self.options['max_iter'] timeout = 60*self.options['timeout'] check_timeout = timeout>0 # This is where progress output will go # Note that it's not the same as logger, which is the main system logger prog_logger = self.logger if check_timeout: prog_logger.info("Due to timeout after %d mins" % self.options['timeout']) ################################################## ### The dummy parse loop # Keep track of how long since we started for timing out timeout_timer = ExecutionTimer() signs_added = True offset = 0 try: # Keep adding signs until none left while len(chart.get_signs(0, input_length)) == 0 and signs_added: if max_iter is not None and offset >= max_iter: # Exceded maximum number of iterations: give up prog_logger.info("Reached maximum number of iterations: "\ "continuing to backoff/fail") break prog_logger.info(">>> Parsing iteration: %d" % (offset+1)) # Get new signs from the tagger added = self._add_signs(offset=offset) # Note whether we added anything new signs_added = bool(added) # Check whether the timeout has expired if check_timeout: if int(timeout_timer.get_time()) > timeout: raise ParserTimeout # Don't do any parsing: just go round again to get more signs offset += 1 except ParserTimeout: # The given timeout elapsed: just continue with no parses logger.debug("Parse loop timeout (%d mins) expired" % self.options['timeout']) prog_logger.info("Parse timeout (%d mins) expired: continuing "\ "to backoff/fail" % self.options['timeout']) parses = [] # If a backoff model was given, always use it now if self.backoff is not None: backoff_results = self.run_backoff() if len(backoff_results) > 0: for res in backoff_results: # Put the semantics result into a sign, with a dummy # syntactic category sign = self.grammar.formalism.Syntax.Sign( self.grammar.formalism.Syntax.DummyCategory(), res) # If the semantics has a probability, put this on the sign if hasattr(res, "probability"): sign.probability = res.probability parses.append(sign) return parses
def parse(self, derivations=False, summaries=False, inspect=False): """ Run the parser on the input, using the specified tagger. Runs the CKY parsing algorithm to do chart parsing. For details of chart parsing, see Chart class. If the parser was given a maximum number of iterations, the routine will return as usual after this number is completed, even if no parses have been found. @type derivations: bool @param derivations: store derivation traces, which can subsequently be used to trace all the derivations that led to any given sign in the chart. Overridden by the module option if it's given @type summaries: int/bool @param summaries: output chart summary information to stderr during parsing to track progress. Set to 2 to output some info, but not the full chart. @type inspect: bool @param inspect: launch a graphical chart inspector during the parse to display interactive chart information. @return: a list of signs that span the full input. """ if 'derivations' in self.options and self.options['derivations'] is not None: derivations = self.options['derivations'] # Time excecution if we're showing any summaries time = bool(summaries) # Find out from the tagger how long the input it read in was input_length = self.tagger.input_length # Create and initialise a chart for parsing # Don't initialise the chart with signs - we'll add signs gradually instead chart = self._create_chart( [[]]*input_length, derivations=derivations) # Launch a chart inspector if requested if self.options['inspect'] or inspect: # Get a string form of the input to display input_strs = self.tagger.get_string_input() chart.launch_inspector(input=input_strs) # Start dumping the chart if requested if self.options['dump_chart']: # Make the first dump of the empty chart from .chart import dump_chart dump_chart(chart, self.options['dump_chart']) # Stop after a given number of iterations if self.options['max_iter'] == 0: max_iter = None else: max_iter = self.options['max_iter'] if self.options['min_iter'] == -1: # Special case: never stop until we've got all the categories min_iter = None else: min_iter = self.options['min_iter'] required_parses = self.options['parses'] timeout = 60*self.options['timeout'] check_timeout = timeout>0 # Make sure the timed out flag is unset to start with self.timed_out = False # This is where progress output will go # Note that it's not the same as logger, which is the main system logger prog_logger = self.logger if check_timeout: prog_logger.info("Due to timeout after %d mins" % self.options['timeout']) ################################################## ### Here is the parser itself. # Keep track of how long since we started for timing out timeout_timer = ExecutionTimer(clock=True) signs_taken = [0]*input_length offset = 0 last_lexicals = [0]*(input_length) try: # Keep adding signs until none left, or we get a full parse, # or we complete the maximum iterations allowed # Keep going if min_iter is None (special value meaning don't stop # when we get a parse while (min_iter is None or (offset < min_iter) \ or len(chart.parses) < required_parses): if max_iter is not None and offset >= max_iter: # Exceded maximum number of iterations: give up prog_logger.info("Reached maximum number of iterations: "\ "continuing to backoff/fail") break prog_logger.info(">>> Parsing iteration: %d" % (offset+1)) # Get new signs from the tagger added = self._add_signs(offset=offset) # Note whether we added anything new if added: # Apply unary rules to these new signs added_spans = set([(start,end) for (start,end,sign) in added]) for (start,end) in added_spans: chart.apply_unary_rules(start,end) else: # No new signs added by the tagger: no point in continuing prog_logger.info("No new signs added: ending parse") break ##### Main parser loop: produce all possible results # Set end point to each node for end in range(1,input_length+1): if time: # Start a timer timer = ExecutionTimer() chart.apply_unary_rules(end-1, end) # Set start point to each node before the end, in reverse order for start in range(end-2,-1,-1): for middle in range(start+1,end): chart.apply_binary_rules(start, middle, end) # Check whether the timeout has expired and don't process # any more if it has if check_timeout: # Check whether the timeout has passed if int(timeout_timer.get_time()) > timeout: # Move on to post-parse stuff raise ParserTimeout # Check for new unary rule applications chart.apply_unary_rules(start, end) if summaries: prog_logger.info("Completed parsing up to node %d / %d (%.2f secs)" % (end,input_length, timer.get_time())) if summaries != 2: prog_logger.info(chart.summary) if self.options['dump_chart']: # Dump an update of the chart to the file dump_chart(chart, self.options['dump_chart']) if summaries: prog_logger.info("Completed parsing to end of sequence") if summaries != 2: prog_logger.info(chart.summary) offset += 1 except ParserTimeout: # The given timeout elapsed: just continue with no parses prog_logger.info("Parse timeout (%d mins) expired: continuing "\ "to backoff/fail" % self.options['timeout']) # Set the timed_out flag so we can check later whether we timed out self.timed_out = True except KeyboardInterrupt: # We pass the interrupt on to a higher level, but first kill # the inspector window, so it doesn't hang around and mess up self.chart.kill_inspector() raise parses = chart.parses if len(parses) == 0 and self.backoff is not None: prog_logger.info("Using backoff model") backoff_results = self.run_backoff() if len(backoff_results) > 0: for res in backoff_results: # Put the semantics result into a sign, with a dummy # syntactic category sign = self.grammar.formalism.Syntax.Sign( self.grammar.formalism.Syntax.DummyCategory(), res) # If the semantics has a probability, put this on the sign if hasattr(res, "probability"): sign.probability = res.probability parses.append(sign) elif len(parses): prog_logger.info("Parse finished with %d results" % len(parses)) else: prog_logger.info("Parse finished with no results") # Close the inspector window if one was opened if not self.options['inspect_persist']: self.chart.kill_inspector() return parses
def main(): usage = "%prog [options] <midi-input>" description = "Trims a MIDI file to the required start and end points. "\ "By default, plays the trimmed MIDI (for testing) and can also write "\ "it out to a file." parser = OptionParser(usage=usage, description=description) parser.add_option( "-s", "--start", dest="start", action="store", help="start point, in ticks as 'x', or in seconds as 'xs'") parser.add_option("-e", "--end", dest="end", action="store", help="end point (formatted as -s)") parser.add_option( "-o", "--output", dest="output", action="store", help= "MIDI file to output to. If given, output is stored instead of being played" ) options, arguments = parser.parse_args() if len(arguments) == 0: print >> sys.stderr, "You must specify a MIDI file" sys.exit(1) mid = read_midifile(arguments[0]) def _time_to_ticks(time, before=False): # Find the tick time of the first event after the given time # or the last event before it mstime = int(time * 1000) if time is not None: previous = min(mid.trackpool) for ev in sorted(mid.trackpool): # Look for the first event after the time if ev.msdelay >= mstime: if before: # Return the previous event's tick return previous.tick else: # Return this event's tick return ev.tick previous = ev return max(mid.trackpool).tick def _ticks_to_ticks(ticks, before=False): # Find the tick time of the first event after the given time # or the last event before it if ticks is not None: previous = min(mid.trackpool) for ev in sorted(mid.trackpool): # Look for the first event after the time if ev.tick >= ticks: if before: # Return the previous event's tick return previous.tick else: # Return this event's tick return ev.tick previous = ev return max(mid.trackpool).tick def _get_time(ticks, before=False): # Find the event time of the first event after the given tick time # or the last event before it previous = min(mid.trackpool) if ticks is not None: for ev in sorted(mid.trackpool): # Look for the first event after the time in ticks if ev.tick >= ticks: if before: # Return the previous event's time return previous.msdelay else: # Return this event's time return ev.msdelay previous = ev return max(mid.trackpool).msdelay def _parse_time(val, before=False): if val.endswith("s"): # Value in seconds # Convert to ticks return _time_to_ticks(float(val[:-1]), before=before) else: return int(val) # Work out start and end points if options.start is not None: start = _parse_time(options.start, before=False) else: start = 0 if options.end is not None: end = _parse_time(options.end, before=True) else: end = None if end is not None and start > end: print "Start time of %d ticks > end time of %d ticks" % (start, end) sys.exit(1) # Cut the stream to the desired start and end slc = EventStreamSlice(mid, start, end) trimmed_mid = slc.to_event_stream(repeat_playing=False) # Print out some info print "Start tick: %s" % start print "End tick: %s" % end print print "First event tick: %s" % _ticks_to_ticks(start) print "Last event tick: %s" % _ticks_to_ticks(end, before=True) print print "Start time: %ss" % (float(_get_time(start)) / 1000.0) print "Last event time: %ss" % (float(_get_time(end, before=True)) / 1000.0) print print "%d events" % len(trimmed_mid.trackpool) # Record playing time timer = ExecutionTimer() if options.output is None: # Play the output by default try: play_stream(trimmed_mid, block=True) except KeyboardInterrupt: print "\nPlayed for %.2f seconds" % timer.get_time() else: # Output to a file outfile = os.path.abspath(options.output) write_midifile(trimmed_mid, outfile) print "Output written to %s" % outfile
def parse(self, derivations=False, summaries=False, inspect=False): # Find out from the tagger how long the input it read in was input_length = self.tagger.input_length # Create and initialise a chart for parsing # Don't initialise the chart with signs - we'll add signs gradually instead chart = self._create_chart([[]] * input_length, derivations=derivations) # Stop after a given number of iterations if self.options['max_iter'] == 0: max_iter = None else: max_iter = self.options['max_iter'] timeout = 60 * self.options['timeout'] check_timeout = timeout > 0 # This is where progress output will go # Note that it's not the same as logger, which is the main system logger prog_logger = self.logger if check_timeout: prog_logger.info("Due to timeout after %d mins" % self.options['timeout']) ################################################## ### The dummy parse loop # Keep track of how long since we started for timing out timeout_timer = ExecutionTimer() signs_added = True offset = 0 try: # Keep adding signs until none left while len(chart.get_signs(0, input_length)) == 0 and signs_added: if max_iter is not None and offset >= max_iter: # Exceded maximum number of iterations: give up prog_logger.info("Reached maximum number of iterations: "\ "continuing to backoff/fail") break prog_logger.info(">>> Parsing iteration: %d" % (offset + 1)) # Get new signs from the tagger added = self._add_signs(offset=offset) # Note whether we added anything new signs_added = bool(added) # Check whether the timeout has expired if check_timeout: if int(timeout_timer.get_time()) > timeout: raise ParserTimeout # Don't do any parsing: just go round again to get more signs offset += 1 except ParserTimeout: # The given timeout elapsed: just continue with no parses logger.debug("Parse loop timeout (%d mins) expired" % self.options['timeout']) prog_logger.info("Parse timeout (%d mins) expired: continuing "\ "to backoff/fail" % self.options['timeout']) parses = [] # If a backoff model was given, always use it now if self.backoff is not None: backoff_results = self.run_backoff() if len(backoff_results) > 0: for res in backoff_results: # Put the semantics result into a sign, with a dummy # syntactic category sign = self.grammar.formalism.Syntax.Sign( self.grammar.formalism.Syntax.DummyCategory(), res) # If the semantics has a probability, put this on the sign if hasattr(res, "probability"): sign.probability = res.probability parses.append(sign) return parses
def main(): usage = "%prog [options] <midi-input>" description = ( "Trims a MIDI file to the required start and end points. " "By default, plays the trimmed MIDI (for testing) and can also write " "it out to a file." ) parser = OptionParser(usage=usage, description=description) parser.add_option( "-s", "--start", dest="start", action="store", help="start point, in ticks as 'x', or in seconds as 'xs'" ) parser.add_option("-e", "--end", dest="end", action="store", help="end point (formatted as -s)") parser.add_option( "-o", "--output", dest="output", action="store", help="MIDI file to output to. If given, output is stored instead of being played", ) options, arguments = parser.parse_args() if len(arguments) == 0: print >> sys.stderr, "You must specify a MIDI file" sys.exit(1) mid = read_midifile(arguments[0]) def _time_to_ticks(time, before=False): # Find the tick time of the first event after the given time # or the last event before it mstime = int(time * 1000) if time is not None: previous = min(mid.trackpool) for ev in sorted(mid.trackpool): # Look for the first event after the time if ev.msdelay >= mstime: if before: # Return the previous event's tick return previous.tick else: # Return this event's tick return ev.tick previous = ev return max(mid.trackpool).tick def _ticks_to_ticks(ticks, before=False): # Find the tick time of the first event after the given time # or the last event before it if ticks is not None: previous = min(mid.trackpool) for ev in sorted(mid.trackpool): # Look for the first event after the time if ev.tick >= ticks: if before: # Return the previous event's tick return previous.tick else: # Return this event's tick return ev.tick previous = ev return max(mid.trackpool).tick def _get_time(ticks, before=False): # Find the event time of the first event after the given tick time # or the last event before it previous = min(mid.trackpool) if ticks is not None: for ev in sorted(mid.trackpool): # Look for the first event after the time in ticks if ev.tick >= ticks: if before: # Return the previous event's time return previous.msdelay else: # Return this event's time return ev.msdelay previous = ev return max(mid.trackpool).msdelay def _parse_time(val, before=False): if val.endswith("s"): # Value in seconds # Convert to ticks return _time_to_ticks(float(val[:-1]), before=before) else: return int(val) # Work out start and end points if options.start is not None: start = _parse_time(options.start, before=False) else: start = 0 if options.end is not None: end = _parse_time(options.end, before=True) else: end = None if end is not None and start > end: print "Start time of %d ticks > end time of %d ticks" % (start, end) sys.exit(1) # Cut the stream to the desired start and end slc = EventStreamSlice(mid, start, end) trimmed_mid = slc.to_event_stream(repeat_playing=False) # Print out some info print "Start tick: %s" % start print "End tick: %s" % end print print "First event tick: %s" % _ticks_to_ticks(start) print "Last event tick: %s" % _ticks_to_ticks(end, before=True) print print "Start time: %ss" % (float(_get_time(start)) / 1000.0) print "Last event time: %ss" % (float(_get_time(end, before=True)) / 1000.0) print print "%d events" % len(trimmed_mid.trackpool) # Record playing time timer = ExecutionTimer() if options.output is None: # Play the output by default try: play_stream(trimmed_mid, block=True) except KeyboardInterrupt: print "\nPlayed for %.2f seconds" % timer.get_time() else: # Output to a file outfile = os.path.abspath(options.output) write_midifile(trimmed_mid, outfile) print "Output written to %s" % outfile
def do_parse(grammar, tagger_cls, parser_cls, input, topts, popts, backoff, npopts, options, identifier, multiprocessing=False, logfile=None, partition=None): """ Function called for each input to do tagging and parsing and return the results. It's a separate function so that we can hand it over to worker processes to do multiprocessing. @type logfile: str @param logfile: filename to send logging output to. If None, will log to stderr """ # If the input's a string, preprocess it if isinstance(input, str): input = input.rstrip("\n") if len(input) == 0: return input = ChordInput.from_string(input) print "Processing input: %s (%s)" % (input, identifier) if logfile is None: # Sending logging output to stderr logger = create_plain_stderr_logger() else: logger = create_logger(filename=logfile) print "Logging parser progress to %s" % logfile # Prepare an initial response # We'll fill in some values of this later response = { 'tagger' : None, 'parser' : None, 'input' : input, 'error' : None, 'messages' : [], 'time' : None, 'identifier' : identifier, 'results' : None, 'timed_out' : False, } tagger = None parser = None messages = [] if options.short_progress: # Only output the short form of the progress reports progress = 2 elif options.long_progress: progress = 1 else: progress = 0 # Start a timer now to time the parse timer = ExecutionTimer(clock=True) # Catch any errors and continue to the next input, instead of giving up try: ######### Do that parsing thang logger.info("Tagging sequence (%d timesteps)" % len(input)) # Prepare a suitable tagger component tagger = tagger_cls(grammar, input, options=topts.copy(), logger=logger) if not multiprocessing: response['tagger'] = tagger # Create a parser using this tagger parser = parser_cls(grammar, tagger, options=popts.copy(), backoff=backoff, backoff_options=npopts.copy(), logger=logger) if not multiprocessing: response['parser'] = parser try: # Parse to produce a list of results results = parser.parse(derivations=options.derivations, summaries=progress) except (KeyboardInterrupt, Exception), err: if multiprocessing: # Don't go interactive if we're in a subprocess # Instead, just return with an error response.update({ 'error' : exception_tuple(str_tb=True), }) return response else: # Drop into the shell if type(err) == KeyboardInterrupt: print "Dropping out on keyboard interrupt" print "Entering shell: use 'chart' command to see current state of parse" elif options.error_shell: print >> sys.stderr, "Error parsing %s" % str(input) print >> sys.stderr, "The error was:" traceback.print_exc(file=sys.stderr) # If we keyboard interrupted, always go into the shell, so # the user can see how far we got if options.error_shell or type(err) == KeyboardInterrupt: # Instead of exiting, enter the interactive shell print from jazzparser.shell import interactive_shell env = {} env.update(globals()) env.update(locals()) interactive_shell(parser.chart.parses,options,tagger,parser, grammar.formalism,env,input_data=input) return else: raise except (KeyboardInterrupt, Exception), err: if multiprocessing: response.update({ 'error' : exception_tuple(str_tb=True), }) return response else: if type(err) == KeyboardInterrupt: print "Exiting on keyboard interrupt" sys.exit(1) else: response.update({ 'error' : exception_tuple(str_tb=True), 'messages' : messages, 'time' : timer.get_time(), }) return response