예제 #1
0
 public function __construct($scanner, $_symTable)
 {
     $args = new SymTable($_symTable);
     if (!$scanner->get()->isIdentifier()) {
         parent::simpleException($scanner, ['<IDENTIFIER>']);
     }
     $this->identifier = $scanner->get()->getValue();
     $scanner->next();
     if (!$scanner->get()->isOperator('(')) {
         parent::simpleException($scanner, ['<OPERATOR \'(\'>']);
     }
     while (!$scanner->get()->isOperator(')')) {
         $identifiers = [];
         while ($scanner->get()->isIdentifier()) {
             $identifiers[] = $scanner->get()->getValue();
             $scanner->next();
             if (!$scanner->get()->isOperator(',')) {
                 break;
             }
             $scanner->next();
         }
         if (!$scanner->get()->isOperator(':')) {
             parent::simpleException($scanner, ['<OPERATOR \':\'>']);
         }
         $scanner->next();
         $type = SymType::parseExisting($scanner, $args);
         foreach ($identifiers as $identifier) {
             $args->append(new SymVar($identifier, $type));
         }
         parent::semicolonPass($scanner);
     }
     $this->symbol = new SymProc($this->identifier->getValue(), $args);
     $_symTable->append($this->symbol);
     $scanner->next();
 }
예제 #2
0
 public function __construct($scanner, $_symTable, $identifier)
 {
     $this->symTable = new SymTable($_symTable);
     $this->identifier = $identifier;
     while ($scanner->get()->isIdentifier()) {
         //variable declaration parse
         $identifier = $scanner->get();
         if (!$scanner->nget()->isOperator(':')) {
             Node::simpleException($scanner, ['<OPERATOR \':\'>']);
         }
         $scanner->next();
         $type = SymType::parse($scanner, $_symTable, null);
         if ($type->isAnonim()) {
             $this->symTable->append($type);
         }
         $this->symTable->append(new SymVar($identifier->getValue(), $type));
         // $scanner->next();
         Node::semicolonPass($scanner);
     }
     if (!$scanner->get()->isKeyword('end')) {
         Node::simpleException($scanner, ['<KEYWORD \'end\'']);
     }
     $scanner->next();
     if ($this->symTable->count() == 0) {
         SemanticException::expected($scanner, ['<VAR DECLARATIONS>']);
     }
 }
예제 #3
0
 public function __construct($scanner, $_symTable)
 {
     if (!$scanner->get()->isKeyword()) {
         parent::simpleException($scanner, ['<KEYWORD>']);
     }
     $identifier = $scanner->get();
     $scanner->next();
     $valid = false;
     switch ($identifier->getValue()) {
         case 'break':
             $valid = Globals::$switchDepth > 0;
         case 'continue':
             $valid |= Globals::$loopDepth > 0;
             break;
         case 'exit':
             $valid |= Globals::$funcDepth > 0;
             break;
         default:
             throw new \Exception("Control keyword " . $identifier->getValue() . " not implemented yet");
     }
     if (!$valid) {
         SemanticException::illegalControlStatement($scanner, $identifier->getValue());
     }
     $this->identifier = $identifier;
 }
예제 #4
0
 public function __construct($scanner, $_symTable)
 {
     parent::requireKeyword($scanner, 'for');
     $scanner->next();
     $this->counter = VariableAccess::parse($scanner, $_symTable);
     if (!SymSimpleType::equal($this->counter->symType, Globals::getSimpleType('integer'))) {
         SemanticException::raw($scanner, 'Counter must be integer');
     }
     parent::requireOperator($scanner, ':=');
     $scanner->next();
     $this->from = new Expression($scanner, $_symTable);
     $this->from = TypeCast::tryTypeCast($this->from, 'integer');
     switch ($scanner->get()->getValue()) {
         case 'to':
             $this->direction = self::DIRECTION_ASC;
             break;
         case 'downto':
             $this->direction = self::DIRECTION_DESC;
             break;
         default:
             parent::simpleException($scanner, ['<KEYWORD \'to\'>', '<KEYWORD \'downto\'>']);
     }
     $scanner->next();
     $this->to = new Expression($scanner, $_symTable);
     $this->to = TypeCast::tryTypeCast($this->to, 'integer');
     parent::requireKeyword($scanner, 'do');
     $scanner->next();
     Globals::$loopDepth++;
     $this->statements = CompoundStatement::smartParse($scanner, $_symTable);
     Globals::$loopDepth--;
 }
