Advertisement
Guest User

Untitled

a guest
Mar 13th, 2018
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 8.19 KB | None | 0 0
  1. <?php
  2. /*********************************************
  3. IPP - 1.projekt
  4. Iva Kavankova
  5.  *********************************************/
  6.  
  7. // TODO: ignor entru mezi radky a instrukce malymi pismeny
  8.  
  9. error_reporting(-1); // vypis vsech chyb
  10.  
  11. function error($msg) {
  12.     fprintf(STDERR, "CHYBA: $msg!\n");
  13. }
  14.  
  15. class InstructionRegister {
  16.     public static $options = array(
  17.         "MOVE" => "var_symb",
  18.         "CREATEFRAME" => "",
  19.         "PUSHFRAME" => "",
  20.         "POPHFRAME" => "",
  21.         "DEFVAR" => "var",
  22.         "CALL" => "label",
  23.         "RETURN" => "",
  24.         "PUSHS" => "symb",
  25.         "POPS" => "var",
  26.         "ADD" => "var_symb_symb",
  27.         "SUB" => "var_symb_symb",
  28.         "MUL" => "var_symb_symb",
  29.         "IDIV" => "var_symb_symb",
  30.         "LT" => "var_symb_symb",
  31.         "GT" => "var_symb_symb",
  32.         "EQ" => "var_symb_symb",
  33.         "AND" => "var_symb1_symb2",
  34.         "OR" => "var_symb_symb",
  35.         "NOT" => "var_symb_symb",
  36.         "INT2CHAR" => "var_symb",
  37.         "STRI2INT" => "var_symb_symb",
  38.         "READ" => "var_type",
  39.         "WRITE" => "symb",
  40.         "CONCAT" => "var_symb_symb",
  41.         "STRLEN" => "var_symb",
  42.         "GETCHAR" => "var_symb_symb",
  43.         "SETCHAR" => "var_symb_symb",
  44.         "TYPE" => "var_symb",
  45.         "LABEL" => "label",
  46.         "JUMP" => "label",
  47.         "JUMPIFEQ" => "label_symb_symb",
  48.         "JUMPIFNEQ" => "label_symb_symb",
  49.         "DPRINT" => "symb",
  50.         "BREAK" => "",
  51.     );
  52. }
  53.  
  54. // napoveda
  55. function help() {
  56.     echo "Tento skript parse.php nacte ze standardniho vstupu zdrojovy kod v jazyce IPPcode18, zkontroluje lexikalni a syntaktickou spravnost kodu.\nNakonec vypise na stdout vystup ve forme XML reprezentace programu.";
  57. }
  58.  
  59. // nacteni argumentu
  60. if ($argc == 2) {
  61.     if ($argc > 1 && strcmp($argv[1], "--help") == 0) {
  62.         help();
  63.         exit(0);
  64.     }
  65.     else {
  66.         error("chybne zadani argumentu");
  67.         exit(10);
  68.     }
  69. }
  70. else if ($argc > 2) {
  71.     error("chybne zadani argumentu");
  72.     exit(10);
  73. }
  74.  
  75. // nacitani ze stdin
  76. $inputStream = STDIN;
  77. if ($inputStream === FALSE) {
  78.     error("nelze nacist soubor");
  79.     exit(1);
  80. }
  81.  
  82. // kontrola
  83. function checkSignature($opcode, $foundType, $index) {
  84.     $instructionOptions = array(
  85.         "MOVE" => "var_symb",
  86.         "CREATEFRAME" => "",
  87.         "PUSHFRAME" => "",
  88.         "POPFRAME" => "",
  89.         "DEFVAR" => "var",
  90.         "CALL" => "label",
  91.         "RETURN" => "",
  92.         "PUSHS" => "symb",
  93.         "POPS" => "var",
  94.         "ADD" => "var_symb_symb",
  95.         "SUB" => "var_symb_symb",
  96.         "MUL" => "var_symb_symb",
  97.         "IDIV" => "var_symb_symb",
  98.         "LT" => "var_symb_symb",
  99.         "GT" => "var_symb_symb",
  100.         "EQ" => "var_symb_symb",
  101.         "AND" => "var_symb1_symb2",
  102.         "OR" => "var_symb_symb",
  103.         "NOT" => "var_symb_symb",
  104.         "INT2CHAR" => "var_symb",
  105.         "STRI2INT" => "var_symb_symb",
  106.         "READ" => "var_type",
  107.         "WRITE" => "symb",
  108.         "CONCAT" => "var_symb_symb",
  109.         "STRLEN" => "var_symb",
  110.         "GETCHAR" => "var_symb_symb",
  111.         "SETCHAR" => "var_symb_symb",
  112.         "TYPE" => "var_symb",
  113.         "LABEL" => "label",
  114.         "JUMP" => "label",
  115.         "JUMPIFEQ" => "label_symb_symb",
  116.         "JUMPIFNEQ" => "label_symb_symb",
  117.         "DPRINT" => "symb",
  118.         "BREAK" => "",
  119.     );
  120.  
  121.     if(array_key_exists($opcode, $instructionOptions) == FALSE)
  122.     {
  123.         error("neznamy operacni kod instrukce: ($opcode)");
  124.         return FALSE;
  125.     }
  126.     $instructionSignature = explode('_', $instructionOptions[$opcode]);
  127.     if($index < count($instructionSignature)) {
  128.         //$instructionOptions[$opcode];
  129.         if ($instructionSignature[$index] == $foundType) {
  130.             return TRUE;
  131.         }
  132.         elseif ($instructionSignature[$index] == 'symb'){
  133.             if(in_array($foundType, ['var', 'int', 'string', 'bool'])) {
  134.                 return TRUE;
  135.             }
  136.             else {
  137.                 error("spatny typ opreandu");
  138.                 return FALSE;
  139.             }
  140.         }
  141.         else {
  142.             error("nenalezen operand");
  143.             return FALSE;
  144.         }
  145.     }
  146.     else {
  147.         error("prebytecny operand");
  148.         return FALSE;
  149.     }
  150.     error("vsechno spatne");
  151.     return FALSE;
  152. }
  153.  
  154. $text = stream_get_contents($inputStream); // retezec
  155.  
  156. function parseInput($input) {
  157.     $lines = preg_split('/[\n\r]/', $input);
  158.     $hasHeader = FALSE;
  159.     $parsedLines = [];
  160.     foreach ($lines as $lineNumber => $line) {
  161.         $hashIndex = strpos($line, '#');
  162.         if ($hashIndex !== FALSE) {
  163.             $line = substr($line, 0, $hashIndex);
  164.         }
  165.         $line = trim($line);
  166.         if ($line == '') continue;
  167.  
  168.         if (mb_strtoupper($line) == '.IPPCODE18' && !$hasHeader) {
  169.             $hasHeader = TRUE;
  170.             continue;
  171.         }
  172.         if (!$hasHeader) {
  173.             error("nema povinnou hlavicku");
  174.             return FALSE;
  175.         }
  176.         $parsedLines[] = $line;
  177.     }
  178.     return $parsedLines;
  179. }
  180.  
  181. // parsovani operandu
  182. function parseOperand($parentElement, $lineParts, $index) {
  183.     $part = $lineParts[$index];
  184.     $elementText = $elementType = '';
  185.  
  186.     if (strpos($part, '@') !== FALSE) {
  187.  
  188.         list($opType, $opContent) = explode('@', $part, 2);
  189.  
  190.         if ($opType == 'int') {
  191.             $elementText = $opContent;
  192.             $elementType = $opType;
  193.         } else if ($opType == 'bool') {
  194.             $elementText = $opContent;
  195.             $elementType = $opType;
  196.         } else if ($opType == 'string') {
  197.             $elementText = $opContent;
  198.             $elementType = $opType;
  199.         } else if (in_array($opType, ['GF', 'LF', 'TF'])) {
  200.             $elementText = $part;
  201.             $elementType = 'var';
  202.         } else {
  203.             throw new Exception("problem $opType, $part", 1);
  204.         }
  205.  
  206.  
  207.     } else {
  208.         if ($lineParts[0] == 'READ' && $index == 2) {
  209.             $elementText = $part;
  210.             $elementType = 'type';
  211.         } else {
  212.             $elementText = $part;
  213.             $elementType = 'label';
  214.         }
  215.     }
  216.  
  217.     if (checkSignature($lineParts[0], $elementType, $index - 1) == FALSE)
  218.     {
  219.         error("nastal mensi problem: $lineParts, $index, $elementType");
  220.         return NULL;
  221.     }
  222.  
  223.     $argElement = $parentElement->addChild('arg' . $index, $elementText);
  224.     $argElement->addAttribute('type', $elementType);
  225.     return $argElement;
  226. }
  227.  
  228. $lines = parseInput($text);
  229.  
  230. // zacatek generovani XML dokumentu
  231. $programElement = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><program />');
  232. $programElement->addAttribute('language', 'IPPcode18');
  233.  
  234. function generateInstructions($lines, $programElement) {
  235.  
  236.     foreach ($lines as $instructionOrder => $line) {
  237.         $parts = preg_split("/\s+/", $line);
  238.  
  239.         $instructionElement = $programElement->addChild('instruction');
  240.  
  241.         $opcode = $parts[0];
  242.  
  243.  
  244.         $instructionElement->addAttribute('opcode', $opcode);
  245.  
  246.         $opcode = mb_strtoupper($opcode);
  247.         if (!array_key_exists($opcode, InstructionRegister::$options)) {
  248.             error("nenalezena instrukce");
  249.             return FALSE;
  250.         }
  251.  
  252.         $operandsCount = count($parts) - 1;
  253.  
  254.         if ($operandsCount > 0) {
  255.             if(parseOperand($instructionElement, $parts, 1) == NULL) {
  256.                 error("nespravny operand 1: $line");
  257.                 return FALSE;
  258.             }
  259.         }
  260.         if ($operandsCount > 1) {
  261.             if(parseOperand($instructionElement, $parts, 2) == NULL) {
  262.                 error("nespravny operand 2: $line");
  263.                 return FALSE;
  264.             }
  265.         }
  266.         if ($operandsCount > 2) {
  267.             if(parseOperand($instructionElement, $parts, 3) == NULL) {
  268.                 error("nespravny operand 3: $line");
  269.                 return FALSE;
  270.             }
  271.         }
  272.         if ($operandsCount > 3) {
  273.             error("prilis mnoho operandu");
  274.             return FALSE;
  275.         }
  276.     }
  277.     return TRUE;
  278. }
  279.  
  280. // chybovy navratovy kod specificky pro analyzator
  281. if (!generateInstructions($lines,$programElement)) {
  282.     exit(21);
  283. }
  284.  
  285. // vygenerovani zbytku XML
  286. echo $programElement->asXML();
  287.  
  288. exit(0); // bez problemu
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement