xxeell

TFLAT-3-poliz-generation

Nov 14th, 2021 (edited)
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <!DOCTYPE html>
  2. <html>
  3.  
  4. <head>
  5.     <title>Poliz</title>
  6. </head>
  7.  
  8. <body>
  9.     <textarea id="input" cols="60" rows="10"></textarea>
  10.     <button id="parseButton">parse</button>
  11.     <br>
  12.     <details>
  13.         <summary>Лексемы</summary>
  14.         <div id="lexOutputContainer"></div>
  15.     </details>
  16.     <br>
  17.     <details>
  18.         <summary>Синтаксическое дерево</summary>
  19.         <div id="sintOutputContainer"></div>
  20.         <br>
  21.         <br>
  22.         <div id="sintOutputCanvas" width="100%" height="1000px"
  23.             style="vertical-align:top;text-anchor:middle;font-family:monospace;font-size:16px;"></div>
  24.     </details>
  25.     <br>
  26.     <details open>
  27.         <summary>Полиз</summary>
  28.         <div id="polizOutputContainer"></div>
  29.     </details>
  30.  
  31. </body>
  32. <!-- IO -->
  33. <script>
  34.     const IOContainers = {
  35.         input: document.getElementById('input'),
  36.         lexOutput: document.getElementById('lexOutputContainer'),
  37.         sintOutput: document.getElementById('sintOutputContainer'),
  38.         polizOutput: document.getElementById('polizOutputContainer'),
  39.     };
  40.     IOContainers.input.value =
  41.         `a = 1
  42. b = 2
  43. c = 3
  44. do while (((a < b) and (a <= c)) or (a > c))
  45.     b=b+c
  46.     b=b+a-20
  47. loop`;
  48. </script>
  49. <!-- Automate engine -->
  50. <script>
  51.     function distinct(array) {
  52.         return array.filter((value, index) => array.indexOf(value) == index);
  53.     }
  54.  
  55.     (function () {
  56.         let automateExample = {
  57.             states: {
  58.                 list: ['a', 'b', 'c'],
  59.                 start: 'a',
  60.                 end: ['c']
  61.             },
  62.             alphabet: [1, 2, 3],
  63.             translations: [
  64.                 { from: 'a', to: 'b', when: 1 },
  65.                 { from: 'b', to: 'c', when: 2 },
  66.                 { from: 'b', to: 'a', when: 2 },
  67.                 { from: 'a', to: 'c', when: 3 },
  68.             ],
  69.             epsilon: {
  70.                 useEpsilon: true,
  71.                 translations: [
  72.                     { from: 'b', to: 'a' },
  73.                     { from: 'b', to: 'b' },
  74.                 ],
  75.             },
  76.             config: {
  77.                 drowWhenNoTranslation: false,
  78.                 logEpsilonSeparately: true
  79.             }
  80.         };
  81.     })();
  82.  
  83.     function validateAutomateTemplate(automateTemplate) {
  84.         if (!automateTemplate) {
  85.             throw new Error(`Template error! Input is undefined.`);
  86.         }
  87.  
  88.         // --- --- States --- ---
  89.         if (!automateTemplate.states) {
  90.             throw new Error(`States error! States object is empty.`);
  91.         }
  92.         // --- list ---
  93.         if (!automateTemplate.states.list) {
  94.             throw new Error(`States error! States list is undefined.`);
  95.         }
  96.  
  97.         if (automateTemplate.states.list.length < 1) {
  98.             throw new Error(`States error! States list is empty.`);
  99.         }
  100.         // --- end list ---
  101.         // --- start ---
  102.         if (!automateTemplate.states.start) {
  103.             throw new Error(`Start state error! Start state is undefined.`);
  104.         }
  105.  
  106.         if (!automateTemplate.states.list.includes(automateTemplate.states.start)) {
  107.             throw new Error(`Start state error! States not include '${automateTemplate.states.start}'.`);
  108.         }
  109.         // --- end start ---
  110.         // --- end ---
  111.         if (!automateTemplate.states.end) {
  112.             throw new Error(`End states error! End states is undefined.`);
  113.         }
  114.  
  115.         if (automateTemplate.states.end.length < 1) {
  116.             throw new Error(`End states error! End states list is empty.`);
  117.         }
  118.  
  119.         for (const state of automateTemplate.states.end) {
  120.             if (!automateTemplate.states.list.includes(state)) {
  121.                 throw new Error(`End states error! States not include '${state}'.`);
  122.             }
  123.         }
  124.         // --- end end ---
  125.         // --- --- end States --- ---
  126.  
  127.         // --- --- Alphabet --- ---
  128.         if (!automateTemplate.alphabet) {
  129.             throw new Error(`Alphabet error! Alphabet is undefined.`);
  130.         }
  131.  
  132.         if (automateTemplate.alphabet.length < 1) {
  133.             throw new Error(`Alphabet error! Alphabet list is empty.`);
  134.         }
  135.         // --- --- end Alphabet --- ---
  136.  
  137.         // --- --- Translation --- ---
  138.         if (!automateTemplate.translations) {
  139.             throw new Error(`Translation error! Translations is undefined.`);
  140.         }
  141.  
  142.         if (automateTemplate.translations.length < 1) {
  143.             throw new Error(`Translation error! Translations list is empty.`);
  144.         }
  145.  
  146.         for (const translation of automateTemplate.translations) {
  147.             if (!automateTemplate.states.list.includes(translation.from)) {
  148.                 throw new Error(`Translation error! States not include 'from' value '${translation.from}' on transtalion ${JSON.stringify(translation)}.`);
  149.             }
  150.             if (!automateTemplate.states.list.includes(translation.to)) {
  151.                 throw new Error(`Translation error! States not include 'to' value '${translation.to}' on transtalion ${JSON.stringify(translation)}.`);
  152.             }
  153.             if (!automateTemplate.alphabet.includes(translation.when)) {
  154.                 throw new Error(`Translation error! Alphabet not include 'when' value '${translation.when}' on transtalion ${JSON.stringify(translation)}.`);
  155.             }
  156.         }
  157.         // --- --- end Translation --- ---
  158.  
  159.         // --- --- Epsilon --- ---
  160.         if (!automateTemplate.epsilon) {
  161.             throw new Error(`Epsilon error! Epsilon is undefined.`);
  162.         }
  163.  
  164.         if (automateTemplate.epsilon.useEpsilon) {
  165.             if (!automateTemplate.epsilon.translations) {
  166.                 throw new Error(`Epsilon error! Epsilon translations is undefined.`);
  167.             }
  168.  
  169.             if (automateTemplate.epsilon.translations.length < 1) {
  170.                 throw new Error(`Epsilon error! Epsilon translations list is empty.`);
  171.             }
  172.  
  173.             for (const translation of automateTemplate.epsilon.translations) {
  174.                 if (!automateTemplate.states.list.includes(translation.from)) {
  175.                     throw new Error(`Epsilon error! States not include 'from' value '${translation.from}' on epsilon transtalion ${JSON.stringify(translation)}.`);
  176.                 }
  177.                 if (!automateTemplate.states.list.includes(translation.to)) {
  178.                     throw new Error(`Epsilon error! States not include 'to' value '${translation.to}' on epsilon transtalion ${JSON.stringify(translation)}.`);
  179.                 }
  180.             }
  181.         }
  182.         // --- --- end Epsilon --- ---
  183.  
  184.         // --- --- Config --- ---
  185.         if (!automateTemplate.config) {
  186.             throw new Error(`Config error! Config is undefined.`);
  187.         }
  188.         // --- --- end Config --- ---
  189.     }
  190.  
  191.     function Automate(automateTemplate) {
  192.         validateAutomateTemplate(automateTemplate);
  193.  
  194.         this.automate = {
  195.             states: {
  196.                 list: Array.from(automateTemplate.states.list),
  197.                 start: automateTemplate.states.start,
  198.                 end: Array.from(automateTemplate.states.end)
  199.             },
  200.             alphabet: Array.from(automateTemplate.alphabet),
  201.             translations: {},
  202.             epsilon: {
  203.                 useEpsilon: false,
  204.                 translations: {}
  205.             },
  206.             config: {
  207.                 drowWhenNoTranslation: automateTemplate.config.drowWhenNoTranslation,
  208.                 logEpsilonSeparately: automateTemplate.config.logEpsilonSeparately
  209.             }
  210.         };
  211.  
  212.         for (const state of this.automate.states.list) {
  213.             this.automate.translations[state] = {};
  214.             for (const letter of this.automate.alphabet) {
  215.                 this.automate.translations[state][letter] = [];
  216.             }
  217.         }
  218.         for (const translation of automateTemplate.translations) {
  219.             if (this.automate.translations[translation.from][translation.when].includes(translation.to)) {
  220.                 throw new Error(`Translation error! Transtalion ${JSON.stringify(translation)} already exists.`);
  221.             }
  222.             this.automate.translations[translation.from][translation.when].push(translation.to);
  223.         }
  224.  
  225.         if (automateTemplate.epsilon.useEpsilon) {
  226.             this.automate.epsilon.useEpsilon = true;
  227.             for (const state of this.automate.states.list) {
  228.                 this.automate.epsilon.translations[state] = [];
  229.             }
  230.             for (const translation of automateTemplate.epsilon.translations) {
  231.                 if (this.automate.epsilon.translations[translation.from].includes(translation.to)) {
  232.                     throw new Error(`Epsilon translation error! Epsilon transtalion ${JSON.stringify(translation)} already exists.`);
  233.                 }
  234.                 this.automate.epsilon.translations[translation.from].push(translation.to);
  235.             }
  236.         }
  237.  
  238.         this.execution = {
  239.             current: [this.automate.states.start],
  240.             log: [],
  241.             errors: []
  242.         };
  243.     }
  244.  
  245.     Automate.prototype = {
  246.         clearExecution() {
  247.             this.execution = {
  248.                 current: [this.automate.states.start],
  249.                 log: [],
  250.                 errors: []
  251.             };
  252.             this.logStep(null);
  253.         },
  254.         logStep(letter) {
  255.             this.execution.log.push({
  256.                 getLetter: letter,
  257.                 resultStates: Array.from(this.execution.current)
  258.             });
  259.         },
  260.         processEpsilon() {
  261.             if (!this.automate.epsilon.useEpsilon) {
  262.                 return;
  263.             }
  264.  
  265.             let next = [...this.execution.current];
  266.             let currentChars = this.execution.current;
  267.             let nextChars = [];
  268.  
  269.             while (currentChars.length > 0) {
  270.                 for (let curChar of currentChars) {
  271.                     nextChars.push(...this.automate.epsilon.translations[curChar]);
  272.                 }
  273.                 next.push(...nextChars);
  274.                 currentChars = distinct(nextChars).filter(value => !next.includes(value));
  275.                 nextChars = [];
  276.             }
  277.  
  278.             this.execution.current = distinct(next);
  279.             if (this.automate.config.logEpsilonSeparately) {
  280.                 this.logStep('epsilon');
  281.             }
  282.         },
  283.         processLetter(letter) {
  284.             if (!this.automate.alphabet.includes(letter)) {
  285.                 alert(`Input error! Alphabet not include ${letter}`);
  286.                 return;
  287.             }
  288.  
  289.             let next = [];
  290.  
  291.             for (let currentState of this.execution.current) {
  292.                 let nextStates = this.automate.translations[currentState][letter];
  293.                 if (nextStates.length < 1) {
  294.                     let error = `No translation for ${JSON.stringify({ from: currentState, when: letter })}`;
  295.                     this.execution.errors.push(error);
  296.                     if (this.automate.config.drowWhenNoTranslation) {
  297.                         throw error;
  298.                     } else {
  299.                         nextStates = [currentState];
  300.                     }
  301.                 }
  302.                 next.push(...nextStates);
  303.             }
  304.  
  305.             this.execution.current = distinct(next);
  306.  
  307.             if (this.automate.config.logEpsilonSeparately) {
  308.                 this.logStep(letter);
  309.                 this.processEpsilon();
  310.             } else {
  311.                 this.processEpsilon();
  312.                 this.logStep(letter);
  313.             }
  314.         },
  315.         isComplete() {
  316.             return this.execution.current.some(value => this.automate.states.end.includes(value));
  317.         }
  318.     };
  319. </script>
  320. <!-- Lex classes -->
  321. <script>
  322.     const LexClasses = {
  323.         keywords: {
  324.             loop: {
  325.                 while: {
  326.                     start: { value: 'lex.keyword.loop.while.start', priority: 1 },
  327.                     end: { value: 'lex.keyword.loop.while.end', priority: 1 },
  328.                 }
  329.             },
  330.             codeSegment: {
  331.                 start: { value: 'lex.keyword.codeSegment.start', priority: 2 },
  332.                 end: { value: 'lex.keyword.codeSegment.end', priority: 2 },
  333.             },
  334.         },
  335.         separators: {
  336.             bracket: {
  337.                 start: { value: 'lex.separators.bracket.start', priority: 3 },
  338.                 end: { value: 'lex.separators.bracket.end', priority: 3 },
  339.             }
  340.         },
  341.         operations: {
  342.             as: { value: 'lex.operations.as', priority: 3 },
  343.             logical: { value: 'lex.operations.logical', priority: 4 },
  344.             compare: { value: 'lex.operations.compare', priority: 4 },
  345.             math: { value: 'lex.operations.math', priority: 4 },
  346.         },
  347.         values: {
  348.             variable: { value: 'lex.values.variable', priority: 5 },
  349.             numConst: { value: 'lex.values.numConst', priority: 5 },
  350.         },
  351.     };
  352. </script>
  353. <!-- Automate builder -->
  354. <script>
  355.     const AutomateBuilder = {
  356.         alphabet: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ<>=+-*/ ()'.split(''),
  357.         createAutomateTemplate(keyword) {
  358.             let template = {
  359.                 states: {
  360.                     list: ['start'],
  361.                     start: 'start',
  362.                     end: [keyword]
  363.                 },
  364.                 alphabet: AutomateBuilder.alphabet,
  365.                 translations: [],
  366.                 epsilon: {
  367.                     useEpsilon: false,
  368.                     translations: [],
  369.                 },
  370.                 config: {
  371.                     drowWhenNoTranslation: true,
  372.                     logEpsilonSeparately: false
  373.                 }
  374.             };
  375.  
  376.             let wordPart = '';
  377.             for (const letter of keyword) {
  378.                 wordPart += letter;
  379.                 const prewState = template.states.list[template.states.list.length - 1];
  380.                 const curState = wordPart;
  381.                 template.states.list.push(curState);
  382.                 template.translations.push({ from: prewState, to: curState, when: letter });
  383.             }
  384.  
  385.             return template;
  386.         },
  387.         createAutomate(keyword) {
  388.             let template = AutomateBuilder.createAutomateTemplate(keyword);
  389.             let automate = new Automate(template);
  390.             return automate;
  391.         },
  392.         createNumConstAtomate() {
  393.             let template = {
  394.                 states: {
  395.                     list: ['start', 'num'],
  396.                     start: 'start',
  397.                     end: ['num']
  398.                 },
  399.                 alphabet: AutomateBuilder.alphabet,
  400.                 translations: [],
  401.                 epsilon: {
  402.                     useEpsilon: false,
  403.                     translations: [],
  404.                 },
  405.                 config: {
  406.                     drowWhenNoTranslation: true,
  407.                     logEpsilonSeparately: false
  408.                 }
  409.             };
  410.  
  411.             for (let letter of '123456789') {
  412.                 template.translations.push({ from: 'start', to: 'num', when: letter });
  413.                 template.translations.push({ from: 'num', to: 'num', when: letter });
  414.             }
  415.             template.translations.push({ from: 'num', to: 'num', when: '0' });
  416.  
  417.             let automate = new Automate(template);
  418.             return automate;
  419.         },
  420.         createVariableAtomate() {
  421.             let template = {
  422.                 states: {
  423.                     list: ['start', 'var'],
  424.                     start: 'start',
  425.                     end: ['var']
  426.                 },
  427.                 alphabet: AutomateBuilder.alphabet,
  428.                 translations: [],
  429.                 epsilon: {
  430.                     useEpsilon: false,
  431.                     translations: [],
  432.                 },
  433.                 config: {
  434.                     drowWhenNoTranslation: true,
  435.                     logEpsilonSeparately: false
  436.                 }
  437.             };
  438.  
  439.             for (let letter of 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') {
  440.                 template.translations.push({ from: 'start', to: 'var', when: letter });
  441.                 template.translations.push({ from: 'var', to: 'var', when: letter });
  442.             }
  443.  
  444.             for (let letter of '0123456789') {
  445.                 template.translations.push({ from: 'var', to: 'var', when: letter });
  446.             }
  447.  
  448.             let automate = new Automate(template);
  449.             return automate;
  450.         }
  451.     }
  452. </script>
  453. <!-- Automates -->
  454. <script>
  455.     const FullAutomatesList = {
  456.         // keywords,
  457.         while: {
  458.             automate: AutomateBuilder.createAutomate('while'),
  459.             class: LexClasses.keywords.loop.while.start
  460.         },
  461.         loop: {
  462.             automate: AutomateBuilder.createAutomate('loop'),
  463.             class: LexClasses.keywords.loop.while.end
  464.         },
  465.         do: {
  466.             automate: AutomateBuilder.createAutomate('do'),
  467.             class: LexClasses.keywords.codeSegment.start
  468.         },
  469.         end: {
  470.             automate: AutomateBuilder.createAutomate('end'),
  471.             class: LexClasses.keywords.codeSegment.end
  472.         },
  473.         // end keywords
  474.         // separators
  475.         '(': {
  476.             automate: AutomateBuilder.createAutomate('('),
  477.             class: LexClasses.separators.bracket.start
  478.         },
  479.         ')': {
  480.             automate: AutomateBuilder.createAutomate(')'),
  481.             class: LexClasses.separators.bracket.end
  482.         },
  483.         // end separators
  484.         // operations
  485.         and: {
  486.             automate: AutomateBuilder.createAutomate('and'),
  487.             class: LexClasses.operations.logical
  488.         },
  489.         or: {
  490.             automate: AutomateBuilder.createAutomate('or'),
  491.             class: LexClasses.operations.logical
  492.         },
  493.         '<': {
  494.             automate: AutomateBuilder.createAutomate('<'),
  495.             class: LexClasses.operations.compare
  496.         },
  497.         '>': {
  498.             automate: AutomateBuilder.createAutomate('>'),
  499.             class: LexClasses.operations.compare
  500.         },
  501.         '<=': {
  502.             automate: AutomateBuilder.createAutomate('<='),
  503.             class: LexClasses.operations.compare
  504.         },
  505.         '==': {
  506.             automate: AutomateBuilder.createAutomate('=='),
  507.             class: LexClasses.operations.compare
  508.         },
  509.         '<>': {
  510.             automate: AutomateBuilder.createAutomate('<>'),
  511.             class: LexClasses.operations.compare
  512.         },
  513.         '+': {
  514.             automate: AutomateBuilder.createAutomate('+'),
  515.             class: LexClasses.operations.math
  516.         },
  517.         '-': {
  518.             automate: AutomateBuilder.createAutomate('-'),
  519.             class: LexClasses.operations.math
  520.         },
  521.         '*': {
  522.             automate: AutomateBuilder.createAutomate('*'),
  523.             class: LexClasses.operations.math
  524.         },
  525.         '/': {
  526.             automate: AutomateBuilder.createAutomate('/'),
  527.             class: LexClasses.operations.math
  528.         },
  529.         '=': {
  530.             automate: AutomateBuilder.createAutomate('='),
  531.             class: LexClasses.operations.as
  532.         },
  533.         // end operations
  534.         // values
  535.         variable: {
  536.             automate: AutomateBuilder.createVariableAtomate(),
  537.             class: LexClasses.values.variable
  538.         },
  539.         numConst: {
  540.             automate: AutomateBuilder.createNumConstAtomate(),
  541.             class: LexClasses.values.numConst
  542.         },
  543.         // end values
  544.     }
  545. </script>
  546. <!-- Render -->
  547. <script>
  548.     const HTMLTags = {
  549.         Table: 'table',
  550.         TableRow: 'tr',
  551.         TableData: 'td'
  552.     }
  553.  
  554.     const ItemTypes = {
  555.         Value: 'VALUE',
  556.         Container: 'CONTAINER'
  557.     }
  558.  
  559.     function render(item) {
  560.         if (item.element) {
  561.             return item.element;
  562.         }
  563.  
  564.         let element = document.createElement(item.tag);
  565.         item.element = element;
  566.  
  567.         if (item.attributes) {
  568.             for (let name in item.attributes) {
  569.                 let value = item.attributes[name];
  570.                 element.setAttribute(name, value);
  571.             }
  572.         }
  573.  
  574.         switch (item.type) {
  575.             case ItemTypes.Value:
  576.                 if (item.value) {
  577.                     element.innerHTML = item.value;
  578.                 }
  579.                 break;
  580.             case ItemTypes.Container:
  581.                 if (item.childs) {
  582.                     for (let i in item.childs) {
  583.                         let child = item.childs[i];
  584.                         if (!child.element) {
  585.                             render(child);
  586.                         }
  587.                         element.append(child.element);
  588.                     }
  589.                 }
  590.                 break;
  591.         }
  592.  
  593.         return element;
  594.     }
  595. </script>
  596. <!-- Lex analizer -->
  597. <script>
  598.     function LexAnalizer(automatesList) {
  599.         this.automates = automatesList;
  600.         this.output = [];
  601.         this.execution = {
  602.             prevAutomates: [],
  603.             prevCompleteAutomates: [],
  604.             curAutomates: [],
  605.             accumulator: '',
  606.         };
  607.     }
  608.  
  609.     LexAnalizer.prototype = {
  610.         getAllAutomates() {
  611.             let list = Object.values(this.automates);
  612.             list.sort((a, b) => a.class.priority - b.class.priority);
  613.             list.forEach(element => element.automate.clearExecution());
  614.             return list;
  615.         },
  616.         getCompleteAutomates(automates) {
  617.             return automates.filter(value => value.automate.isComplete());
  618.         },
  619.         resetExecution() {
  620.             this.execution = {
  621.                 prevAutomates: this.getAllAutomates(),
  622.                 prevCompleteAutomates: null,
  623.                 curAutomates: [],
  624.                 accumulator: '',
  625.             };
  626.             this.execution.prevCompleteAutomates = this.getCompleteAutomates(this.execution.prevAutomates);
  627.         },
  628.         tryAddToOutput(index) {
  629.             if (this.execution.curAutomates.length < 1) {
  630.                 if (this.execution.prevAutomates.length > 0) {
  631.                     const lastAutomate = this.execution.prevCompleteAutomates[0];
  632.                     if (lastAutomate) {
  633.                         this.output.push({
  634.                             word: this.execution.accumulator,
  635.                             position: {
  636.                                 start: index - this.execution.accumulator.length,
  637.                                 end: index - 1
  638.                             },
  639.                             class: lastAutomate.class.value
  640.                         });
  641.                         return 3;
  642.                     }
  643.                     return 2;
  644.                 }
  645.                 return 1;
  646.             }
  647.             return 0;
  648.         },
  649.         prepareNextStep(letter) {
  650.             this.execution.prevAutomates = this.execution.curAutomates;
  651.             this.execution.prevCompleteAutomates = this.getCompleteAutomates(this.execution.prevAutomates);
  652.             this.execution.curAutomates = [];
  653.             this.execution.accumulator += letter;
  654.         },
  655.         analize(input) {
  656.             const space = ' ';
  657.             this.output = [];
  658.             this.resetExecution();
  659.             input = input.replaceAll(/\s+/g, space);
  660.  
  661.             for (let i = 0; i < input.length; i++) {
  662.                 const letter = input[i];
  663.  
  664.                 for (const automate of this.execution.prevAutomates) {
  665.                     try {
  666.                         automate.automate.processLetter(letter);
  667.                         this.execution.curAutomates.push(automate);
  668.                     } catch {
  669.                         automate.automate.clearExecution();
  670.                     }
  671.                 }
  672.  
  673.                 let stepFinished = this.tryAddToOutput(i);
  674.                 if (stepFinished) {
  675.                     this.resetExecution();
  676.                     if (letter != space) {
  677.                         i--;
  678.                     }
  679.                 } else {
  680.                     this.prepareNextStep(letter);
  681.                 }
  682.             }
  683.  
  684.             this.tryAddToOutput(input.length);
  685.         }
  686.     };
  687. </script>
  688. <!-- Sint classes -->
  689. <script>
  690.     const SintClasses = {
  691.         Value: 'sint.value',
  692.         // lex.values.variable
  693.         //  | lex.values.numConst
  694.         //  | lex.separators.bracket.start sint.math lex.separators.bracket.end
  695.         MathOperation: 'sint.math',
  696.         // sint.value lex.operations.math sint.math
  697.         //  | sint.value
  698.         LogicOperation: 'sint.logic.operation',
  699.         // lex.separators.bracket.start sint.math lex.operations.compare sint.math lex.separators.bracket.end
  700.         LogicExpression: 'sint.logic.expression',
  701.         // lex.separators.bracket.start sint.logic.expression lex.operations.logical sint.logic.expression lex.separators.bracket.end
  702.         //  | sint.logic.operation
  703.         Assignment: 'sint.assignment',
  704.         // lex.values.variable lex.operations.as sint.math
  705.         WhileLoop: 'sint.loop.while',
  706.         // lex.keyword.codeSegment.start lex.keyword.loop.while.start sint.logic.expression [sint.operation] lex.keyword.loop.while.end
  707.         Operation: 'sint.operation',
  708.         // sint.assignment
  709.         //  | sint.loop.while
  710.         Code: 'sint.code',
  711.         // [sint.operation]
  712.     };
  713. </script>
  714. <!-- Poliz -->
  715. <script>
  716.     const PolizRecordType = {
  717.         Command: 'prCommand',
  718.         Variable: 'prVariable',
  719.         Const: 'prConst',
  720.         Pointer: 'prPointer',
  721.     };
  722.  
  723.     const PolizCommand = {
  724.         JMP: { value: 'JMP', index: 0 },
  725.         JZ: { value: 'JZ', index: 1 },
  726.         SET: { value: 'SET', index: 2 },
  727.         ADD: { value: 'ADD', index: 3 },
  728.         SUB: { value: 'SUB', index: 4 },
  729.         MUL: { value: 'MUL', index: 5 },
  730.         DIV: { value: 'DIV', index: 6 },
  731.         AND: { value: 'AND', index: 7 },
  732.         OR: { value: 'OR', index: 8 },
  733.         CMPE: { value: 'CMPE', index: 9 },
  734.         CMPNE: { value: 'CMPNE', index: 10 },
  735.         CMPL: { value: 'CMPL', index: 11 },
  736.         CMPLE: { value: 'CMPLE', index: 12 },
  737.         CMPG: { value: 'CMPG', index: 13 },
  738.         CMPGE: { value: 'CMPGE', index: 14 },
  739.     };
  740.  
  741.     const PolizCommandsList = (function () {
  742.         let commands = Object.values(PolizCommand);
  743.         commands.sort((a, b) => a.index - b.index);
  744.         return commands.map(value => value.value);
  745.     })();
  746.  
  747.     function Poliz() {
  748.         this.code = [];
  749.         this.valiables = [];
  750.         this.valiableNames = {};
  751.     }
  752.  
  753.     Poliz.prototype = {
  754.         getCodeLength() {
  755.             return this.code.length;
  756.         },
  757.         popCodeForLength(length) {
  758.             while (this.code.length > length) {
  759.                 this.code.pop();
  760.             }
  761.         },
  762.         addRecord(type, value) {
  763.             let index = this.code.length;
  764.             let record = { type: type, value: value };
  765.             this.code.push(record);
  766.             return index;
  767.         },
  768.         addCommand(command) {
  769.             return this.addRecord(PolizRecordType.Command, command.index);
  770.         },
  771.         addVariable(name) {
  772.             if (!this.valiableNames[name]) {
  773.                 this.valiableNames[name] = this.valiables.length;
  774.                 this.valiables.push(name);
  775.             }
  776.             return this.addRecord(PolizRecordType.Variable, this.valiableNames[name]);
  777.         },
  778.         addConst(value) {
  779.             return this.addRecord(PolizRecordType.Const, value);
  780.         },
  781.         addPointer(index) {
  782.             return this.addRecord(PolizRecordType.Pointer, index);
  783.         },
  784.         updateValue(index, newValue) {
  785.             if (index < this.code.length) {
  786.                 this.code[index].value = newValue;
  787.             }
  788.         }
  789.     };
  790. </script>
  791. <!-- SintAnalizer -->
  792. <script>
  793.     function SintAnalizer() {
  794.         this.lexList = [];
  795.         this.currentLexIndex = 0;
  796.         this.currentLex = {};
  797.         this.output = {};
  798.         this.poliz = new Poliz();
  799.     }
  800.  
  801.     SintAnalizer.prototype = {
  802.         SetLexIndex(i) {
  803.             this.currentLexIndex = i;
  804.             this.currentLex = this.lexList[this.currentLexIndex];
  805.             //console.log(`${this.currentLexIndex}) ${JSON.stringify(this.currentLex)}`);
  806.         },
  807.         FirstLex() {
  808.             this.SetLexIndex(0);
  809.         },
  810.         NextLex() {
  811.             this.SetLexIndex(this.currentLexIndex + 1);
  812.         },
  813.         PrevLex() {
  814.             this.SetLexIndex(this.currentLexIndex - 1);
  815.         },
  816.         Error(expected) {
  817.             let text = `Incorrect char on position ${this.currentLex.position.start}. Expected (${JSON.stringify(expected)}) but has "${this.currentLex.class}"`;
  818.             throw new Error(text);
  819.         },
  820.         GenerateNode(value, type, pos) {
  821.             let node = {
  822.                 value: value,
  823.                 type: type,
  824.                 position: pos.start,
  825.                 nodes: [],
  826.                 UpdateValueByNodes() {
  827.                     if (this.nodes.length < 1) {
  828.                         return this.value;
  829.                     }
  830.  
  831.                     let nodesValues = this.nodes.map(n => n.UpdateValueByNodes());
  832.                     let newValue = nodesValues.join(' ');
  833.                     this.value = newValue;
  834.                     return newValue;
  835.                 }
  836.             };
  837.             return node;
  838.         },
  839.         GeneratePosNode(value, type) {
  840.             let node = this.GenerateNode(value, type, this.currentLex.position);
  841.             return node;
  842.         },
  843.         GenerateTypeNode(type) {
  844.             let node = this.GenerateNode('none', type, this.currentLex.position);
  845.             return node;
  846.         },
  847.         GenerateLexNode() {
  848.             let node = this.GeneratePosNode(this.currentLex.word, this.currentLex.class);
  849.             return node;
  850.         },
  851.         Value(parrentNode) {
  852.             // lex.values.variable
  853.             //  | lex.values.numConst
  854.             //  | lex.separators.bracket.start sint.math lex.separators.bracket.end
  855.             let node = this.GenerateTypeNode(SintClasses.Value);
  856.             let tempIndex = this.currentLexIndex;
  857.  
  858.             if(!this.currentLex) return;
  859.  
  860.             if (this.currentLex.class == LexClasses.separators.bracket.start.value) {
  861.                 let temp = this.GenerateLexNode();
  862.                 node.nodes.push(temp);
  863.                 this.NextLex();
  864.  
  865.                 this.MathOperation(node);
  866.  
  867.                 if (this.currentLex.class !== LexClasses.separators.bracket.end.value) {
  868.                     this.Error([LexClasses.separators.bracket.end.value]);
  869.                 }
  870.                 temp = this.GenerateLexNode();
  871.                 node.nodes.push(temp);
  872.                 this.NextLex();
  873.             } else {
  874.                 let inner = undefined;
  875.                 switch (this.currentLex.class) {
  876.                     case LexClasses.values.variable.value:
  877.                         this.poliz.addVariable(this.currentLex.word);
  878.                         inner = this.GenerateLexNode();
  879.                         node.nodes.push(inner);
  880.                         this.NextLex();
  881.                         break;
  882.                     case LexClasses.values.numConst.value:
  883.                         this.poliz.addConst(this.currentLex.word);
  884.                         inner = this.GenerateLexNode();
  885.                         node.nodes.push(inner);
  886.                         this.NextLex();
  887.                         break;
  888.                     default:
  889.                         this.Error([LexClasses.values.variable.value, LexClasses.values.numConst.value]);
  890.                 }
  891.             }
  892.  
  893.             parrentNode.nodes.push(node);
  894.         },
  895.         MathOperation(parrentNode) {
  896.             // sint.value lex.operations.math sint.math
  897.             //  | sint.value
  898.             let node = this.GenerateTypeNode(SintClasses.MathOperation);
  899.  
  900.             this.Value(node);
  901.  
  902.             if (this.currentLex && this.currentLex.class === LexClasses.operations.math.value) {
  903.                 let polizMathCommand = undefined;
  904.                 switch (this.currentLex.word) {
  905.                     case '+':
  906.                         polizMathCommand = PolizCommand.ADD;
  907.                         break;
  908.                     case '-':
  909.                         polizMathCommand = PolizCommand.SUB;
  910.                         break;
  911.                     case '*':
  912.                         polizMathCommand = PolizCommand.MUL;
  913.                         break;
  914.                     case '/':
  915.                         polizMathCommand = PolizCommand.DIV;
  916.                         break;
  917.                     default:
  918.                         throw 'Poliz error!';
  919.                 }
  920.  
  921.                 let temp = this.GenerateLexNode();
  922.                 node.nodes.push(temp);
  923.                 this.NextLex();
  924.  
  925.                 this.MathOperation(node);
  926.  
  927.                 this.poliz.addCommand(polizMathCommand);
  928.             }
  929.  
  930.             parrentNode.nodes.push(node);
  931.         },
  932.         LogicOperation(parrentNode) {
  933.             // lex.separators.bracket.start sint.math lex.operations.compare sint.math lex.separators.bracket.end
  934.             let node = this.GenerateTypeNode(SintClasses.LogicOperation);
  935.  
  936.             if (this.currentLex.class !== LexClasses.separators.bracket.start.value) {
  937.                 this.Error([LexClasses.separators.bracket.start.value]);
  938.             }
  939.             let temp = this.GenerateLexNode();
  940.             node.nodes.push(temp);
  941.             this.NextLex();
  942.  
  943.             this.MathOperation(node);
  944.  
  945.             if (this.currentLex.class !== LexClasses.operations.compare.value) {
  946.                 this.Error([LexClasses.operations.compare.value]);
  947.             }
  948.             let polizCompareCommand = undefined;
  949.             switch (this.currentLex.word) {
  950.                 case '<':
  951.                     polizCompareCommand = PolizCommand.CMPL;
  952.                     break;
  953.                 case '<=':
  954.                     polizCompareCommand = PolizCommand.CMPLE;
  955.                     break;
  956.                 case '>':
  957.                     polizCompareCommand = PolizCommand.CMPG;
  958.                     break;
  959.                 case '>=':
  960.                     polizCompareCommand = PolizCommand.CMPGE;
  961.                     break;
  962.                 case '==':
  963.                     polizCompareCommand = PolizCommand.CMPE;
  964.                     break;
  965.                 case '<>':
  966.                     polizCompareCommand = PolizCommand.CMPNE;
  967.                     break;
  968.                 default:
  969.                     throw 'Poliz error!';
  970.             }
  971.             temp = this.GenerateLexNode();
  972.             node.nodes.push(temp);
  973.             this.NextLex();
  974.  
  975.             this.MathOperation(node);
  976.  
  977.             if (this.currentLex.class !== LexClasses.separators.bracket.end.value) {
  978.                 this.Error([LexClasses.separators.bracket.end.value]);
  979.             }
  980.             temp = this.GenerateLexNode();
  981.             node.nodes.push(temp);
  982.             this.NextLex();
  983.  
  984.             this.poliz.addCommand(polizCompareCommand);
  985.  
  986.             parrentNode.nodes.push(node);
  987.         },
  988.         LogicExpression(parrentNode) {
  989.             // lex.separators.bracket.start sint.logic.expression lex.operations.logical sint.logic.expression lex.separators.bracket.end
  990.             //  | sint.logic.operation
  991.             let node = this.GenerateTypeNode(SintClasses.LogicExpression);
  992.  
  993.             let tempIndex = this.currentLexIndex;
  994.             let polizCodeLen = this.poliz.getCodeLength();
  995.             try {
  996.                 this.LogicOperation(node);
  997.             } catch (error) {
  998.                 this.SetLexIndex(tempIndex);
  999.                 this.poliz.popCodeForLength(polizCodeLen);
  1000.                 if (this.currentLex.class !== LexClasses.separators.bracket.start.value) {
  1001.                     this.Error([LexClasses.separators.bracket.start.value]);
  1002.                 }
  1003.                 let temp = this.GenerateLexNode();
  1004.                 node.nodes.push(temp);
  1005.                 this.NextLex();
  1006.  
  1007.                 tempIndex = this.currentLexIndex;
  1008.                 lizCodeLen = this.poliz.getCodeLength();
  1009.                 try {
  1010.                     this.LogicExpression(node);
  1011.                 } catch (error) {
  1012.                     this.SetLexIndex(tempIndex);
  1013.                     this.poliz.popCodeForLength(polizCodeLen);
  1014.                     this.LogicOperation(node);
  1015.                 }
  1016.  
  1017.                 if (this.currentLex.class !== LexClasses.operations.logical.value) {
  1018.                     this.Error([LexClasses.operations.logical.value]);
  1019.                 }
  1020.                 let polizLogicCommand = undefined;
  1021.                 switch (this.currentLex.word) {
  1022.                     case 'and':
  1023.                         polizLogicCommand = PolizCommand.AND;
  1024.                         break;
  1025.                     case 'or':
  1026.                         polizLogicCommand = PolizCommand.OR;
  1027.                         break;
  1028.                     default:
  1029.                         throw 'Poliz error!';
  1030.                 }
  1031.                 temp = this.GenerateLexNode();
  1032.                 node.nodes.push(temp);
  1033.                 this.NextLex();
  1034.  
  1035.                 tempIndex = this.currentLexIndex;
  1036.                 lizCodeLen = this.poliz.getCodeLength();
  1037.                 try {
  1038.                     this.LogicExpression(node);
  1039.                 } catch (error) {
  1040.                     this.SetLexIndex(tempIndex);
  1041.                     this.poliz.popCodeForLength(polizCodeLen);
  1042.                     this.LogicOperation(node);
  1043.                 }
  1044.  
  1045.                 if (this.currentLex.class !== LexClasses.separators.bracket.end.value) {
  1046.                     this.Error([LexClasses.separators.bracket.end.value]);
  1047.                 }
  1048.                 temp = this.GenerateLexNode();
  1049.                 node.nodes.push(temp);
  1050.                 this.NextLex();
  1051.  
  1052.                 this.poliz.addCommand(polizLogicCommand);
  1053.             }
  1054.  
  1055.             parrentNode.nodes.push(node);
  1056.         },
  1057.         Assignment(parrentNode) {
  1058.             // lex.values.variable lex.operations.as sint.math
  1059.             let node = this.GenerateTypeNode(SintClasses.Assignment);
  1060.  
  1061.             if (this.currentLex.class !== LexClasses.values.variable.value) {
  1062.                 this.Error([LexClasses.values.variable.value]);
  1063.             }
  1064.             this.poliz.addVariable(this.currentLex.word);
  1065.             let temp = this.GenerateLexNode();
  1066.             node.nodes.push(temp);
  1067.             this.NextLex();
  1068.  
  1069.             if (this.currentLex.class !== LexClasses.operations.as.value) {
  1070.                 this.Error([LexClasses.operations.as.value]);
  1071.             }
  1072.             temp = this.GenerateLexNode();
  1073.             node.nodes.push(temp);
  1074.             this.NextLex();
  1075.  
  1076.             this.MathOperation(node);
  1077.  
  1078.             this.poliz.addCommand(PolizCommand.SET);
  1079.  
  1080.             parrentNode.nodes.push(node);
  1081.         },
  1082.         WhileLoop(parrentNode) {
  1083.             // lex.keyword.codeSegment.start lex.keyword.loop.while.start sint.logic.expression [sint.operation] lex.keyword.loop.while.end
  1084.             let node = this.GenerateTypeNode(SintClasses.WhileLoop);
  1085.  
  1086.             let polizLoopStartIndex = this.poliz.getCodeLength();
  1087.  
  1088.             if (this.currentLex.class !== LexClasses.keywords.codeSegment.start.value) {
  1089.                 this.Error([LexClasses.keywords.codeSegment.start.value]);
  1090.             }
  1091.             let temp = this.GenerateLexNode();
  1092.             node.nodes.push(temp);
  1093.             this.NextLex();
  1094.  
  1095.             if (this.currentLex.class !== LexClasses.keywords.loop.while.start.value) {
  1096.                 this.Error([LexClasses.keywords.loop.while.start.value]);
  1097.             }
  1098.             temp = this.GenerateLexNode();
  1099.             node.nodes.push(temp);
  1100.             this.NextLex();
  1101.  
  1102.             this.LogicExpression(node);
  1103.  
  1104.             let polizAfterLoopLabel = this.poliz.addPointer(-1);
  1105.             this.poliz.addCommand(PolizCommand.JZ);
  1106.  
  1107.             while (this.currentLex.class !== LexClasses.keywords.loop.while.end.value) {
  1108.                 this.Operation(node);
  1109.             }
  1110.  
  1111.             if (this.currentLex.class !== LexClasses.keywords.loop.while.end.value) {
  1112.                 this.Error([LexClasses.keywords.loop.while.end.value]);
  1113.             }
  1114.             temp = this.GenerateLexNode();
  1115.             node.nodes.push(temp);
  1116.             this.NextLex();
  1117.  
  1118.             this.poliz.addPointer(polizLoopStartIndex);
  1119.             let polizLastLoopIndex = this.poliz.addCommand(PolizCommand.JMP);
  1120.             this.poliz.updateValue(polizAfterLoopLabel, polizLastLoopIndex + 1);
  1121.  
  1122.             parrentNode.nodes.push(node);
  1123.         },
  1124.         Operation(parrentNode) {
  1125.             // sint.assignment
  1126.             //  | sint.loop.while
  1127.             let node = this.GenerateTypeNode(SintClasses.Operation);
  1128.             switch (this.currentLex.class) {
  1129.                 case LexClasses.values.variable.value:
  1130.                     this.Assignment(node);
  1131.                     break;
  1132.                 case LexClasses.keywords.codeSegment.start.value:
  1133.                     this.WhileLoop(node);
  1134.                     break;
  1135.                 default:
  1136.                     throw this.Error([LexClasses.values.variable.value, LexClasses.keywords.codeSegment.start.value]);
  1137.             }
  1138.             parrentNode.nodes.push(node);
  1139.         },
  1140.         parse(lexems) {
  1141.             this.lexList = lexems;
  1142.             this.FirstLex();
  1143.             this.output = this.GenerateTypeNode(SintClasses.Code);
  1144.             try {
  1145.                 while (this.currentLexIndex < this.lexList.length) {
  1146.                     this.Operation(this.output);
  1147.                 }
  1148.                 this.output.UpdateValueByNodes();
  1149.             } catch (ex) {
  1150.                 alert(ex);
  1151.             }
  1152.         },
  1153.     };
  1154. </script>
  1155.  
  1156. <script src="http://synset.com/ai/_js/tree.js"></script>
  1157.  
  1158. <script>
  1159.     const lexAnalizerInstance = new LexAnalizer(FullAutomatesList);
  1160.  
  1161.     const sintAnalizerInstance = new SintAnalizer();
  1162.  
  1163.     function drawLexOutputTable(output) {
  1164.         let outputTable = {
  1165.             tag: HTMLTags.Table,
  1166.             type: ItemTypes.Container,
  1167.             attributes: { border: "1" },
  1168.             childs: []
  1169.         };
  1170.  
  1171.         outputTable.childs.push({
  1172.             tag: HTMLTags.TableRow,
  1173.             type: ItemTypes.Container,
  1174.             childs: [
  1175.                 {
  1176.                     tag: HTMLTags.TableData,
  1177.                     type: ItemTypes.Value,
  1178.                     value: 'Значение'
  1179.                 },
  1180.                 {
  1181.                     tag: HTMLTags.TableData,
  1182.                     type: ItemTypes.Value,
  1183.                     value: 'Начальная позиция'
  1184.                 },
  1185.                 {
  1186.                     tag: HTMLTags.TableData,
  1187.                     type: ItemTypes.Value,
  1188.                     value: 'Конечная позиция'
  1189.                 },
  1190.                 {
  1191.                     tag: HTMLTags.TableData,
  1192.                     type: ItemTypes.Value,
  1193.                     value: 'Класс'
  1194.                 },
  1195.             ]
  1196.         });
  1197.  
  1198.         for (const o of output) {
  1199.             outputTable.childs.push({
  1200.                 tag: HTMLTags.TableRow,
  1201.                 type: ItemTypes.Container,
  1202.                 childs: [
  1203.                     {
  1204.                         tag: HTMLTags.TableData,
  1205.                         type: ItemTypes.Value,
  1206.                         value: o.word
  1207.                     },
  1208.                     {
  1209.                         tag: HTMLTags.TableData,
  1210.                         type: ItemTypes.Value,
  1211.                         value: o.position.start
  1212.                     },
  1213.                     {
  1214.                         tag: HTMLTags.TableData,
  1215.                         type: ItemTypes.Value,
  1216.                         value: o.position.end
  1217.                     },
  1218.                     {
  1219.                         tag: HTMLTags.TableData,
  1220.                         type: ItemTypes.Value,
  1221.                         value: o.class
  1222.                     },
  1223.                 ]
  1224.             });
  1225.         }
  1226.  
  1227.         return outputTable;
  1228.     }
  1229.  
  1230.     function drawGraphTable(graphNode) {
  1231.         let curNode = undefined;
  1232.         let value = `(value: "${graphNode.value}", pos: ${graphNode.position}, type: ${graphNode.type})`;
  1233.         let tableAttrs = { border: "1", cellspacing: 0 };
  1234.  
  1235.         if (graphNode.nodes.length > 0) {
  1236.             const nodesList = {
  1237.                 tag: HTMLTags.TableRow,
  1238.                 type: ItemTypes.Container,
  1239.                 childs: []
  1240.             };
  1241.  
  1242.             for (const node of graphNode.nodes) {
  1243.                 nodesList.childs.push({
  1244.                     tag: HTMLTags.TableData,
  1245.                     type: ItemTypes.Container,
  1246.                     attributes: { align: 'center', valign: 'top' },
  1247.                     childs: [
  1248.                         drawGraphTable(node)
  1249.                     ]
  1250.                 });
  1251.             }
  1252.  
  1253.             curNode = {
  1254.                 tag: HTMLTags.Table,
  1255.                 type: ItemTypes.Container,
  1256.                 attributes: tableAttrs,
  1257.                 childs: [
  1258.                     {
  1259.                         tag: HTMLTags.TableRow,
  1260.                         type: ItemTypes.Container,
  1261.                         childs: [
  1262.                             {
  1263.                                 tag: HTMLTags.TableData,
  1264.                                 type: ItemTypes.Value,
  1265.                                 attributes: { colspan: graphNode.nodes.length, align: 'center', valign: 'top' },
  1266.                                 value: value
  1267.                             }
  1268.                         ]
  1269.                     },
  1270.                     nodesList
  1271.                 ]
  1272.             };
  1273.         } else {
  1274.             curNode = {
  1275.                 tag: HTMLTags.Table,
  1276.                 type: ItemTypes.Container,
  1277.                 attributes: tableAttrs,
  1278.                 childs: [
  1279.                     {
  1280.                         tag: HTMLTags.TableRow,
  1281.                         type: ItemTypes.Container,
  1282.                         childs: [
  1283.                             {
  1284.                                 tag: HTMLTags.TableData,
  1285.                                 type: ItemTypes.Value,
  1286.                                 attributes: { align: 'center', valign: 'top' },
  1287.                                 value: value
  1288.                             }
  1289.                         ]
  1290.                     }
  1291.                 ]
  1292.             };
  1293.         }
  1294.  
  1295.         return curNode;
  1296.     }
  1297.  
  1298.     function drawPolizTable(poliz) {
  1299.         let table = {
  1300.             tag: HTMLTags.Table,
  1301.             type: ItemTypes.Container,
  1302.             attributes: { border: "1", cellspacing: 0 },
  1303.             childs: [
  1304.                 {
  1305.                     tag: HTMLTags.TableRow,
  1306.                     type: ItemTypes.Container,
  1307.                     childs: [
  1308.                         {
  1309.                             tag: HTMLTags.TableData,
  1310.                             type: ItemTypes.Value,
  1311.                             attributes: { align: 'center' },
  1312.                             value: 'Index'
  1313.                         },
  1314.                         {
  1315.                             tag: HTMLTags.TableData,
  1316.                             type: ItemTypes.Value,
  1317.                             attributes: { align: 'center' },
  1318.                             value: 'Type'
  1319.                         },
  1320.                         {
  1321.                             tag: HTMLTags.TableData,
  1322.                             type: ItemTypes.Value,
  1323.                             attributes: { align: 'center' },
  1324.                             value: 'Value'
  1325.                         },
  1326.                         {
  1327.                             tag: HTMLTags.TableData,
  1328.                             type: ItemTypes.Value,
  1329.                             attributes: { align: 'center' },
  1330.                             value: 'Details'
  1331.                         },
  1332.                     ]
  1333.                 }
  1334.             ]
  1335.         };
  1336.  
  1337.         poliz.code.forEach((value, index) => {
  1338.             let details = undefined;
  1339.             switch (value.type) {
  1340.                 case PolizRecordType.Variable:
  1341.                     details = poliz.valiables[value.value];
  1342.                     break;
  1343.                 case PolizRecordType.Command:
  1344.                     details = PolizCommandsList[value.value];
  1345.                     break;
  1346.                 case PolizRecordType.Const:
  1347.                 case PolizRecordType.Pointer:
  1348.                     details = value.value;
  1349.                     break;
  1350.             }
  1351.  
  1352.             table.childs.push({
  1353.                 tag: HTMLTags.TableRow,
  1354.                 type: ItemTypes.Container,
  1355.                 childs: [
  1356.                     {
  1357.                         tag: HTMLTags.TableData,
  1358.                         type: ItemTypes.Value,
  1359.                         attributes: { align: 'center' },
  1360.                         value: index
  1361.                     },
  1362.                     {
  1363.                         tag: HTMLTags.TableData,
  1364.                         type: ItemTypes.Value,
  1365.                         attributes: { align: 'center' },
  1366.                         value: value.type
  1367.                     },
  1368.                     {
  1369.                         tag: HTMLTags.TableData,
  1370.                         type: ItemTypes.Value,
  1371.                         attributes: { align: 'center' },
  1372.                         value: value.value
  1373.                     },
  1374.                     {
  1375.                         tag: HTMLTags.TableData,
  1376.                         type: ItemTypes.Value,
  1377.                         attributes: { align: 'center' },
  1378.                         value: details
  1379.                     }
  1380.                 ]
  1381.             });
  1382.         })
  1383.  
  1384.         return table;
  1385.     }
  1386.  
  1387.     document.getElementById('parseButton').onclick = () => {
  1388.         lexAnalizerInstance.analize(IOContainers.input.value);
  1389.         IOContainers.lexOutput.innerHTML = '';
  1390.         IOContainers.lexOutput.append(render(drawLexOutputTable(lexAnalizerInstance.output)));
  1391.  
  1392.         sintAnalizerInstance.parse(lexAnalizerInstance.output);
  1393.         IOContainers.sintOutput.innerHTML = '';
  1394.         IOContainers.sintOutput.append(render(drawGraphTable(sintAnalizerInstance.output)));
  1395.  
  1396.         if (Tree) {
  1397.             function mapToTree(node) {
  1398.                 // if (node.nodes.length < 1) {
  1399.                 //     return {
  1400.                 //         nm: `(value: "${node.value}", pos: ${node.position}, type: ${node.type})`
  1401.                 //     };
  1402.                 // }
  1403.                 let res = {
  1404.                     nm: node.value,
  1405.                     ar: []
  1406.                 };
  1407.  
  1408.                 for (let inner of node.nodes) {
  1409.                     res.ar.push(mapToTree(inner));
  1410.                 }
  1411.  
  1412.                 return res;
  1413.             }
  1414.  
  1415.             let t1 = mapToTree(sintAnalizerInstance.output); // Tree.rand(3, 4, 0.1);
  1416.             let t2 = Tree.getSVG(t1);
  1417.             document.getElementById('sintOutputCanvas').innerHTML = t2;
  1418.         }
  1419.  
  1420.         IOContainers.polizOutput.innerHTML = '';
  1421.         IOContainers.polizOutput.append(render(drawPolizTable(sintAnalizerInstance.poliz)));
  1422.  
  1423.     };
  1424. </script>
  1425.  
  1426. </html>
Add Comment
Please, Sign In to add comment