예제 #5
0
 public function __construct($scanner, $_symTable)
 {
     parent::requireKeyword($scanner, 'case');
     $scanner->next();
     $this->condition = new Expression($scanner, $_symTable);
     parent::requireKeyword($scanner, 'of');
     $scanner->next();
     Globals::$switchDepth++;
     while (true) {
         if ($scanner->get()->isKeyword('else')) {
             $scanner->next();
             $this->default = CompoundStatement::smartParse($scanner, $_symTable);
             parent::semicolonPass($scanner);
             break;
         }
         $caseCondition = new Expression($scanner, $_symTable);
         $caseCondition = TypeCast::tryTypeCast($caseCondition, $this->condition->symType, false);
         parent::requireOperator($scanner, ':');
         $scanner->next();
         $caseStatements = CompoundStatement::smartParse($scanner, $_symTable);
         $this->cases[] = ["condition" => $caseCondition, "statements" => $caseStatements];
         parent::semicolonPass($scanner);
         if ($scanner->get()->isKeyword('end')) {
             break;
         }
     }
     Globals::$switchDepth--;
     parent::requireKeyword($scanner, 'end');
     $scanner->next();
 }
예제 #6
0
 public function __construct($scanner, $_symTable, $array)
 {
     $arrayType = $array->variable->symType;
     if (!is_a($arrayType, 'vendor\\SemanticParser\\Nodes\\SymArrayType')) {
         SemanticException::varAccessTypeMismatch($scanner, $arrayType, 'array');
     }
     $this->array = $array;
     $this->indexes = [];
     $continue = true;
     $idx = 0;
     while (!$scanner->get()->isOperator(']')) {
         if (!$continue) {
             parent::simpleException($scanner, ["<OPERATOR ']'>"]);
         }
         $this->indexes[$idx] = new Expression($scanner, $_symTable);
         if (!$arrayType->checkIndex($this->indexes[$idx], $idx, $_symTable)) {
             SemanticException::raw($scanner, "Array index type mismatch");
         }
         $idx++;
         $continue = $scanner->get()->isOperator(',');
         if ($scanner->get()->isOperator(']')) {
             break;
         }
         $scanner->next();
     }
     if ($idx != count($arrayType->dimensions)) {
         SemanticException::raw($scanner, "Array should be dereferenced completely");
     }
     $this->symType = $arrayType->type;
     if ($continue) {
         parent::simpleException($scanner, ['<INDEX-EXPRESSION>']);
     }
     $scanner->next();
 }
예제 #7
0
 public static function parse($scanner, $_symTable, $identifier = null)
 {
     if (!$identifier) {
         if (!$scanner->get()->isIdentifier()) {
             parent::simpleException($scanner, ['<IDENTIFIER>']);
         }
         $identifier = $scanner->get();
         $scanner->next();
     }
     //entire-variable
     $cur = new EntireVariable($scanner, $_symTable, $identifier);
     //variable-access
     $curVA = new VariableAccess($cur);
     while (self::isKeyOperator($scanner->get())) {
         $operVal = $scanner->get()->getValue();
         $scanner->next();
         switch ($operVal) {
             case '.':
                 $curVA->variable = new ComponentVariable($scanner, $_symTable, clone $curVA);
                 break;
             case '[':
                 $curVA->variable = new IndexedVariable($scanner, $_symTable, clone $curVA);
                 break;
             case '^':
                 $curVA->variable = new IdentifiedVariable($scanner, $_symTable, clone $curVA);
                 break;
         }
     }
     $curVA->symType = $curVA->variable->symType;
     return $curVA;
 }
예제 #8
0
 public function __construct($scanner, $_symTable)
 {
     if ($scanner->get()->isUnSignedConst()) {
         $this->node = $scanner->get();
         $this->symType = SymType::recognizeSimpleType($this->node, $_symTable);
         $scanner->next();
         return;
     }
     if ($scanner->get()->isLBracket()) {
         $scanner->next();
         $this->node = new Expression($scanner, $_symTable);
         parent::requireOperator($scanner, ')');
         $this->symType = $this->node->symType;
         $scanner->next();
         return;
     }
     if ($scanner->get()->isKeyword('not')) {
         $this->keyword = $scanner->get();
         $scanner->next();
         $this->node = new Factor($scanner, $_symTable);
         $this->node = TypeCast::tryTypeCast($this->node, 'boolean');
         $this->symType = $this->node->symType;
         return;
     }
     if ($scanner->get()->isIdentifier()) {
         $identifier = $scanner->get();
         $symbol = $_symTable->findRecursive($identifier->getValue());
         if (is_a($symbol, 'vendor\\SemanticParser\\Nodes\\SymType')) {
             $scanner->next();
             if (!$scanner->get()->isLBracket()) {
                 parent::simpleException($scanner, ['<OPERATOR \'(\'>']);
             }
             $scanner->next();
             $expression = new Expression($scanner, $_symTable);
             if (!$scanner->get()->isRBracket()) {
                 parent::simpleException($scanner, ["<OPERATOR ')'>"]);
             }
             $scanner->next();
             $class = get_class($expression->symType);
             if (!$class::equal($expression->symType, $symbol)) {
                 $expression = new TypeCast($expression, $symbol);
             }
             $this->node = $expression;
             $this->symType = $this->node->symType;
             return;
         }
         $scanner->next();
         if ($scanner->get()->isLBracket()) {
             $actualParamList = new ActualParamList($scanner, $_symTable);
             $this->node = new FunctionDesignator($identifier, $actualParamList, $_symTable);
         } else {
             $this->node = VariableAccess::parse($scanner, $_symTable, $identifier);
         }
         $this->symType = $this->node->symType;
         return;
     }
 }
