Upload block_relation_builder.py
Browse files- utils/block_relation_builder.py +85 -12
utils/block_relation_builder.py
CHANGED
|
@@ -2716,21 +2716,94 @@ def generate_plan(generated_input, opcode_keys, pseudo_code):
|
|
| 2716 |
# if "KEY_OPTION" in info["fields"] and opcode == "event_whenkeypressed": # For event_whenkeypressed hat block's field
|
| 2717 |
# m = re.search(r"when\s*\[([^\]]+)\s*v\] key pressed", stmt_for_parse, re.IGNORECASE)
|
| 2718 |
# if m: info["fields"]["KEY_OPTION"] = [m.group(1).strip(), None]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2719 |
if "KEY_OPTION" in info["fields"] and opcode == "event_whenkeypressed":
|
| 2720 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2721 |
if m:
|
| 2722 |
-
|
| 2723 |
-
|
| 2724 |
-
|
| 2725 |
-
|
| 2726 |
-
|
| 2727 |
-
|
| 2728 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2729 |
else:
|
| 2730 |
-
|
| 2731 |
-
if
|
| 2732 |
-
|
| 2733 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2734 |
# if "BACKDROP" in info["fields"] and opcode == "event_whenbackdropswitchesto": # For event_whenbackdropswitchesto hat block's field
|
| 2735 |
# m = re.search(r"when backdrop switches to\s*\[([^\]]+)\s*v\]", stmt_for_parse, re.IGNORECASE)
|
| 2736 |
# if m: info["fields"]["BACKDROP"] = [m.group(1).strip(), None]
|
|
|
|
| 2716 |
# if "KEY_OPTION" in info["fields"] and opcode == "event_whenkeypressed": # For event_whenkeypressed hat block's field
|
| 2717 |
# m = re.search(r"when\s*\[([^\]]+)\s*v\] key pressed", stmt_for_parse, re.IGNORECASE)
|
| 2718 |
# if m: info["fields"]["KEY_OPTION"] = [m.group(1).strip(), None]
|
| 2719 |
+
# if "KEY_OPTION" in info["fields"] and opcode == "event_whenkeypressed":
|
| 2720 |
+
# m = re.search(r"when\s*\[([^\]]+)\s*v\]\s*key pressed", stmt_for_parse, re.IGNORECASE)
|
| 2721 |
+
# if m:
|
| 2722 |
+
# option = m.group(1).strip()
|
| 2723 |
+
# # Valid key options
|
| 2724 |
+
# valid_options = [ "space", "up arrow", "down arrow", "right arrow", "left arrow", "any",
|
| 2725 |
+
# "a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9"] # temporary
|
| 2726 |
+
# cleaned = re.sub(r"[^a-z0-9]", "", option.lower()).strip()
|
| 2727 |
+
# normalized_map = { re.sub(r"[^a-z0-9]", "", v.lower()): v for v in valid_options }
|
| 2728 |
+
# if cleaned in normalized_map: option_val = normalized_map[cleaned]
|
| 2729 |
+
# else:
|
| 2730 |
+
# match = difflib.get_close_matches(cleaned, normalized_map.keys(), n=1, cutoff=0.5)
|
| 2731 |
+
# if match: option_val = normalized_map[match[0]]
|
| 2732 |
+
# else: option_val = "space"
|
| 2733 |
+
# info["fields"]["KEY_OPTION"] = [option_val, None]
|
| 2734 |
if "KEY_OPTION" in info["fields"] and opcode == "event_whenkeypressed":
|
| 2735 |
+
print("event_whenkeypressed--here")
|
| 2736 |
+
stmt = stmt_for_parse
|
| 2737 |
+
|
| 2738 |
+
# single regex to capture many forms:
|
| 2739 |
+
# - [up arrow], (up arrow)
|
| 2740 |
+
# - when key up arrow pressed
|
| 2741 |
+
# - when up arrow key pressed
|
| 2742 |
+
# - when up arrow pressed
|
| 2743 |
+
pattern = re.compile(
|
| 2744 |
+
r"(?:\[\s*([^\]]+?)\s*\]|\(\s*([^\)]+?)\s*\)|when\s+key\s+([A-Za-z0-9\-\s]+?)\s+pressed|when\s+([A-Za-z0-9\-\s]+?)\s+key\s+pressed|when\s+([A-Za-z0-9\-\s]+?)\s+pressed)",
|
| 2745 |
+
re.IGNORECASE
|
| 2746 |
+
)
|
| 2747 |
+
|
| 2748 |
+
m = pattern.search(stmt)
|
| 2749 |
+
option = ""
|
| 2750 |
if m:
|
| 2751 |
+
# pick the first non-empty capture group
|
| 2752 |
+
for g in m.groups():
|
| 2753 |
+
if g:
|
| 2754 |
+
option = g.strip()
|
| 2755 |
+
break
|
| 2756 |
+
|
| 2757 |
+
print("raw extracted option:", repr(option))
|
| 2758 |
+
|
| 2759 |
+
# inline normalization (no def)
|
| 2760 |
+
cleaned = option.lower().strip()
|
| 2761 |
+
# trim surrounding quotes, replace hyphens with spaces, remove trailing " v" like "[x v]"
|
| 2762 |
+
cleaned = re.sub(r'^[\'"]+|[\'"]+$', '', cleaned)
|
| 2763 |
+
cleaned = cleaned.replace('-', ' ')
|
| 2764 |
+
cleaned = re.sub(r'\s+v\s*$', '', cleaned) # trailing " v"
|
| 2765 |
+
cleaned = re.sub(r'[^\w\s]', '', cleaned) # remove punctuation
|
| 2766 |
+
cleaned = re.sub(r'\s+', ' ', cleaned).strip() # collapse spaces
|
| 2767 |
+
print("normalized extracted option:", repr(cleaned))
|
| 2768 |
+
|
| 2769 |
+
# allowed keys (expand as you need)
|
| 2770 |
+
valid_options = [
|
| 2771 |
+
"space", "up arrow", "down arrow", "right arrow", "left arrow", "any",
|
| 2772 |
+
"enter", "tab", "escape", "backspace",
|
| 2773 |
+
"a","b","c","d","e","f","g","h","i","j","k","l","m",
|
| 2774 |
+
"n","o","p","q","r","s","t","u","v","w","x","y","z",
|
| 2775 |
+
"0","1","2","3","4","5","6","7","8","9"
|
| 2776 |
+
]
|
| 2777 |
+
|
| 2778 |
+
# build normalization map inline
|
| 2779 |
+
normalized_map = {}
|
| 2780 |
+
for v in valid_options:
|
| 2781 |
+
nv = v.lower().replace('-', ' ')
|
| 2782 |
+
nv = re.sub(r'[^\w\s]', '', nv)
|
| 2783 |
+
nv = re.sub(r'\s+', ' ', nv).strip()
|
| 2784 |
+
normalized_map[nv] = v
|
| 2785 |
+
|
| 2786 |
+
option_val = None
|
| 2787 |
+
if cleaned in normalized_map:
|
| 2788 |
+
option_val = normalized_map[cleaned]
|
| 2789 |
+
print("option matched exact:", option_val)
|
| 2790 |
+
else:
|
| 2791 |
+
# fuzzy match as fallback
|
| 2792 |
+
keys = list(normalized_map.keys())
|
| 2793 |
+
match = difflib.get_close_matches(cleaned, keys, n=1, cutoff=0.55)
|
| 2794 |
+
if match:
|
| 2795 |
+
option_val = normalized_map[match[0]]
|
| 2796 |
+
print("option fuzzy matched:", option_val)
|
| 2797 |
else:
|
| 2798 |
+
# accept single char or digit
|
| 2799 |
+
if re.fullmatch(r'[a-z0-9]', cleaned):
|
| 2800 |
+
option_val = cleaned
|
| 2801 |
+
print("option single-char accepted:", option_val)
|
| 2802 |
+
else:
|
| 2803 |
+
option_val = option if option else cleaned
|
| 2804 |
+
print("option fallback (unrecognized):", option_val)
|
| 2805 |
+
|
| 2806 |
+
info["fields"]["KEY_OPTION"] = [option_val, None]
|
| 2807 |
# if "BACKDROP" in info["fields"] and opcode == "event_whenbackdropswitchesto": # For event_whenbackdropswitchesto hat block's field
|
| 2808 |
# m = re.search(r"when backdrop switches to\s*\[([^\]]+)\s*v\]", stmt_for_parse, re.IGNORECASE)
|
| 2809 |
# if m: info["fields"]["BACKDROP"] = [m.group(1).strip(), None]
|