Ejemplo n.º 1
0
            private string ReadName(SimpleParser parser)
            {
                using (var la = parser.LookAround())
                {
                    if (!parser.ReadChar('_') &&
                        !parser.ReadChar(UnicodeCategory.LowercaseLetter) &&
                        !parser.ReadChar(UnicodeCategory.UppercaseLetter))
                    {
                        return(null);
                    }

                    parser.ReadWhileCharOrEof(IsIdentifierChar);

                    la.Success();

                    return(la.Text);
                }
            }
Ejemplo n.º 2
0
 private static bool ReadListSeparator(SimpleParser parser)
 {
     parser.SkipSpaces();
     return(parser.ReadChar(','));
 }
Ejemplo n.º 3
0
 /// <summary>
 /// Reads the code using a SimpleParser object, and using a previously parsed result,
 /// and then returns a new object representing the result from parsing the current code.
 /// </summary>
 /// <param name="parser">The parser object used to read the code.</param>
 /// <param name="prevData">Previously parsed result. This is used to chain results together.</param>
 /// <returns>Returns an object that results from parsing the code.</returns>
 public abstract object Read(SimpleParser parser, object prevData);
Ejemplo n.º 4
0
            /// <summary>
            /// Reads the code trying to extract the AST from it.
            /// </summary>
            /// <param name="parser">The parser object used to read the code.</param>
            /// <param name="prevData">Previously parsed result. This is used to chain results together.</param>
            /// <returns>Returns an object that results from parsing the code.</returns>
            public override object Read(SimpleParser parser, object prevData)
            {
                var prevExecutor = prevData as INode;

                parser.SkipSpaces();

                if (prevData == null)
                {
                    var name = this.ReadName(parser);

                    // this is a direct method call in the root
                    var call = ReadMethodCall(parser, null, name);
                    if (call != null)
                    {
                        return(call);
                    }

                    // this is a global property
                    if (!string.IsNullOrWhiteSpace(name))
                    {
                        var typeReference = parser.StaticTypes.SingleOrDefault(t => t.Name == name);
                        if (typeReference != null)
                        {
                            return(typeReference);
                        }

                        return(new PropertyGet {
                            Name = name, Element = null
                        });
                    }

                    // this is an array construct
                    if (parser.ReadChar('{'))
                    {
                        var values = parser.ReadList <ValueBuilder, INode>(ReadListSeparator);
                        if (values.Count > 0)
                        {
                            parser.SkipSpaces();
                            if (!parser.ReadChar('}'))
                            {
                                return(new Exception("Unterminated array construct."));
                            }

                            return(new ArrayConstruct {
                                Values = values
                            });
                        }
                    }

                    // this is a precedence operator
                    if (parser.ReadChar('('))
                    {
                        var value = parser.Read <ValueBuilder, INode>();
                        if (value == null)
                        {
                            return(new Exception("Syntax error."));
                        }

                        parser.SkipSpaces();
                        if (!parser.ReadChar(')'))
                        {
                            return(new Exception("Unterminated precedence construct."));
                        }

                        return(value);
                    }

                    // this is a number literal
                    var number = parser.ReadWhileCharOrEof(char.IsNumber);
                    if (number.Length > 0)
                    {
                        return new NumberLiteral {
                                   Data = number
                        }
                    }
                    ;

                    // this is a string literal
                    if (parser.ReadChar('"'))
                    {
                        var strBuilder = new StringBuilder();

                        while (true)
                        {
                            strBuilder.Append(parser.ReadWhileCharOrEof(ch => ch != '\\' && ch != '"'));

                            if (parser.Eof)
                            {
                                return(new InvalidOperationException("String literal not terminated."));
                            }

                            if (parser.ReadChar('\\'))
                            {
                                if (parser.ReadChar('0'))
                                {
                                    strBuilder.Append('\0');
                                }
                                else if (parser.ReadChar('n'))
                                {
                                    strBuilder.Append('\n');
                                }
                                else if (parser.ReadChar('r'))
                                {
                                    strBuilder.Append('\r');
                                }
                                else if (parser.ReadChar('\\'))
                                {
                                    strBuilder.Append('\\');
                                }
                                else if (parser.ReadChar('"'))
                                {
                                    strBuilder.Append('"');
                                }
                                else
                                {
                                    return(new InvalidOperationException("Escape sequence not recognized."));
                                }
                            }

                            if (parser.ReadChar('"'))
                            {
                                break;
                            }
                        }

                        return(new StringLiteral {
                            Data = strBuilder.ToString()
                        });
                    }
                }
                else
                {
                    if (parser.ReadChar('.'))
                    {
                        var name = this.ReadName(parser);

                        // this is a direct method call in the previous element
                        var call = ReadMethodCall(parser, prevData, name);
                        if (call != null)
                        {
                            return(call);
                        }

                        if (!string.IsNullOrWhiteSpace(name))
                        {
                            return new PropertyGet {
                                       Name = name, Element = prevExecutor
                            }
                        }
                        ;
                    }

                    // indexer property
                    if (parser.ReadChar('['))
                    {
                        var indexValues = parser.ReadList <ValueBuilder, INode>(ReadListSeparator);

                        if (indexValues.Count == 0)
                        {
                            return(new Exception("Index is missing."));
                        }

                        parser.SkipSpaces();
                        if (!parser.ReadChar(']'))
                        {
                            return(new Exception("Unterminated indexer."));
                        }

                        return(new IndexerGet {
                            Element = prevExecutor, Indexes = indexValues
                        });
                    }

                    // this only happens when calling a delegate
                    // direct method calls never fall here
                    if (parser.ReadChar('('))
                    {
                        var paramValues = parser.ReadList <ValueBuilder, INode>(ReadListSeparator);

                        parser.SkipSpaces();
                        if (parser.ReadChar(')'))
                        {
                            return new Call {
                                       Element = prevExecutor, Name = "Invoke", Parameters = paramValues
                            }
                        }
                        ;
                    }

                    if (parser.ReadChar('?'))
                    {
                        var trueValue = parser.Read <ValueBuilder, INode>();
                        parser.SkipSpaces();
                        if (!parser.ReadChar(':'))
                        {
                            throw new Exception("Missing ':' for ternary operator a?b:c.");
                        }
                        parser.SkipSpaces();
                        var falseValue = parser.Read <ValueBuilder, INode>();

                        return(new TernaryInlineIf {
                            Condition = prevExecutor, TrueValue = trueValue, FalseValue = falseValue
                        });
                    }

                    var binOp = parser.ReadAnyStringAlternative("==", "!=", ">", "<", ">=", "<=", "&&", "||");
                    if (binOp != null)
                    {
                        var valueB = parser.Read <ValueBuilder, INode>();

                        return(new BinaryBoolOps {
                            ValueA = prevExecutor, ValueB = valueB, Operator = binOp
                        });
                    }
                }

                return(null);
            }
Ejemplo n.º 5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="LookAroundDisposer"/> class.
 /// </summary>
 /// <param name="parser">
 /// The SimpleParser object that should be reverted to the current state, if the parsing block fails.
 /// </param>
 public LookAroundDisposer(SimpleParser parser)
 {
     this.parser      = parser;
     this.oldPosition = parser.Position;
 }