feat: add parser visitor for Tamil keywords
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
"""Parse Tamil code into Python AST."""
|
||||
|
||||
from typing import Any
|
||||
import ast
|
||||
|
||||
|
||||
class TamilParser(ast.NodeVisitor):
|
||||
"""Parse Tamil code and map keywords to Python."""
|
||||
|
||||
def __init__(self, keywords: dict[str, str]):
|
||||
self.keywords = keywords
|
||||
self.errors: list[str] = []
|
||||
|
||||
def parse(self, code: str) -> ast.AST:
|
||||
"""Parse Tamil code and return Python AST."""
|
||||
try:
|
||||
tree = ast.parse(code)
|
||||
self._transform(tree)
|
||||
return tree
|
||||
except SyntaxError as e:
|
||||
self.errors.append(f"SyntaxError at line {e.lineno}: {e.msg}")
|
||||
raise
|
||||
|
||||
def _transform(self, node: ast.AST) -> None:
|
||||
"""Transform node to handle Tamil keywords."""
|
||||
node = self._visit(node)
|
||||
if isinstance(node, ast.AST):
|
||||
for field, value in ast.iter_fields(node):
|
||||
if isinstance(value, list):
|
||||
for i, item in enumerate(value):
|
||||
if isinstance(item, ast.AST):
|
||||
value[i] = self._visit(item)
|
||||
elif isinstance(value, ast.AST):
|
||||
setattr(node, field, self._visit(value))
|
||||
|
||||
def _visit(self, node: ast.AST) -> Any:
|
||||
"""Visit and transform a single node."""
|
||||
if not hasattr(node, "lineno"):
|
||||
return node
|
||||
|
||||
line = node.lineno
|
||||
col = getattr(node, "col_offset", 0)
|
||||
|
||||
keyword = self._get_keyword_at_position(node, line, col)
|
||||
if keyword:
|
||||
node.keywords = self.keywords.get(keyword, keyword)
|
||||
|
||||
visitor = self._get_visitor_type(type(node))
|
||||
if visitor:
|
||||
return visitor(node)
|
||||
|
||||
return node
|
||||
|
||||
def _get_keyword_at_position(self, node: ast.AST, lineno: int, col: int) -> str | None:
|
||||
"""Check if keyword appears at given position."""
|
||||
# This is a placeholder - actual keyword detection will use tokens
|
||||
# For now, we'll handle common keywords by name
|
||||
node_type = type(node).__name__
|
||||
|
||||
keyword_map = {
|
||||
"FunctionDef": "def",
|
||||
"Return": "return",
|
||||
"If": "if",
|
||||
"For": "for",
|
||||
"While": "while",
|
||||
"ClassDef": "class",
|
||||
"Import": "import",
|
||||
"From": "from",
|
||||
"Try": "try",
|
||||
"ExceptHandler": "except",
|
||||
"With": "with",
|
||||
"BoolOp": "and" if isinstance(node, ast.BoolOp) and node.op.__class__.__name__ == "And" else "or",
|
||||
"Compare": "in",
|
||||
"NamedExpr": "if",
|
||||
}
|
||||
|
||||
return keyword_map.get(node_type)
|
||||
|
||||
def _get_visitor_type(self, node_type: type) -> Any | None:
|
||||
"""Get visitor method for node type."""
|
||||
visitor_name = f"visit_{node_type.__name__}"
|
||||
return getattr(self, visitor_name, None)
|
||||
|
||||
44
tests/test_parser.py
Normal file
44
tests/test_parser.py
Normal file
@@ -0,0 +1,44 @@
|
||||
"""Test parser functionality."""
|
||||
|
||||
import pytest
|
||||
from src.tampy.transpiler import TamilParser
|
||||
|
||||
|
||||
def test_parse_simple_python():
|
||||
"""Test parsing simple Python code."""
|
||||
code = "print('hello')"
|
||||
keywords = {"print": "இருப்பு"}
|
||||
|
||||
parser = TamilParser(keywords)
|
||||
tree = parser.parse(code)
|
||||
|
||||
assert isinstance(tree, ast.Module)
|
||||
|
||||
|
||||
def test_parse_import_statement():
|
||||
"""Test parsing import statement."""
|
||||
code = "import sys"
|
||||
keywords = {"import": "மேற்கோள்கள்"}
|
||||
|
||||
parser = TamilParser(keywords)
|
||||
tree = parser.parse(code)
|
||||
|
||||
assert isinstance(tree, ast.Module)
|
||||
|
||||
|
||||
def test_parse_function_definition():
|
||||
"""Test parsing function definition."""
|
||||
code = "def foo(): pass"
|
||||
keywords = {"def": "வரையறை"}
|
||||
|
||||
parser = TamilParser(keywords)
|
||||
tree = parser.parse(code)
|
||||
|
||||
assert isinstance(tree, ast.Module)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_parse_simple_python()
|
||||
test_parse_import_statement()
|
||||
test_parse_function_definition()
|
||||
print("All tests passed")
|
||||
Reference in New Issue
Block a user