예제 #9
0
 public function __construct($scanner, $_symTable)
 {
     while ($scanner->get()->isKeyword('procedure') || $scanner->get()->isKeyword('function')) {
         array_push($this->fps, $scanner->get()->isKeyword('procedure') ? Proc::smartParse($scanner, $_symTable) : Func::smartParse($scanner, $_symTable));
         parent::semicolonPass($scanner);
     }
     if (empty($this->fps)) {
         parent::simpleException($scanner, ['<IDENTIFIER>']);
     }
 }
예제 #10
0
 public function __construct($scanner)
 {
     if (!$scanner->get()->isKeyword('program')) {
         parent::simpleException($scanner, ["<KEYWORD 'program'"]);
     }
     $this->name = $scanner->nget();
     if (!$this->name->isIdentifier()) {
         parent::simpleException($scanner, ['<IDENTIFIER>']);
     }
     $scanner->next();
 }
예제 #11
0
 public function __construct($scanner, $_symTable)
 {
     $this->statements = [];
     parent::requireKeyword($scanner, 'begin');
     $scanner->next();
     while (!$scanner->get()->isKeyword('end')) {
         $this->statements[] = new Statement($scanner, $_symTable);
         parent::semicolonPass($scanner);
     }
     $scanner->next();
 }
예제 #12
0
 public function __construct($scanner, $_symTable)
 {
     $decs = [];
     while ($scanner->get()->isIdentifier()) {
         array_push($this->varDecs, new VarDec($scanner, $_symTable));
         parent::semicolonPass($scanner);
     }
     if (empty($this->varDecs)) {
         parent::simpleException($scanner, ['<IDENTIFIER>']);
     }
 }
예제 #13
0
 public function __construct($scanner, $_symTable)
 {
     if (!$scanner->get()->isIdentifier()) {
         parent::simpleException($scanner, ['<IDENTIFIER>']);
     }
     $identifier = $scanner->get();
     $scanner->next();
     parent::requireOperator($scanner, '=');
     $scanner->next();
     $this->symbol = SymType::parse($scanner, $_symTable, $identifier->getValue());
     $_symTable->append($this->symbol);
 }
예제 #14
0
 public function __construct($scanner, $_symTable)
 {
     $finalKeyWords = ['var', 'function', 'procedure', 'begin'];
     $defs = [];
     while ($scanner->get()->isIdentifier()) {
         array_push($defs, new TypeDef($scanner, $_symTable));
         parent::semicolonPass($scanner);
     }
     if (empty($defs)) {
         parent::simpleException($scanner, ['<IDENTIFIER>']);
     }
 }
예제 #15
0
 public function __construct($scanner, $_symTable)
 {
     parent::requireKeyword($scanner, 'while');
     $scanner->next();
     $this->condition = new Expression($scanner, $_symTable);
     $this->condition = TypeCast::tryTypeCast($this->condition, 'boolean');
     parent::requireKeyword($scanner, 'do');
     $scanner->next();
     Globals::$loopDepth++;
     $this->statements = CompoundStatement::smartParse($scanner, $_symTable);
     Globals::$loopDepth--;
 }
예제 #16
0
 public function __construct($scanner)
 {
     $scanner->next();
     $this->symTable = new SymTable(null);
     Globals::init($this->symTable);
     $this->heading = new ProgramHeading($scanner);
     parent::semicolonPass($scanner);
     $this->block = new Block($scanner, $this->symTable);
     parent::requireOperator($scanner, '.');
     $scanner->next();
     if (!$scanner->get()->isEOF()) {
         parent::simpleException($scanner, ['<EOF>']);
     }
 }
예제 #17
0
 public function __construct($scanner, $_symTable, $identifier)
 {
     $this->identifier = $identifier;
     $type = $scanner->nget();
     if (!$type->isIdentifier()) {
         Node::simpleException($scanner, ['<TYPE IDENTIFIER>']);
     }
     $type = $_symTable->findRecursive($type->getValue());
     if ($type == null || !is_a($type, 'vendor\\SemanticParser\\Nodes\\SymType')) {
         SemanticException::expected($scanner, ['<TYPE IDENTIFIER>']);
     }
     $this->type = $type;
     $scanner->next();
 }
