Пример #1
0
 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;
 }
Пример #3
0
        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;
        }