private void SetContent(CharacterBuffer buffer, string literal, int start) { var ignoreWhiteSpace = GetIgnoreWhiteSpace(buffer); if (this.IsValid || this.Type == GroupType.Named || this.Type == GroupType.Numbered || this.Type == GroupType.Balancing) { this.Content = new SubExpression(literal, start, ignoreWhiteSpace, buffer.IsEcma); } }
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(); }
public void Add(SubExpression expression) { this.Expressions.Add(expression); }
private void HandleAlternatives(CharacterBuffer charBuffer) { if (this.alternatives.Count != 0) { SubExpression alternative = new SubExpression(this.Clone()); alternative.Exp.alternatives = new Alternatives(); alternative.Start = charBuffer.Offset; alternative.End = charBuffer.IndexInOriginalBuffer; alternative.Literal = charBuffer.Substring(0, charBuffer.CurrentIndex); this.alternatives.Add(alternative); this.alternatives.Start = 0; this.alternatives.End = charBuffer.IndexInOriginalBuffer; } }
public Expression Stringify() { if (this.alternatives.Count != 0) { return this; } Expression expression = new Expression(); SubExpression end = null; bool flag = true; foreach (Element element in this) { string name = element.GetType().Name; if ((name == "Character" || name == "SpecialCharacter" || name == "Backreference" ? false : name != "NamedClass")) { if (!flag) { expression.Add(end); flag = true; } expression.Add(element); } else if (!flag) { end.Exp.Add(element); end.End = element.End; Expression exp = end.Exp; exp.Literal = string.Concat(exp.Literal, element.Literal); SubExpression subExpression = end; subExpression.Literal = string.Concat(subExpression.Literal, element.Literal); } else { end = new SubExpression(); end.Exp.Add(element); end.Start = element.Start; end.End = element.End; end.Exp.Literal = element.Literal; end.Literal = element.Literal; flag = false; } } if (!flag) { expression.Add(end); } return expression; }
public void Parse(int offset, bool skipFirstCaptureNumber) { Character character; CharacterBuffer charBuffer = new CharacterBuffer(Literal) { Offset = offset, IgnoreWhiteSpace = IgnoreWhitespace, IsEcma = IsEcma }; //Label2: while (!charBuffer.IsAtEnd) { int indexInOriginalBuffer = charBuffer.IndexInOriginalBuffer; HandleWhiteSpace(charBuffer, indexInOriginalBuffer); if (charBuffer.IsAtEnd) break; // Exit the loop char current = charBuffer.CurrentCharacter; if (current > Characters.Dot) { if (current == Characters.QuestionMark) { //goto Label0; AddMisplacedQuantifier(charBuffer); continue; // was goto Label2; } switch (current) { case Characters.SquareBracketOpen: { this.Add(new CharacterClass(charBuffer)); continue; // Move to next iteration } case Characters.BackSlash: { if (!SpecialCharacter.NextIsWhitespace(charBuffer)) { BackReference backReference = new BackReference(); if (!backReference.Parse(charBuffer)) { NamedClass namedClass = new NamedClass(); if (!namedClass.Parse(charBuffer)) { this.Add(new SpecialCharacter(charBuffer)); continue; // Move to next iteration } else { this.Add(namedClass); continue; // Move to next iteration } } else { BackReference.NeedsSecondPass = true; if (!backReference.IsOctal) { this.Add(backReference); continue; // Move to next iteration } else { this.Add(new SpecialCharacter(backReference)); continue; // Move to next iteration } } } else { this.Add(new SpecialCharacter(charBuffer)); continue; // Move to next iteration } } case Characters.SquareBracketClosed: { break; } case Characters.CircumflexAccent: { //goto Label1; AddSpecialCharacter(charBuffer); continue; // was goto Label2; } default: { switch (current) { case Characters.CurlyBraceOpen: { character = new Character(charBuffer, true) { //Description = string.Concat(character.Literal, " Misplaced quantifier"), IsValid = false }; character.Description = string.Concat(character.Literal, " Misplaced quantifier"); if (character.RepeatType != Repeat.Once) { this.Add(character); continue; } else { this.Add(new Character(charBuffer)); continue; } } case Characters.Pipe: { SubExpression subExpression = new SubExpression(this.Clone()) { Literal = charBuffer.Substring(0, charBuffer.CurrentIndex), Start = charBuffer.Offset, End = charBuffer.IndexInOriginalBuffer }; this.alternatives.Add(subExpression); charBuffer.MoveNext(); int num = charBuffer.IndexInOriginalBuffer; charBuffer = new CharacterBuffer(charBuffer.GetToEnd()) { Offset = num, IgnoreWhiteSpace = IgnoreWhitespace, IsEcma = IsEcma }; this.Clear(); continue; } } break; } } } else { switch (current) { case '\t': case '\n': case '\r': { //goto Label1; AddSpecialCharacter(charBuffer); continue; // was goto Label2; } case '\v': case '\f': { break; } default: { switch (current) { case ' ': case '$': case '.': { //goto Label1; AddSpecialCharacter(charBuffer); continue; // was goto Label2; } case '#': { if (!this.IgnoreWhitespace) { this.Add(new Character(charBuffer)); continue; } else { this.Add(new Comment(charBuffer)); continue; } } case '(': { Conditional conditional = new Conditional(); if (!conditional.Parse(charBuffer)) { Group group = new Group(charBuffer, skipFirstCaptureNumber); if (group.Type == GroupType.OptionsOutside) { if (group.SetX == CheckState.Checked) { this.IgnoreWhitespace = true; } else if (group.SetX == CheckState.Unchecked) { this.IgnoreWhitespace = false; } charBuffer.IgnoreWhiteSpace = this.IgnoreWhitespace; } this.Add(group); continue; } else { this.Add(conditional); BackReference.NeedsSecondPass = true; continue; } } case Characters.BracketClosed: { character = new Character(charBuffer) { IsValid = false, Description = "Unbalanced parenthesis" }; this.Add(character); continue; // Move to next character } case Characters.Star: case Characters.Plus: { //goto Label0; AddMisplacedQuantifier(charBuffer); continue; // was goto Label2; } } break; } } } Add(new Character(charBuffer)); } HandleAlternatives(charBuffer); //Label0: // AddMisplacedQuantifier(charBuffer); // goto Label2; //Label1: // AddSpecialCharacter(charBuffer); // goto Label2; }