예제 #18
0
 public function __construct($scanner, $_symTable, $identifier)
 {
     $this->identifier = $identifier;
     $this->from = self::getRangeValue($scanner, $_symTable);
     $dots = $scanner->nget();
     if (!$dots->isOperator('..')) {
         Node::simpleException($scanner, ['<OPERATOR \'..\'>']);
     }
     $scanner->next();
     $this->to = self::getRangeValue($scanner, $_symTable);
     if ($this->from > $this->to) {
         SemanticException::raw($scanner, 'Found Subrange type, but FROM > TO');
     }
     $scanner->next();
 }
예제 #19
0
 public function __construct($scanner, $_symTable)
 {
     $identifier = $scanner->get();
     if (!$identifier->isIdentifier()) {
         parent::simpleException($scanner, ['<IDENTIFIER>']);
     }
     $scanner->next();
     parent::requireOperator($scanner, '=');
     $constant = $scanner->nget();
     if (!$constant->isConst()) {
         parent::simpleException($scanner, ['<CONSTANT']);
     }
     $this->symbol = new SymConst($identifier->getValue(), $constant->getValue(), $constant->type, $_symTable);
     $_symTable->append($this->symbol);
     $scanner->next();
 }
예제 #20
0
파일: Proc.php 프로젝트: kaduev13/Compiler
 public static function smartParse($scanner, $_symTable)
 {
     $scanner->next();
     list($identifier, $symTable) = self::parseSignature($scanner, $_symTable);
     parent::semicolonPass($scanner);
     $symbol = new SymProc($identifier, $symTable, null);
     $proc = new Proc(null, $symbol);
     $proc->symbol->node = $proc;
     if ($scanner->get()->isKeyword('forward')) {
         $_symTable->appendForwardable($proc->symbol);
         $scanner->next();
         return $proc;
     }
     $proc->block = new Block($scanner, $symTable);
     $_symTable->appendForwardable($proc->symbol);
     return $proc;
 }
예제 #21
0
 public function __construct($scanner, $_symTable, $expression)
 {
     if ($expression != null) {
         $this->leftPart = $expression;
     } else {
         $this->leftPart = new Expression($scanner, $_symTable);
     }
     if (!$scanner->get()->isOperator(':=')) {
         parent::simpleException($scanner, ["<OPERATOR ':='>"]);
     }
     $scanner->next();
     $this->rightPart = new Expression($scanner, $_symTable);
     $class = get_class($this->rightPart->symType);
     if (!$class::equal($this->rightPart->symType, $this->leftPart->symType)) {
         $this->rightPart = new TypeCast($this->rightPart, $this->leftPart->symType);
     }
 }
예제 #22
0
 public function __construct($scanner, $_symTable)
 {
     $this->params = [];
     parent::requireOperator($scanner, '(');
     $scanner->next();
     if ($scanner->get()->isRBracket()) {
         $scanner->next();
         $this->params = [];
         return;
     }
     $this->params[] = new SimpleExpression($scanner, $_symTable);
     while (!$scanner->get()->isRBracket()) {
         parent::requireOperator($scanner, ',');
         $scanner->next();
         $this->params[] = new SimpleExpression($scanner, $_symTable);
     }
     $scanner->next();
 }
예제 #23
0
 private static function guessType($scanner)
 {
     if ($scanner->get()->isIdentifier()) {
         return self::$IDENTIFIER;
     } else {
         if ($scanner->get()->isKeyword('record')) {
             return self::$NEW_STRUCT;
         } else {
             if ($scanner->get()->isConst()) {
                 return self::$NEW_SUBRANGE;
             } else {
                 if ($scanner->get()->isOperator('^')) {
                     return self::$NEW_POINTER;
                 } else {
                     parent::simpleException($scanner, self::firstTokens());
                 }
             }
         }
     }
 }
예제 #24
0
 public function __construct($scanner, $_symTable, $record)
 {
     $recType = $record->variable->symType;
     if (is_a($recType, 'vendor\\SemanticParser\\Nodes\\SymAliasType')) {
         $recType = $recType->getBase();
     }
     if (!is_a($recType, 'vendor\\SemanticParser\\Nodes\\SymRecordType')) {
         SemanticException::varAccessTypeMismatch($scanner, $recType, 'record');
     }
     if (!$scanner->get()->isIdentifier()) {
         parent::simpleException($scanner, ['<FIELD-DESIGNATOR>']);
     }
     $identifier = $scanner->get()->getValue();
     $designatorType = $recType->getFieldType($identifier);
     if ($designatorType == null) {
         SemanticException::undeclared($scanner, $identifier->getValue());
     }
     $this->symType = $designatorType;
     $this->record = $record;
     $this->designator = $scanner->get();
     $scanner->next();
 }