public void Accept1() { int level = 1; string name = "FOO"; string patt = "9V99"; BcProgram program = BackDoor.Parse( X.A(X.D(X.DA_DIV)), X.A(X.PIC(level, name, patt)), X.A(X.D(X.PR_DIV)), X.B(X.ACCEPT(name)) ); Assert.IsNotNull(program); Assert.AreEqual(0, program.Identifications.Count); Assert.AreEqual(1, program.Data.Count); ValidateDataField(program.Data[0], level, name, patt); Assert.AreEqual(1, program.Paragraphs.Count); var paraname = program.Paragraphs.Keys.First(); Assert.AreEqual("", paraname); Assert.AreEqual(1, program.Paragraphs[paraname].Sentences.Count); Assert.AreEqual(1, program.Paragraphs[paraname].Sentences[0].Statements.Count); var stmt = program.Paragraphs[paraname].Sentences[0].Statements[0] as BcAccept; Assert.IsNotNull(stmt); Assert.AreEqual(1, stmt.Accepted.Count); Assert.AreEqual(name, stmt.Accepted[0].Name); }
public void EmptyProgram() { string input = String.Empty; BcProgram program = BackDoor.Parse( X.A(X.D(X.ID_DIV)) ); Assert.IsNotNull(program); Assert.AreEqual(0, program.Identifications.Count); Assert.AreEqual(0, program.Paragraphs.Count); }
public void TopLevelPicName() { int level = 1; string name = "PICTUREISCOOL"; string patt = "X(20)"; BcProgram program = BackDoor.Parse( X.A(X.D(X.DA_DIV)), X.A(X.PIC(level, name, patt)) ); Assert.IsNotNull(program); Assert.AreEqual(0, program.Identifications.Count); Assert.AreEqual(1, program.Data.Count); X.ValidateDataField(program.Data[0], level, name, patt); }
public void TopLevelLike() { int level = 3; string name1 = "FOO", name2 = "BAR"; string patt = "X(20)"; BcProgram program = BackDoor.Parse( X.A(X.D(X.DA_DIV)), X.A(X.PIC(level, name1, patt)), X.A(X.LIKE(level, name2, name1)) ); Assert.IsNotNull(program); Assert.AreEqual(0, program.Identifications.Count); Assert.AreEqual(2, program.Data.Count); X.ValidateDataField(program.Data[0], level, name1, patt); X.ValidateDataField(program.Data[1], level, name2, patt); }
public void TopLevelPicLike() { int level = 3; string name1 = "LY"; string patt1 = "S9(10)V9(2)"; BcProgram program = BackDoor.Parse( X.A(X.D(X.DA_DIV)), X.A(X.PIC(level, name1, patt1)), X.A("03 UNLIKELY.") // should be perceived as UN LIKE LY where LY is a PIC above ); Assert.IsNotNull(program); Assert.AreEqual(0, program.Identifications.Count); Assert.AreEqual(2, program.Data.Count); X.ValidateDataField(program.Data[0], level, name1, patt1); X.ValidateDataField(program.Data[1], level, "UN", patt1); }
public void OneClaimBoolean() { string claim = "AUTHOR-is-grammarware"; string input = String.Empty; BcProgram program = BackDoor.Parse( X.A(X.D(X.ID_DIV)), X.B(X.D(claim)) ); Assert.IsNotNull(program); Assert.AreEqual(1, program.Identifications.Count); string k = program.Identifications.Keys.First(); Assert.AreEqual(claim, k); Assert.AreEqual("", program.Identifications[k]); Assert.AreEqual(0, program.Paragraphs.Count); }
public void OneClaimManyDots() { string claim1 = "AUTHOR"; string claim2 = "g.r.a.m.m.a.r.w.a.r.e"; string input = String.Empty; BcProgram program = BackDoor.Parse( X.A(X.D(X.ID_DIV)), X.B(X.D(claim1) + X.D(claim2)) ); Assert.IsNotNull(program); Assert.AreEqual(1, program.Identifications.Count); string k = program.Identifications.Keys.First(); Assert.AreEqual(claim1, k); Assert.AreEqual(claim2, program.Identifications[k]); Assert.AreEqual(0, program.Paragraphs.Count); }
public void NestedPicName2() { int level1 = 1, level2 = 5; string name1 = "UNLIKELY", name2 = "FOO"; string patt = "99999V999"; BcProgram program = BackDoor.Parse( X.A(X.D(X.DA_DIV)), X.A(X.VIEW(level1, name1)), X.B(X.PIC(level2, name2, patt)) ); Assert.IsNotNull(program); Assert.AreEqual(0, program.Identifications.Count); Assert.AreEqual(1, program.Data.Count); var view = program.Data[0] as BcDataView; Assert.IsNotNull(view); Assert.AreEqual(level1, view.Level); Assert.AreEqual(name1, view.Name); Assert.AreEqual(1, view.Inners.Count); X.ValidateDataField(view.Inners[0], level2, name2, patt); }
internal static BcProgram Parse(List <LineOfCode> lines) { BcProgram prg = new BcProgram(); if (lines == null || lines.Count == 0) { return(prg); } int index = 0; // IDENTIFICATION DIVISION if (IsZoneAExact(lines[index], IDENTIFICATION_DIVISION)) { // parse the entire division as key-value pairs index++; int dot1, dot2; string key, val; while (index < lines.Count && IsZoneB(lines[index])) { dot1 = lines[index].Content.IndexOf('.'); dot2 = lines[index].Content.LastIndexOf('.'); if (dot1 < 0 || (dot1 != dot2 && dot2 != lines[index].Content.Length - 1)) { Logger.ErrorIdDivClauseBug(lines[index].Line, lines[index].Content); } key = lines[index].Content.Substring(0, dot1).Trim(); if (dot1 == dot2) { val = String.Empty; } else { val = lines[index].Content.Substring(dot1 + 1, dot2 - dot1 - 1).Trim(); } if (prg.Identifications.ContainsKey(key)) { Logger.ErrorIdDivClauseDup(lines[index].Line, lines[index].Content); } prg.Identifications[key] = val; index++; } } // DATA DIVISION Dictionary <string, BcDataEntry> CachedData = new Dictionary <string, BcDataEntry>(); HashSet <string> Duplicates = new HashSet <string>(); if (index < lines.Count && IsZoneAExact(lines[index], DATA_DIVISION)) { index++; // there is a data division while (index < lines.Count && !IsZoneAExact(lines[index], PROCEDURE_DIVISION)) { string val = lines[index].Content.Replace(" ", ""); if (val[val.Length - 1] == '.') { val = val.Substring(0, val.Length - 1); } uint lineNo = lines[index].Line; int level = GetIntOrComplain(lineNo, val.Substring(0, 2), Logger.ErrorDataDivWrongLevel); int occurs = 1; // OCCURS int occursPos = val.IndexOf(OCCURS); if (occursPos >= 0) { occurs = GetIntOrComplain(lineNo, val.Substring(occursPos + OCCURS.Length), Logger.ErrorDataDivWrongOccurs); val = val.Substring(0, occursPos); } // PICTURE int picPos = val.LastIndexOf(PICTURE); // using last index to avoid problems where PICTURE is a (part of) the name if (picPos >= 0) { string pat = val.Substring(picPos + PICTURE.Length); BcDataEntry f = new BcDataField(level, val.Substring(2, picPos - 2), pat); RememberFieldType(f, CachedData, Duplicates); ConnectField(prg.Data, f, lineNo, level, occurs); index++; continue; } // LIKE int lastLikePos = val.LastIndexOf(LIKE); if (lastLikePos >= 0) { bool done = false; int curLikePos = -LIKE.Length; string s1, s2; while (!done && curLikePos < lastLikePos) { curLikePos = val.IndexOf(LIKE, curLikePos + LIKE.Length); s1 = val.Substring(2, curLikePos - 2); s2 = val.Substring(curLikePos + LIKE.Length); if (CachedData.ContainsKey(s2)) { BcDataEntry f = CachedData[s2].Like(); f.Level = level; f.Name = s1; RememberFieldType(f, CachedData, Duplicates); ConnectField(prg.Data, f, lineNo, level, occurs); done = true; } } if (done) { index++; continue; } } // nothing var v = new BcDataView(level, val.Substring(2)); RememberFieldType(v, CachedData, Duplicates); ConnectField(prg.Data, v, lineNo, level, occurs); index++; } } // PROCEDURE DIVISION if (index < lines.Count && IsZoneAExact(lines[index], PROCEDURE_DIVISION)) { index++; var currParaName = ""; var currParaCode = new BcBlock(); var currSentence = new BcSentence(); // there is a procedure division while (index < lines.Count) { var tokens = Tokenise(lines[index]); for (int i = 0; i < tokens.Count; i++) { if (tokens[i] is EOPToken tokenP) { if (currSentence.Statements.Count > 0) { currParaCode.Sentences.Add(currSentence); currSentence = new BcSentence(); } if (currParaCode.Sentences.Count > 0) { prg.Paragraphs.Add(currParaName, currParaCode); currParaCode = new BcBlock(); if (i + 2 < tokens.Count && tokens[i + 1] is UnquotedToken tokenPU && tokens[i + 2] is EOSToken) { currParaName = tokenPU.Value; i += 2; } else { currParaName = ""; } } } else if (tokens[i] is EOSToken tokenS) { if (currSentence.Statements.Count > 0) { currParaCode.Sentences.Add(currSentence); currSentence = new BcSentence(); } } else if (tokens[i] is QuotedToken tokenQ) { Logger.ErrorStrayQuoted(tokenQ); } else if (tokens[i] is UnquotedToken tokenU) { if (tokenU.Value.StartsWith(ACCEPT)) { // TODO cover all possible arguments, now it accepts only one trivial identifier var acc = new BcAccept(); var name = tokenU.Value.Substring(ACCEPT.Length); acc.Accepted.Add(new BcIdRef(name)); currSentence.Statements.Add(acc); } else { Logger.ErrorNotImplementedYet(tokenU.Row, tokenU.Col, tokenU.Value); } } else { Logger.ErrorUnrecognisedToken(tokens[i]); } }