analisadorSintatico.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import { CommonTokenStream } from 'antlr4/index';
  2. import { SintaxError } from './SintaxError';
  3. class AnalisadorSintatico {
  4. constructor (lexer) {
  5. this.lexer = lexer;
  6. this.tokenStream = new CommonTokenStream(lexer);
  7. this.tokenStream.fill();
  8. this.pos = 1;
  9. this.variableTypes = [this.lexer.PR_INTEIRO, this.lexer.PR_REAL, this.lexer.PR_LOGICO, this.lexer.PR_CADEIA];
  10. }
  11. parseTree () {
  12. return {};
  13. }
  14. getToken (index = null) {
  15. if(index === null)
  16. index = this.pos;
  17. return this.tokenStream.LT(index);
  18. }
  19. parseProgram () {
  20. let token = null;
  21. if(this.lexer.PR_PROGRAMA === (token = this.getToken()).type) {
  22. try {
  23. this.pos++;
  24. this.consumeNewLines();
  25. parseOpenCurly();
  26. this.pos++;
  27. this.consumeNewLines();
  28. const globalVars = parseGlobalVariables();
  29. this.consumeNewLines();
  30. const functions = parseFunctions();
  31. this.consumeNewLines();
  32. parseCloseCurly();
  33. this.pos++;
  34. this.consumeNewLines();
  35. if(this.lexer.EOF !== (token = this.getToken()).type) {
  36. console.log("No extra characters are allowed after program {...}");
  37. }
  38. return {global: globalVars, functions: functions};
  39. } catch(SintaxError err) {
  40. console.log(err.message);
  41. }
  42. } else {
  43. throw SintaxError.createError(this.lexer.literalNames(this.lexer.PR_PROGRAMA), token);
  44. }
  45. return null;
  46. }
  47. parseOpenCurly () {
  48. let token = null;
  49. if(this.lexer.ABRE_CHA !== (token = this.getToken()).type){
  50. throw SintaxError.createError(this.getErrorString('{', token));
  51. }
  52. }
  53. parseCloseCurly () {
  54. let token = null;
  55. if(this.lexer.FECHA_CHA !== (token = this.getToken()).type){
  56. throw SintaxError.createError(this.getErrorString('}', token));
  57. }
  58. }
  59. parseGlobalVariables () {
  60. let vars = [];
  61. while(true) {
  62. const decl = this.parseHasConst();
  63. const eosToken = this.getToken();
  64. if (eosToken.type !== this.lexer.EOS) {
  65. throw SintaxError.createError('new line or \';\'', eosToken);
  66. }
  67. this.pos++;
  68. if (decl === null)
  69. break;
  70. else
  71. vars.push(decl);
  72. }
  73. return vars;
  74. }
  75. /*
  76. * Checks if the next token is PR_CONST. It's only available
  77. * at global variables declaration level
  78. * @returns Declararion(const, type, id, initVal?)
  79. **/
  80. parseHasConst () {
  81. const constToken = this.getToken();
  82. if(constToken.type === this.lexer.PR_CONST) {
  83. this.pos++;
  84. const typeToken = this.getToken();
  85. if(!this.isVariableType(typeToken)) {
  86. throw SintaxError.createError(this.getCommaTypeString(), typeToken);
  87. }
  88. this.pos++;;
  89. return parseDeclararion(typeToken, true);
  90. } else if(isVariableType(constToken)) {
  91. return parseDeclararion(constToken);
  92. } else {
  93. return null;
  94. }
  95. }
  96. /*
  97. * Parses a declarion of the form: type --- id --- (= --- EAnd)?
  98. * @returns Declararion(const, type, id, initVal?)
  99. **/
  100. parseDeclararion (isConst = false) {
  101. const typeToken = this.getToken();
  102. if(!this.isVariableType(typeToken)) {
  103. throw SintaxError.createError(this.getCommaTypeString(), typeToken);
  104. }
  105. this.pos++;
  106. const idToken = this.getToken();
  107. if(idToken.type !== this.lexer.ID) {
  108. throw SintaxError.createError('ID', idToken);
  109. }
  110. this.pos++;
  111. const equalsToken = this.getToken();
  112. if(equalsToken.type === this.lexer.ATRIBUICAO) {
  113. //process Expression
  114. } else {
  115. return {isConst: isConst, tipo: typeToken.text, id: idToken.text};
  116. }
  117. }
  118. consumeNewLines () {
  119. token = this.getToken();
  120. while(token.type === this.lexer.EOS && token.text.match('[\r\n]')) {
  121. this.pos++;
  122. token = this.getToken();
  123. }
  124. }
  125. isVariableType (token) {
  126. return this.variableTypes.find(v => v === token.type);
  127. }
  128. getCommaTypeString () {
  129. return this.variableTypes.map( x => this.lexer.literalNames[x])
  130. .reduce((o, n) => {
  131. if (o.length <= 0)
  132. return n;
  133. else
  134. return o + ", " + n;
  135. }, '');
  136. }
  137. }