diff --git a/gdb-port/README.md b/gdb-port/README.md index 18da846bba32aaf7825eeddec45c775014d75f4d..c7ba895a6620e0ea6ce8f2e032039e595ec8adeb 100644 --- a/gdb-port/README.md +++ b/gdb-port/README.md @@ -78,6 +78,16 @@ hammer-parse-continue Alias of GDB `continue`. May change later. +``` +hammer-parse-apply +``` + +Applies the current parser and prints the HParseResult. More precisely: + +Steps execution until the "current" parser (the one `h_do_parse()` has been called on at the time of command execution) returns its result. Thereafter, it steps to the next invocation of `h_do_parse`, and optionally prints the parser stack and input preview, as with `hammer-parse-step`. + +In terms of call stack navigation, this is roughly analogous to executing `finish` to step out of the current stack frame, followed by stepping into the next function call. (With the difference, that this commands steps between "frames" of the parser stack) + ## Querying ``` diff --git a/gdb-port/commands.py b/gdb-port/commands.py index e0668ffef7a0afa1854360b3f9b8a6f79ebb9f21..c8b625a5e3089a85cbdc322e57922bb422c069e8 100644 --- a/gdb-port/commands.py +++ b/gdb-port/commands.py @@ -209,7 +209,7 @@ class HammerParserPrintAST(gdb.Command): HammerParserPrintAST() # Step until the "current" parser is applied and returns the HParsedToken, stopping in h_do_parse -class HammerParseApply(gdb.Command): +class HammerParseApply(FlowControlWithPrint): def __init__(self): super(HammerParseApply, self).__init__("hammer-parse-apply", gdb.COMMAND_OBSCURE) print(":: hammer-parse-apply") @@ -224,16 +224,6 @@ class HammerParseApply(gdb.Command): gdb.set_convenience_variable("hammer_step_counter", 1) # Continue and stop at the next h_do_parse invocation gdb.execute("continue") - try: - if gdb.parameter("hammer-extended-parse-step-info"): - print("Parser stack:") - gdb.execute("hammer-parser-backtrace") - print("Input preview:") - gdb.execute("hammer-parser-preview-input") - except RuntimeError as e: - # This probably means parser-name-instrumentation.py is not loaded. - #pass - print("Exception: %s" % e) - print("Probably caused by hammer-extended-parse-step-info parameter not existing") + self.conditionally_print_backtrace() HammerParseApply() diff --git a/gdb-port/utility-commands.py b/gdb-port/utility-commands.py index ae02fba8eae20fc5195e91d469aa083e0a5d6e70..30bb43e9555b566290021b20d9bdd06be43cd10a 100644 --- a/gdb-port/utility-commands.py +++ b/gdb-port/utility-commands.py @@ -13,8 +13,23 @@ class HammerParseStopAtInputPos(gdb.Command): HammerParseStopAtInputPos() +# __init__ deliberately omitted, because this is not actually a command we want to register, just inherit from +class FlowControlWithPrint(gdb.Command): + def conditionally_print_backtrace(self): + try: + if gdb.parameter("hammer-extended-parse-step-info"): + print("Parser stack:") + gdb.execute("hammer-parser-backtrace") + print("Input preview:") + gdb.execute("hammer-parser-preview-input") + except RuntimeError as e: + # This probably means parser-name-instrumentation.py is not loaded. + #pass + print("Exception: %s" % e) + print("Probably caused by hammer-extended-parse-step-info parameter not existing") + # Implements the "step" command for parsing. One step is one invocation of h_do_parse() -class HammerParseStep(gdb.Command): +class HammerParseStep(FlowControlWithPrint): def __init__(self): super(HammerParseStep, self).__init__ ("hammer-parse-step", gdb.COMMAND_OBSCURE) print(":: hammer-parse-stop") @@ -47,19 +62,7 @@ class HammerParseStep(gdb.Command): if gdb.selected_inferior().pid > 0: gdb.execute("continue") - # These are defined in parser-name-instrumentation.py, which we load after this, but this should be fine at runtime - # TODO: factor out commands into their own file - try: - if gdb.parameter("hammer-extended-parse-step-info"): - print("Parser stack:") - gdb.execute("hammer-parser-backtrace") - print("Input preview:") - gdb.execute("hammer-parser-preview-input") - except RuntimeError as e: - # This probably means parser-name-instrumentation.py is not loaded. - #pass - print("Exception: %s" % e) - print("Probably caused by hammer-extended-parse-step-info parameter not existing") + self.conditionally_print_backtrace() HammerParseStep()