<commit_before><?php

namespace ToyLang\Parser;

use ToyLang\Core\Lexer\Token\Token;
use ToyLang\Parser\Node\ExpressionNode;
use ToyLang\Parser\Node\NumberNode;
use ToyLang\Parser\Node\ProgramNode;
use ToyLang\Parser\Node\StatementNode;

class LanguageParser
{
    /**
     * @var Token[]
     */
    private $tokens;

    /**
     * @param Token[] $tokens
     * @return ProgramNode
     */
    public function parse($tokens)
    {
        if (!$tokens) {
            throw new \InvalidArgumentException('Cannot parse an empty tokens tree');
        }

        $this->tokens = $tokens;

        return $this->parseProgram();
    }

    protected function discard()
    {
        array_shift($this->tokens);
    }

    protected function skipWhitespace()
    {
        $tokens = &$this->tokens;
        $continue = true;

        while ($continue && $tokens) {
            $token = $tokens[0];

            if ($token->getTokenType()->getName() === 'WHITESPACE') {
                array_shift($tokens);
            } else {
                $continue = false;
            }
        }
    }

    /**
     * @return Token
     */
    protected function peek()
    {
        $this->skipWhitespace();
        return $this->tokens[0];
    }

    /**
     * @param string $expectedType
     * @return Token
     * @throws \Exception<commit_msg>Changed the way whitespace is handled in the parser, and added the ability to peek multiple tokens ahead.<commit_after><?php

namespace ToyLang\Parser;

use ToyLang\Core\Lexer\Token\Token;
use ToyLang\Parser\Node\ExpressionNode;
use ToyLang\Parser\Node\NumberNode;
use ToyLang\Parser\Node\ProgramNode;
use ToyLang\Parser\Node\StatementNode;

class LanguageParser
{
    /**
     * @var Token[]
     */
    private $tokens;

    /**
     * @param Token[] $tokens
     * @return ProgramNode
     */
    public function parse($tokens)
    {
        if (!$tokens) {
            throw new \InvalidArgumentException('Cannot parse an empty tokens tree');
        }

        $this->tokens = $this->removeWhitespace($tokens);

        return $this->parseProgram();
    }

    protected function discard()
    {
        array_shift($this->tokens);
    }

    /**
     * @param Token[] $tokens
     * @return Token[]
     */
    protected function removeWhitespace($tokens)
    {
        $newTokens = [];

        foreach ($tokens as $token) {
            if ($token->getTokenType()->getName() !== 'WHITESPACE') {
                $newTokens[] = $token;
            }
        }

        return $newTokens;
    }

    /**
     * @param int $count
     * @return Token
     */
    protected function peek($count = 1)
    {
        return $this->tokens[$count - 1];
    }

    /**
     * @param string $expectedType
     * @return Token
     * @throws \Exception
{'fraction_non_alphanumeric': 0.1325907294286741, 'fraction_numerical': 0.001437297879985627, 'mean_word_length': 2.0097297297297296, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 18, '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': '5603843', 'n_tokens_mistral': 817, 'n_tokens_neox': 788, 'n_words': 179}