Browse Source

Rework some array error messages to be syntatic instead of semantic

* Matrix lines size check is now syntatic

Implement dimension size inference error message
Lucas de Souza 4 years ago
parent
commit
40ff0e6c67
4 changed files with 65 additions and 64 deletions
  1. 5 1
      i18n/pt/error.json
  2. 37 17
      js/ast/error/syntaxErrorFactory.js
  3. 13 15
      js/ast/ivprogParser.js
  4. 10 31
      package-lock.json

+ 5 - 1
i18n/pt/error.json

@@ -95,5 +95,9 @@
   "inform_valid_function_duplicated" : "Já existe uma função com o nome <span class='ivprog-error-varname'>$0</span>, você precisa de nomes distintos.",
   "inform_valid_param_duplicated" : "Já existe um parâmetro com o nome <span class='ivprog-error-varname'>$0</span> na função <span class='ivprog-error-varname'>$1</span>, você precisa de nomes distintos.",
   "invalid_character": "O caractere $0 na linha $1 não pode ser utilizado neste contexto.",
-  "annonymous_array_literal": "Erro na linha $0: a notação de vetor/matriz só permitida durante a inicialização de uma variável desse tipo. Ex: inteiro vec[3] ← {1,2,3}."
+  "annonymous_array_literal": "Erro na linha $0: a notação de vetor/matriz só permitida durante a inicialização de uma variável desse tipo. Ex: inteiro vec[3] ← {1,2,3}.",
+  "invalid_matrix_literal_line": "A expressão $0 na linha $1 não possui um número de elementos igual a linha anterior. Todas as linhas de uma matriz devem ter a mesma quantidade de elementos.",
+  "cannot_infer_matrix_line": "Não é possível inferir o número de linhas da matriz $0 na linha $1. É necessário que ela seja inicializada ou que o valor seja informado de forma explícita.",
+  "cannot_infer_matrix_column": "Não é possível inferir o número de colunas da matriz $0 na linha $1. É necessário que ela seja inicializada ou que o valor seja informado de forma explícita.",
+  "cannot_infer_vector_size": "Não é possível inferir o número de elementos do vetor $0 na linha $1. É necessário que ele seja inicializado ou que o valor seja informado de forma explícita"
 }

+ 37 - 17
js/ast/error/syntaxErrorFactory.js

@@ -3,11 +3,15 @@ import { SyntaxError } from './syntaxError';
 
 const LocalizedStrings = LocalizedStringsService.getInstance();
 
