<commit_before>package model;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Stack;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import model.node.NodeFactory;
import model.node.TreeNode;


public class Parser {

    private List<Entry<String, Pattern>> myPatterns;
    private Turtle myTurtle;
    private Deque<String[]> tokenProperties;

    public Parser (List<Entry<String, Pattern>> patterns, Turtle turtle) {
        myPatterns = patterns;
        myTurtle = turtle;
    }

    public List<TreeNode> parse (String feed) {
        List<String> tokens = Arrays.asList(feed.split("\\p{Z}"));

        // read Resource Bundle, convert tokens to Deque
        tokenProperties = new LinkedList<String[]>(tokens.stream()
                .map(this::getMatch)
                .collect(Collectors.toList()));
        return buildTrees();
    }

    private List<TreeNode> buildTrees () {
        List<TreeNode> treeList = new ArrayList<TreeNode>(); // to be returned

        // build trees for all tokenProperties
        while (!tokenProperties.isEmpty()) {

            // TODO: must handle list starts/ends for iterators/conditionals
            // -- recognize them (error-check) but not put in tree

            // node initializes appropriate node, uses tokenProperties
            TreeNode node = getNextNode();

            // push node onto stack
            Stack<TreeNode> nodeStack = new Stack<TreeNode>();
            nodeStack.push(node);

            // continue to add children until node in node is filled
            while (!nodeStack.empty()) {
                if (nodeStack.peek().allChildrenPresent()) {
                    nodeStack.pop();
                    continue;
                }
                if (tokenProperties.isEmpty()) {
                    // throw "unexpected end of instructions" error
                    // -- e.g. fd sum 50
                }

                TreeNode childNode = getNextNode();
                nodeStack.peek().addChild(childNode);

                if (!childNode.allChildrenPresent()) {
                    nodeStack.add(childNode); // currentNode
                }
            }

            // node will have all children
            treeList.add(node);
        }
        return treeList;
    }

    private TreeNode getNextNode () {
        String[] tokenProp = getNextTokenProperty();
        // special case of creating a constant node
        if (tokenProp[0].equals("Constant")) {
            return NodeFactory.getInstance().getConstant(Double.parseDouble(tokenProp[1]));
        }
        else{
            return NodeFactory.getInstance().getNonConstant(tokenProp[0], myTurtle);
        }
    }

    private String[] getNextTokenProperty () {
        String[] tokenProp = tokenProperties.poll();
        
        if (tokenProp[0].equals("Comment")){
            // TODO: recognize comments, must know when lines end
            return getNextTokenProperty(); 
        }
        else if (tokenProp[0].equals("MakeVariable") || tokenProp[0].equals("MakeUserInstruction")) {
            // handle making new variable or udc
            // -- use [ ] as ending conditions
            return getNextTokenProperty();
        }<commit_msg>Parser's addChildren now done recursively<commit_after>package model;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Stack;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import model.node.NodeFactory;
import model.node.TreeNode;


public class Parser {

    private List<Entry<String, Pattern>> myPatterns;
    private Turtle myTurtle;
    private Deque<String[]> tokenProperties;

    public Parser (List<Entry<String, Pattern>> patterns, Turtle turtle) {
        myPatterns = patterns;
        myTurtle = turtle;
    }

    public List<TreeNode> parse (String feed) {
        List<String> tokens = Arrays.asList(feed.split("\\p{Z}"));

        // read Resource Bundle, convert tokens to Deque
        tokenProperties = new LinkedList<String[]>(tokens.stream()
                .map(this::getMatch)
                .collect(Collectors.toList()));
        return buildTrees();
    }

    private List<TreeNode> buildTrees () {
        List<TreeNode> treeList = new ArrayList<TreeNode>(); // to be returned

        // build trees for all tokenProperties
        while (!tokenProperties.isEmpty()) {

            // TODO: must handle list starts/ends for iterators/conditionals
            // -- recognize them (error-check) but not put in tree

            // appropriate node generated using tokenProperties
            TreeNode node = getNextNode();

            addChildren(node);

            // node will have all children
            treeList.add(node);
        }
        return treeList;
    }
    
    private void addChildren(TreeNode node){
        if (node.allChildrenPresent()){
            return;
        }
        if (tokenProperties.isEmpty()) {
            // throw "unexpected end of instructions" error
            // -- e.g. fd sum 50
        }
        TreeNode childNode = getNextNode();
        node.addChild(childNode);
        
        if (!childNode.allChildrenPresent()) {
            addChildren(childNode); // currentNode
        }       
        return;
    }

    private TreeNode getNextNode () {
        String[] tokenProp = getNextTokenProperty();
        // special case of creating a constant node
        if (tokenProp[0].equals("Constant")) {
            return NodeFactory.getInstance().getConstant(Double.parseDouble(tokenProp[1]));
        }
        else{
            return NodeFactory.getInstance().getNonConstant(tokenProp[0], myTurtle);
        }
    }

    private String[] getNextTokenProperty () {
        String[] tokenProp = tokenProperties.poll();
        
        if (tokenProp[0].equals("Comment")){
            // TODO: recognize comments, must know when lines end
            return getNextTokenProperty(); 
        }
        else if (tokenProp[0].equals("MakeVariable") || tokenProp[0].equals("MakeUserInstruction")) {
            // handle making new variable or udc
            // -- use [ ] as ending conditions
            return getNextTokenProperty();
        }
{'fraction_non_alphanumeric': 0.10725404732254047, 'fraction_numerical': 0.0024906600249066002, 'mean_word_length': 2.11138014527845, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1511377', 'n_tokens_mistral': 1691, 'n_tokens_neox': 1614, 'n_words': 425}