philips-cnc6600-interpreter/src/Program/Parser/WordParser.php

65 lines
1.3 KiB
PHP

<?php
namespace Program\Parser;
use Program\Word;
class WordParser
{
/**
* @param string $filename
* @return Word[]
*/
public function parseFile(string $filename): array
{
$lines = explode(PHP_EOL, file_get_contents($filename));
$lines = array_filter($lines);
return $this->parse($lines);
}
/**
* @param string[] $lines
* @return Word[]
*/
public function parse(array $lines): array
{
/** @var Word[] $words */
$words = [];
foreach ($lines as $line) {
$characters = str_split(trim($line) . ' ');
$state = 'NONE';
$wordBuffer = [];
foreach ($characters as $character) {
if ('READING' === $state) {
if ('-' === $character || is_numeric($character)) {
$wordBuffer['value'] .= $character;
continue;
}
// Word is finished
$words[] = new Word($wordBuffer['register'], $wordBuffer['value']);
$wordBuffer = [];
$state = 'NONE';
}
if ('NONE' === $state && ctype_alpha($character)) {
$state = 'READING';
$wordBuffer = ['register' => $character, 'value' => ''];
continue;
}
if (strpos($line, 'EOF') !== false) {
break 2; // End of program reached
}
if (';' === $character) {
break; // Rest of line is a comment
}
}
}
return $words;
}
}