Преглед изворни кода

MPIDE-27: fix breakage in code block parsing

The parser did not account for two particular cases within the code
blocks: unmatched braces (as in strings) and multiple blocks at the same
level (as in if-else statements). It now accounts for templated, double-
and single-quoted strings and sibling blocks.
Austin Meagher пре 10 година
родитељ
комит
65b73f6437
2 измењених фајлова са 20 додато и 2 уклоњено
  1. 12 2
      src/lib/parser/modellang.pegjs
  2. 8 0
      src/lib/parser/test/parser.js

+ 12 - 2
src/lib/parser/modellang.pegjs

@@ -317,8 +317,18 @@ init "Init Block"
     { return new ast.Init(system, body); }
 
 code_block
-    = [^{}]* ( "{" code_block "}" )? [^{}]*
+    = code_text ( "{" code_block "}" ) code_block?
     { return text().trim(); }
+    / code_text
+    { return text().trim(); }
+
+code_text
+    = ( string / [^{}] )* { return text(); }
+
+string
+    = ["] [^"]* ["] { return text(); }
+    / ['] [^']* ['] { return text(); }
+    / [`] [^`]* [`] { return text(); }
 
 behavior_id = id:ID { return id; }
 system_id   = id:ID { return id; }
@@ -358,7 +368,7 @@ _PIPE_         = _ t:"|" _            { return t; }
 _COLON_        = _ t:":" _            { return t; }
 _SEMI_         = _ t:";" _            { return t; }
 
-ID "Identifier"	/*TODO: UNICODE?*/
+ID "Identifier"    /*TODO: UNICODE?*/
     = !KEYWORD [A-Za-z] [a-zA-Z0-9_]*
     { return text(); }
 

+ 8 - 0
src/lib/parser/test/parser.js

@@ -155,6 +155,14 @@ describe("Parser", function() {
 			assert.equal(output.errors.length, 4);
 		});
 
+		it("should not break on braces in code blocks", function() {
+			let input = "SYSTEM: a = b c; WHEN: a:b {'{'\"}\"`}`}; WHEN: a:c {if(a){1}else{2}};";
+			let output = Parser.parse(input, {}, parseOpts);
+
+			assert.equal(output.triggers.length, 2);
+			assert.equal(output.errors.length, 0);
+		});
+
 		it("should ignore comments", function() {
 			let input = "// line comment\n/*block comment\n*/SYSTEM: a = b;";
 			let output = Parser.parse(input, {}, parseOpts);