+function createError (message_id, context = []) {
+  return new SyntaxError(LocalizedStrings.getError(message_id, context));
+}
+
 export const SyntaxErrorFactory = Object.freeze({
   extra_lines: () => new SyntaxError(LocalizedStrings.getError("extra_lines")),
   token_missing_one: (expected, token) => {
     const context = [expected, token.text, token.line, token.column];
-    return new SyntaxError(LocalizedStrings.getError("token_missing_one", context));
+    return createError("token_missing_one", context);
   },
   token_missing_list: (expectedList, token) => {
     const line = expectedList.join(LocalizedStrings.getOR());
@@ -15,66 +19,82 @@ export const SyntaxErrorFactory = Object.freeze({
   },
   id_missing: (token) => {
     const context = [token.text, token.line, token.column];
-    return new SyntaxError(LocalizedStrings.getError("id_missing", context));
+    return createError("id_missing", context);
   },
   eos_missing: (token) => {
     const context = [token.line, token.column];
-    return new SyntaxError(LocalizedStrings.getError("eos_missing", context));
+    return createError("eos_missing", context);
   },
   invalid_array_dimension: (typeName, token) => {
     const context = [token.line, token.column, typeName];
-    return new SyntaxError(LocalizedStrings.getError("invalid_array_dimension", context));
+    return createError("invalid_array_dimension", context);
   },
   invalid_array_size: (token) => {
     const context = [token.line];
-    return new SyntaxError(LocalizedStrings.getError("invalid_array_size", context));
+    return createError("invalid_array_size", context);
   },
   invalid_main_return: (name, typeName, token) => {
     const context = [name, typeName, token.line];
-    return new SyntaxError(LocalizedStrings.getError("invalid_main_return", context));
+    return createError("invalid_main_return", context);
   },
   invalid_var_declaration: (token) => {
     const context = [token.line];
-    return new SyntaxError(LocalizedStrings.getError("invalid_var_declaration", context));
+    return createError("invalid_var_declaration", context);
   },
   invalid_break_command: (cmdName, token) => {
     const context = [token.line, cmdName];
-    return new SyntaxError(LocalizedStrings.getError("invalid_break_command", context));
+    return createError("invalid_break_command", context);
   },
   invalid_terminal: (token) => {
     const context = [token.text, token.line, token.column];
-    return new SyntaxError(LocalizedStrings.getError('invalid_terminal', context));
+    return createError('invalid_terminal', context);
   },
   invalid_type: (list, token) => {
     const line = list.join(LocalizedStrings.getOR());
     const context = [token.text, token.line, token.column, line]
-    return new SyntaxError(LocalizedStrings.getError("invalid_type", context));
+    return createError("invalid_type", context);
   },
   const_not_init: (token) => {
     const context = [token.line, token.column];
-    return new SyntaxError(LocalizedStrings.getError("const_not_init", context));
+    return createError("const_not_init", context);
   },
   invalid_id_format: (token) => {
     const context = [token.text, token.line, token.column];
-    return new SyntaxError(LocalizedStrings.getError("invalid_id_format", context));
+    return createError("invalid_id_format", context);
   },
   duplicate_function: (token) => {
     const context = [token.text, token.line, token.column];
-    return new SyntaxError(LocalizedStrings.getError("duplicate_function", context));
+    return createError("duplicate_function", context);
   },
   main_parameters: () => {
-    return new SyntaxError(LocalizedStrings.getError("main_parameters"));
+    return createError("main_parameters");
   },
   duplicate_variable: (token) => {
     const context = [token.text, token.line, token.column];
-    return new SyntaxError(LocalizedStrings.getError("duplicate_variable", context));
+    return createError("duplicate_variable", context);
   },
   invalid_character: (text, line, column) => {
     const context = [text, line];
-    return new SyntaxError(LocalizedStrings.getError("invalid_character", context));
+    return createError("invalid_character", context);
   },
   annonymous_array_literal: (token) => {
     const context = [token.line];
-    return new SyntaxError(LocalizedStrings.getError("annonymous_array_literal", context));
+    return createError("annonymous_array_literal", context);
+  },
+  invalid_matrix_literal_line: (exp, sourceInfo) => {
+    const context = [exp, sourceInfo.line];
+    return createError("invalid_matrix_literal_line", context);
+  },
+  cannot_infer_matrix_line: (name, sourceInfo) => {
+    const context = [name, sourceInfo.line];
+    return createError("cannot_infer_matrix_line", context);
+  },
+  cannot_infer_matrix_column: (name, sourceInfo) => {
+    const context = [name, sourceInfo.line];
+    return createError("cannot_infer_matrix_column", context);
+  },
+  cannot_infer_vector_size: (name, sourceInfo) => {
+    const context = [name, sourceInfo.line];
+    return createError("cannot_infer_vector_size", context);
   }
 });

+ 13 - 15
js/ast/ivprogParser.js

@@ -343,18 +343,18 @@ export class IVProgParser {
       throw SyntaxErrorFactory.const_not_init(sourceInfo);
     }
     if(equalsToken.type === this.lexerClass.EQUAL) {
-      this.pos++;
+      this.pos += 1
       initial = this.parseArrayLiteral(typeString);
     }
-    if(dimensions === 1) {
-      if(initial == null && dim1 == null) {
-        // cannot infer dimension
-        throw new Error("cannot infer dimension 1");
+    if(initial == null && dim1 == null) {
+      if(dimensions > 1) {
+        throw SyntaxErrorFactory.cannot_infer_matrix_line(idString, sourceInfo);
       }
-    } else {
-      if(initial == null && (dim1 == null || dim2 == null)) {
-        // cannot infer dimension
-        throw new Error("cannot infer dimension 2");
+      throw SyntaxErrorFactory.cannot_infer_vector_size(idString, sourceInfo);
+    }
+    if(dimensions > 1) {
+      if(initial == null &&  dim2 == null) {
+        throw SyntaxErrorFactory.cannot_infer_matrix_column(idString, sourceInfo);
       }
     }
 
@@ -455,6 +455,7 @@ export class IVProgParser {
     this.checkOpenCurly();
     const beginArray = this.getToken();
     if (this.parsingArrayDimension >= 2) {
+      // TODO better message
       throw SyntaxErrorFactory.token_missing_list(`Array dimensions exceed maximum size of 2 at line ${beginArray.line}`);
     }
     this.pos += 1;
@@ -481,10 +482,6 @@ export class IVProgParser {
     const type = new CompoundType(typeString, dataDim);
     const exp = new Expressions.ArrayLiteral(type, data);
     exp.sourceInfo = sourceInfo;
-    if(!exp.isValid) {
-      // invalid array
-      throw new Error("invalid array");
-    }
     return exp;
   }
 
@@ -498,6 +495,7 @@ export class IVProgParser {
       this.checkOpenCurly();
       const beginArray = this.getToken();
       if (this.parsingArrayDimension >= 2) {
+        // TODO better message
         throw SyntaxErrorFactory.token_missing_list(`Array dimensions exceed maximum size of 2 at line ${beginArray.line}`);
       }
       this.pos += 1;
@@ -509,13 +507,13 @@ export class IVProgParser {
       const endArray = this.getToken();
       this.pos += 1;
       this.parsingArrayDimension -= 1;
+      const sourceInfo = SourceInfo.createSourceInfoFromList(beginArray, endArray);
       if(lastSize == null) {
         lastSize = data.length;
       } else if (lastSize !== data.length) {
         const expString = this.inputStream.getText(beginArray.start, endArray.stop);
-        throw new Error("Invalid size: " + expString);
+        throw SyntaxErrorFactory.invalid_matrix_literal_line(expString, sourceInfo);
       }
-      const sourceInfo = SourceInfo.createSourceInfoFromList(beginArray, endArray);
       const type = new CompoundType(typeString, 1);
       const exp = new Expressions.ArrayLiteral(type, data);
       exp.sourceInfo = sourceInfo;

+ 10 - 31
package-lock.json

@@ -5279,9 +5279,9 @@
       }
     },
     "mixin-deep": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
-      "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
+      "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
       "requires": {
         "for-in": "^1.0.2",
         "is-extendable": "^1.0.1"
@@ -6683,9 +6683,9 @@
       "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E="
     },
     "set-value": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
-      "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
+      "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
       "requires": {
         "extend-shallow": "^2.0.1",
         "is-extendable": "^0.1.1",
@@ -7434,35 +7434,14 @@
       "dev": true
     },
     "union-value": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
-      "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
+      "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
       "requires": {
         "arr-union": "^3.1.0",
         "get-value": "^2.0.6",
         "is-extendable": "^0.1.1",
-        "set-value": "^0.4.3"
-      },
-      "dependencies": {
-        "extend-shallow": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
-          "requires": {
-            "is-extendable": "^0.1.0"
-          }
-        },
-        "set-value": {
-          "version": "0.4.3",
-          "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
-          "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
-          "requires": {
-            "extend-shallow": "^2.0.1",
-            "is-extendable": "^0.1.1",
-            "is-plain-object": "^2.0.1",
-            "to-object-path": "^0.3.0"
-          }
-        }
+        "set-value": "^2.0.1"
       }
     },
     "unique-filename": {