glyphic-language / interpreter /glyph_syntax.py
UnconditionalLove's picture
Upload 97 files
ed6bec6 verified
from typing import List, Dict, Any
from .glyph_dictionary_loader import get_dictionary
from .glyph_validator import validate_sequence, validate_roles
class GlyphSyntaxError(Exception): #strict syntax order of glyphs
pass
ROLE_ORDER = [
"actor",
"action",
"object",
"modifier",
"context"
]
CONTEXT_ORDER = [
"place",
"time",
"emotion",
"sensory",
"social"
]
def _get_role(entry: Dict[str, Any]) -> str:
"""Return the highest-priority role for a glyph."""
roles = entry.get("roles", [])
for r in ROLE_ORDER:
if r in roles:
return r
return "context"
def _get_context_type(entry: Dict[str, Any]) -> str:
"""Return the context subtype."""
category = entry.get("category", "")
if category.startswith("context_place"):
return "place"
if category.startswith("context_time"):
return "time"
if category.startswith("context_emotion") or category.startswith("emotion_context"):
return "emotion"
if category.startswith("context_sensory") or category.startswith("sensory_context"):
return "sensory"
if category.startswith("context_social") or category.startswith("social_context"):
return "social"
return "unknown"
def parse_syntax(glyphs: List[str]) -> Dict[str, Any]:
"""
Strict syntax parser enforcing:
- required roles
- strict ordering
- single actor/action/object
- context last
- deterministic structure
"""
validate_sequence(glyphs)
validate_roles(glyphs)
dictionary = get_dictionary()
syntax_tree = {
"actor": None,
"action": None,
"object": None,
"modifiers": [],
"context": {
"place": [],
"time": [],
"emotion": [],
"sensory": [],
"social": []
},
"raw": glyphs
}
last_role_index = -1
last_context_index = -1
for g in glyphs:
entries = dictionary.get_entry_by_glyph(g)
entry = entries[0] # canonical
role = _get_role(entry)
# Enforce ordering
role_index = ROLE_ORDER.index(role)
if role_index < last_role_index:
raise GlyphSyntaxError(
f"Invalid ordering: {g} ({role}) appears after a later role."
)
last_role_index = role_index
# Assign roles
if role == "actor":
if syntax_tree["actor"] is not None:
raise GlyphSyntaxError("Multiple actors not allowed.")
syntax_tree["actor"] = entry
elif role == "action":
if syntax_tree["action"] is not None:
raise GlyphSyntaxError("Multiple actions not allowed.")
syntax_tree["action"] = entry
elif role == "object":
if syntax_tree["object"] is not None:
raise GlyphSyntaxError("Multiple objects not allowed.")
syntax_tree["object"] = entry
elif role == "modifier":
syntax_tree["modifiers"].append(entry)
elif role == "context":
ctx_type = _get_context_type(entry)
if ctx_type == "unknown":
raise GlyphSyntaxError(f"Unknown context type for glyph {g}")
# Enforce context ordering
ctx_index = CONTEXT_ORDER.index(ctx_type)
if ctx_index < last_context_index:
raise GlyphSyntaxError(
f"Context out of order: {ctx_type} appears after later context."
)
last_context_index = ctx_index
syntax_tree["context"][ctx_type].append(entry)
return syntax_tree
def get_syntax_tree(glyphs: List[str]) -> Dict[str, Any]:
return parse_syntax(glyphs)
def is_valid_order(glyphs: List[str]) -> bool:
try:
parse_syntax(glyphs)
return True
except Exception:
return False