Python实现Tiny语言解析器遇报错,请求技术协助排查
Fixing Issues in Your Tiny Language Parser's Expression Handling
Alright, let's dig into the problems with your parser code and fix them one by one. The core issues are in how you implemented the recursive expression rules (like simple_exp, term, exp) and some incomplete statement handling. Here's a breakdown of the fixes:
Key Problems in Your Current Code
- Broken
simple_explogic: It only checks for leading+/-but doesn't properly handle the recursive combination of terms and add operations. - Incomplete
termimplementation: Ignores the recursive structure of factors and multiply operations. - Flawed
expvalidation: Fails to accept a singlesimple_exp(without a comparison operator). - Incomplete statements:
repeat_stmtdoesn't handle theUNTILclause, andassign_stmt/write_stmtskip parsing expressions. - Incorrect string comparison: Using
isinstead of==for checking token values (unsafe in Python, asiscompares object identity rather than string content).
Corrected Parser Code
import scanner3 def program(l): if len(l) < 1: print("Minimum number of expressions is not met") return False # Check if last token is a semicolon (invalid per grammar) if l[-1].value == ";": print("ERROR: Semicolon at last line") return False return stmt_seq(l) def stmt_seq(l): if not stmt(l): return False # Handle optional semicolon + subsequent statements while l and l[0].value == ";": l.pop(0) if not stmt(l): return False return True def stmt(l): if if_stmt(l): print("Parsed IF statement") return True elif repeat_stmt(l): print("Parsed REPEAT statement") return True elif assign_stmt(l): print("Parsed ASSIGN statement") return True elif read_stmt(l): print("Parsed READ statement") return True elif write_stmt(l): print("Parsed WRITE statement") return True else: if l: print(f"ERROR: Invalid statement at line {l[0].line_no}") return False def if_stmt(l): if not l or l[0].value != "IF": return False l.pop(0) # Parse the condition expression if not exp(l): return False if not l or l[0].value != "THEN": print(f"ERROR: Expected THEN at line {l[0].line_no}") return False l.pop(0) # Parse THEN statement sequence if not stmt_seq(l): return False # Handle optional ELSE clause if l and l[0].value == "ELSE": l.pop(0) if not stmt_seq(l): return False # Check for END if not l or l[0].value != "END": print(f"ERROR: Expected END at line {l[0].line_no}") return False l.pop(0) return True def repeat_stmt(l): if not l or l[0].value != "REPEAT": return False l.pop(0) # Parse the statement sequence inside REPEAT if not stmt_seq(l): return False if not l or l[0].value != "UNTIL": print(f"ERROR: Expected UNTIL at line {l[0].line_no}") return False l.pop(0) # Parse the UNTIL condition expression if not exp(l): return False return True def assign_stmt(l): if not l or l[0].type != 'var' or len(l) < 2: return False if l[1].value != ":=": return False # Consume variable and assignment operator l.pop(0) l.pop(0) # Parse the right-hand side expression return exp(l) def read_stmt(l): if not l or l[0].value != 'READ' or len(l) < 2: return False if l[1].type != "var": print(f"ERROR: Expected variable in READ at line {l[0].line_no}") return False l.pop(0) l.pop(0) return True def write_stmt(l): if not l or l[0].value != "WRITE": return False l.pop(0) # Parse the expression to write return exp(l) def exp(l): # Exp -> SimpleExp [ComparisonOp SimpleExp] if not simple_exp(l): return False # Optional comparison operator + second simple exp if l and (l[0].value in ("<", ">", "=")): comparison_op(l) if not simple_exp(l): return False return True def comparison_op(l): if not l or l[0].value not in ("<", ">", "="): print(f"ERROR: Invalid comparison operator at line {l[0].line_no}") return False l.pop(0) return True def simple_exp(l): # SimpleExp -> [AddOp] Term {AddOp Term} optional_op = False if l and l[0].value in ("+", "-"): add_op(l) optional_op = True # Must have at least one term if not term(l): return False # Handle repeated AddOp + Term while l and l[0].value in ("+", "-"): add_op(l) if not term(l): return False return True def add_op(l): if not l or l[0].value not in ("+", "-"): print(f"ERROR: Invalid add operator at line {l[0].line_no}") return False l.pop(0) return True def term(l): # Term -> Factor {MulOp Factor} if not factor(l): return False # Handle repeated MulOp + Factor while l and l[0].value in ("*", "/"): mul_op(l) if not factor(l): return False return True def mul_op(l): if not l or l[0].value not in ("*", "/"): print(f"ERROR: Invalid multiply operator at line {l[0].line_no}") return False l.pop(0) return True def factor(l): if not l: return False current_token = l[0] if current_token.value == "(": l.pop(0) if not exp(l): return False if not l or l[0].value != ")": print(f"ERROR: Expected closing parenthesis at line {current_token.line_no}") return False l.pop(0) return True elif current_token.type == "num": l.pop(0) return True elif current_token.type == "var": l.pop(0) return True else: print(f"ERROR: Invalid factor at line {current_token.line_no}") return False # Main execution tokens = scanner3.tagheez("res.txt").tokenz print("Token list:") for wa7da in tokens: print(f"{wa7da.value}, {wa7da.type} in line {wa7da.line_no}") print("\nParser result:", program(tokens))
Key Fixes Explained
simple_exp: Now correctly handles optional leading+/-, followed by a term, then any number ofAddOp + Termcombinations to match the grammar.term: Implements the recursive rule ofFactor {MulOp Factor}to handle chains of multiplication/division operations.exp: Accepts a singlesimple_exp(without comparison) and properly handles the optional comparison operator + second expression.repeat_stmt: Completes the grammar rule by parsing thestmt_seqinsideREPEATand the requiredUNTILexpression.assign_stmt/write_stmt: Reinstates expression parsing for the right-hand side of assignments and the value to write, which was missing in your original code.- String comparisons: Replaced all
ischecks with==for safe, correct string value comparison. stmt_seq: Now handles multiple statements separated by semicolons correctly using a loop, instead of a single recursive call.
内容的提问来源于stack exchange,提问作者Mariam Mohie Sleem
相关产品推荐
相关产品推荐

