public bool Parse(CharacterBuffer buffer) { int num; this.Start = buffer.IndexInOriginalBuffer; if (buffer.IsAtEnd) { Utility.ParseError("Reached end of buffer looking for a conditional!", buffer); this.IsValid = false; return false; } this.Literal = buffer.GetStringToMatchingParenthesis(); Match match = this.ConditionalRegex.Match(this.Literal); if (!match.Success) { buffer.Move(1 - this.Literal.Length); return false; } var item = match.Groups["Expression"]; int start = this.Start + item.Index; string str = item.Value.Substring(1, item.Value.Length - 2); this.Name = str; this.expType = Conditional.ExpType.Expression; this.Exp = new SubExpression(item.Value, start, buffer.IgnoreWhiteSpace, buffer.IsEcma, true) { Start = start, End = this.Exp.Start + item.Length }; if (this.Exp.Exp[0] is Group) { Group group = (Group)this.Exp.Exp[0]; switch (group.Type) { case GroupType.Balancing: { group.Description = "Test condition cannot be a balancing group"; group.IsValid = false; this.IsValid = false; break; } case GroupType.Named: { group.Description = "Test condition cannot be a named group"; group.IsValid = false; this.IsValid = false; break; } case GroupType.Numbered: { if (BackReference.ContainsName(str)) { this.expType = Conditional.ExpType.NamedCapture; break; } else if (int.TryParse(str, out num)) { this.expType = Conditional.ExpType.NumberedCapture; if (BackReference.ContainsNumber(str)) { break; } this.expType = Conditional.ExpType.NonExistentNumber; group.IsValid = false; break; } else if (!this.AlphanumericRegex.Match(str).Success) { group.Description = "Match if prefix is present"; break; } else if (!char.IsDigit(str[0])) { this.expType = Conditional.ExpType.NonExistentName; break; } else { this.expType = Conditional.ExpType.InvalidName; group.IsValid = false; break; } } case GroupType.Noncapturing: case GroupType.Greedy: case GroupType.OptionsInside: case GroupType.OptionsOutside: { group.Description = "Test condition is"; break; } case GroupType.SuffixPresent: { group.Description = "Match if suffix is present"; break; } case GroupType.PrefixPresent: { group.Description = "Match if prefix is present"; break; } case GroupType.SuffixAbsent: { group.Description = "Match if suffix is absent"; break; } case GroupType.PrefixAbsent: { group.Description = "Match if prefix is absent"; break; } case GroupType.Comment: { group.Description = "Test condition cannot be a comment!"; group.IsValid = false; this.IsValid = false; break; } default: { goto case GroupType.OptionsOutside; } } group.Description = string.Concat(group.Description, " ", group.Literal); } else { this.expType = Conditional.ExpType.NotAGroup; } item = match.Groups["Contents"]; string value = item.Value; List<int> nums = (new CharacterBuffer(value)).FindNakedPipes(); start = this.Start + item.Index; switch (nums.Count) { case 0: { this.Yes = new SubExpression(value, start, buffer.IgnoreWhiteSpace, buffer.IsEcma) { Start = start, End = this.Yes.Start + item.Length }; this.Description = "Conditional Expression with \"Yes\" clause only"; break; } case 1: { int item1 = nums[0] + 1; this.Yes = new SubExpression(value.Substring(0, item1 - 1), start, buffer.IgnoreWhiteSpace, buffer.IsEcma) { Start = start, End = this.Yes.Start + item1 - 1 }; start = this.Yes.Start + item1; this.No = new SubExpression(value.Substring(item1), start, buffer.IgnoreWhiteSpace, buffer.IsEcma) { Start = start, End = this.Yes.Start + item.Length }; this.Description = "Conditional Expression with \"Yes\" and \"No\" clause"; break; } default: { this.Yes = new SubExpression(value, start, buffer.IgnoreWhiteSpace, buffer.IsEcma) { Start = start, End = this.Yes.Start + item.Length }; this.Description = "Too many | symbols in a conditional expression"; this.IsValid = false; break; } } buffer.MoveNext(); base.ParseRepetitions(buffer); return true; }
public Group(CharacterBuffer buffer, bool SkipCaptureNumber) { char literal; char chr; int num; bool flag; bool flag1; //this.Image = ImageType.Group; this.Start = buffer.IndexInOriginalBuffer; bool needToParseRepititions = true; this.Literal = buffer.GetStringToMatchingParenthesis(); if (this.Literal == "") { return; } Match match = Group.RegGroup.Match(this.Literal); if (!match.Success) { this.Type = GroupType.Invalid; this.Content = new SubExpression("", 0, false, false); this.IsValid = false; needToParseRepititions = false; this.Description = "Syntax error in group definition"; buffer.Move(1 - this.Literal.Length); } else { string value = match.Groups["GroupType"].Value; string str = match.Groups["Name"].Value; string value1 = match.Groups["Number"].Value; string str1 = match.Groups["Options"].Value; string value2 = match.Groups["Contents"].Value; int start = this.Start + match.Groups["Contents"].Index; this.Name2 = match.Groups["Name2"].Value; if (str1 == "") { string str2 = value; string str3 = str2; if (str2 != null) { switch (str3) { case ":": { this.Type = GroupType.Noncapturing; goto Label0; } case "=": { this.Type = GroupType.SuffixPresent; goto Label0; } case "<=": { this.Type = GroupType.PrefixPresent; goto Label0; } case "<!": { this.Type = GroupType.PrefixAbsent; goto Label0; } case "!": { this.Type = GroupType.SuffixAbsent; goto Label0; } case "#": { this.Type = GroupType.Comment; needToParseRepititions = false; goto Label0; } case ">": { this.Type = GroupType.Greedy; goto Label0; } case "(": { this.Type = GroupType.Invalid; this.Content = new SubExpression("", 0, false, false); this.IsValid = false; this.Description = "Syntax error in group definition"; needToParseRepititions = false; buffer.Move(1 - this.Literal.Length); goto Label0; } case "": { if (value2.Length <= 0 || !(value2.Substring(0, 1) == "?")) { this.Type = GroupType.Numbered; if (SkipCaptureNumber) { this.Name = ""; goto Label0; } else { this.Name = BackReference.AddNumber().ToString(); goto Label0; } } else { this.Type = GroupType.Invalid; value2 = value2.Substring(1); this.Content = new SubExpression(value2, start + 1, buffer.IgnoreWhiteSpace, buffer.IsEcma); this.Description = "Illegal group syntax"; this.IsValid = false; goto Label0; } } case "-": { int index = match.Groups["Name"].Index - 1; int index1 = match.Groups["Name2"].Index + match.Groups["Name2"].Length; literal = this.Literal[index]; chr = this.Literal[index1]; if (literal != '<' || chr != '>') { flag1 = (literal != '\'' ? false : chr == '\''); } else { flag1 = true; } this.IsValid = flag1; if (!this.IsValid) { this.Description = "Invalid syntax for balancing group"; } this.Type = GroupType.Balancing; this.Name = str; if (this.Name != "") { if (!int.TryParse(this.Name, out num)) { BackReference.AddName(this.Name); } else { BackReference.AddNumber(num); } } if (!int.TryParse(this.Name2, out num)) { if (BackReference.ContainsName(this.Name2)) { goto Label0; } this.Description = string.Concat("Invalid group name in a balancing group: ", this.Name2); this.IsValid = false; goto Label0; } else { if (BackReference.ContainsNumber(this.Name2)) { goto Label0; } this.Description = string.Concat("Invalid group number in a balancing group: ", this.Name2); this.IsValid = false; goto Label0; } } } } literal = value[0]; chr = value[value.Length - 1]; if (literal != '<' || chr != '>') { flag = (literal != '\'' ? false : chr == '\''); } else { flag = true; } this.IsValid = flag; if (str.Length > 0) { this.Type = GroupType.Named; this.Name = str; BackReference.AddName(str); if (!this.IsValid) { this.Description = string.Concat("[", str, "] Invalid syntax for named group"); } } else if (value1.Length <= 0) { this.Type = GroupType.Named; this.Name = ""; this.IsValid = false; this.Description = "Missing name for a named group"; } else { this.Type = GroupType.Numbered; this.Name = value1; BackReference.AddNumber(int.Parse(value1)); if (!this.IsValid) { this.Description = string.Concat("[", value1, "] Invalid syntax for numbered group"); } } } else { this.DecodeOptions(str1); if (this.Type == GroupType.OptionsOutside) { needToParseRepititions = false; } } Label0: // TODO: Remove this and create proper logic! SetContent(buffer, value2, start); } buffer.MoveNext(); if (needToParseRepititions) { ParseRepetitions(buffer); } else { End = buffer.IndexInOriginalBuffer; RepeatType = Repeat.Once; } SetDescription(); }