-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Programming/AP-TED: Add AP-TED Algorithm and Code to AST Converter (#275
- Loading branch information
1 parent
8a75867
commit 2a089a5
Showing
34 changed files
with
26,128 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
87 changes: 87 additions & 0 deletions
87
module_programming_ast/module_programming_ast/convert_code_to_ast/extract_method_and_ast.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
from antlr4 import CommonTokenStream, InputStream | ||
from antlr4.tree.Tree import ParseTreeWalker | ||
from module_programming_ast.convert_code_to_ast.languages.python.Python3Lexer import Python3Lexer | ||
from module_programming_ast.convert_code_to_ast.languages.python.Python3Parser import Python3Parser | ||
from module_programming_ast.convert_code_to_ast.languages.java.JavaLexer import JavaLexer | ||
from module_programming_ast.convert_code_to_ast.languages.java.JavaParser import JavaParser | ||
from module_programming_ast.convert_code_to_ast.languages.python.Python3MethodParserListener import \ | ||
MethodParserListener as PythonMethodParserListener | ||
from module_programming_ast.convert_code_to_ast.languages.java.JavaMethodParserListener import \ | ||
MethodParserListener as JavaMethodParserListener | ||
|
||
# TODO: DO I need the to_ast method? | ||
|
||
# Grammars for programming languages have different parse rules | ||
JAVA_PARSE_RULE = "compilationUnit" | ||
PYTHON_PARSE_RULE = "file_input" | ||
|
||
|
||
# class ASTNode: | ||
# def __init__(self, name): | ||
# self.name = name | ||
# self.children = [] | ||
# | ||
# def add_child(self, child): | ||
# self.children.append(child) | ||
# | ||
# def __repr__(self): | ||
# return f"{self.name}{self.children}" | ||
# | ||
# | ||
# def to_ast(node): | ||
# if isinstance(node, TerminalNodeImpl): | ||
# return ASTNode(node.getText()) | ||
# ast_node = ASTNode(type(node).__name__.replace('Context', '')) | ||
# for i in range(node.getChildCount()): | ||
# ast_node.add_child(to_ast(node.getChild(i))) | ||
# return ast_node | ||
|
||
|
||
def parse_java_file(source_code: str): | ||
return parse_file(source_code, JavaLexer, JavaParser, JAVA_PARSE_RULE, JavaMethodParserListener) | ||
|
||
|
||
def parse_python_file(source_code: str): | ||
return parse_file(source_code, Python3Lexer, Python3Parser, PYTHON_PARSE_RULE, PythonMethodParserListener) | ||
|
||
|
||
def parse_file(source_code, lexer_class, parser_class, parse_rule, listener_class): | ||
input_stream = InputStream(source_code) | ||
lexer = lexer_class(input_stream) | ||
stream = CommonTokenStream(lexer) | ||
parser = parser_class(stream) | ||
tree = getattr(parser, parse_rule)() | ||
|
||
listener = listener_class(parser) | ||
walker = ParseTreeWalker() | ||
walker.walk(listener, tree) | ||
print(listener.methods) | ||
|
||
return listener.methods.copy() | ||
|
||
|
||
def parse(source_code: str, programming_language: str): | ||
if programming_language == "java": | ||
return parse_java_file(source_code) | ||
if programming_language == "python": | ||
return parse_python_file(source_code) | ||
raise ValueError(f"Unsupported programming language: {programming_language}") | ||
|
||
|
||
if __name__ == "__main__": | ||
# file_path2 = "../test_files/test_java_1.java" | ||
# parse_java_file(file_path2) | ||
|
||
code = """def process_numbers(numbers): | ||
total = 0 | ||
for number in numbers: | ||
if number % 2 == 1: | ||
total += number | ||
else: | ||
total -= number | ||
if total > 0: | ||
print("Positive total:", total) | ||
else: | ||
print("Non-positive total:", total)""" | ||
code1 = parse_python_file(code) | ||
code2 = parse_python_file(code) |
27 changes: 27 additions & 0 deletions
27
module_programming_ast/module_programming_ast/convert_code_to_ast/get_feedback_methods.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
from typing import Optional | ||
|
||
from athena.programming import Submission, Feedback | ||
from module_programming_ast.convert_code_to_ast.extract_method_and_ast import parse | ||
from module_programming_ast.convert_code_to_ast.method_node import MethodNode | ||
from athena.logger import logger | ||
|
||
|
||
def get_feedback_method(submission: Submission, feedback: Feedback, programming_language: str) -> Optional[MethodNode]: | ||
"""Find method that the feedback is on""" | ||
if feedback.file_path is None or feedback.line_start is None: | ||
return None | ||
try: | ||
code = submission.get_code(feedback.file_path) | ||
except UnicodeDecodeError: | ||
logger.warning("File %s in submission %d is not UTF-8 encoded.", feedback.file_path, submission.id) | ||
return None | ||
methods = parse(code, programming_language) | ||
for m in methods: | ||
if m.line_start is None or m.line_end is None: | ||
continue | ||
# method has to contain all feedback lines | ||
if m.line_start <= feedback.line_start: | ||
feedback_line_end = feedback.line_end if feedback.line_end is not None else feedback.line_start | ||
if m.line_end >= feedback_line_end: | ||
return m | ||
return None |
Empty file.
Oops, something went wrong.