/// <summary>
        /// Parse a value.
        /// </summary>
        ///
        /// <param name="parser">The parser to use.</param>
        /// <returns>The newly parsed value.</returns>
        private static String ParseValue(SimpleParser parser)
        {
            bool quoted = false;
            var  str    = new StringBuilder();

            parser.EatWhiteSpace();

            if (parser.Peek() == '\"')
            {
                quoted = true;
                parser.Advance();
            }

            while (!parser.EOL())
            {
                if (parser.Peek() == '\"')
                {
                    if (quoted)
                    {
                        parser.Advance();
                        if (parser.Peek() == '\"')
                        {
                            str.Append(parser.ReadChar());
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        str.Append(parser.ReadChar());
                    }
                }
                else if (!quoted &&
                         (parser.IsWhiteSpace() || (parser.Peek() == ',')))
                {
                    break;
                }
                else
                {
                    str.Append(parser.ReadChar());
                }
            }
            return(str.ToString());
        }
        /// <summary>
        /// Parse a name.
        /// </summary>
        ///
        /// <param name="parser">The parser to use.</param>
        /// <returns>The name.</returns>
        private static String ParseName(SimpleParser parser)
        {
            var result = new StringBuilder();

            parser.EatWhiteSpace();
            while (parser.IsIdentifier())
            {
                result.Append(parser.ReadChar());
            }
            return(result.ToString());
        }
Пример #3
0
        /// <summary>
        ///     Read the specified parameter.
        /// </summary>
        /// <param name="parser">The parser to use.</param>
        /// <returns>The parsed parameter.</returns>
        private ParamTemplate ReadParam(SimpleParser parser)
        {
            var result = new ParamTemplate();

            if (!parser.LookAhead("{", true))
            {
                throw new EACompileError("Expected {");
            }
            parser.Advance();

            bool done   = false;
            var  buffer = new StringBuilder();

            while (!done)
            {
                if (parser.Peek() == '}')
                {
                    done = true;
                    parser.Advance();
                }
                else if (parser.Peek() == '{')
                {
                    throw new EACompileError("Unexpected {");
                }
                else if (parser.Peek() == '{')
                {
                    done = true;
                    parser.Advance();
                }
                else if (parser.Peek() == ',')
                {
                    result.AddType(buffer.ToString().Trim().ToLower());
                    parser.Advance();
                    buffer.Length = 0;
                }
                else
                {
                    buffer.Append(parser.ReadChar());
                }
            }

            String s = buffer.ToString().Trim();

            if (s.Length > 0)
            {
                result.AddType(s);
            }

            return(result);
        }
        /// <summary>
        /// Add events, as they are pased.
        /// </summary>
        /// <param name="parser">The parser.</param>
        /// <param name="results">The events found.</param>
        /// <param name="delim">The delimiter to use.</param>
        private void AddEvents(SimpleParser parser, IList <ParsedEvent> results, String delim)
        {
            bool          done = false;
            StringBuilder l    = new StringBuilder();

            while (!done && !parser.EOL())
            {
                char ch = parser.Peek();
                if (delim.IndexOf(ch) != -1)
                {
                    if (ch == ')' || ch == '|')
                    {
                        done = true;
                    }

                    ParsedEvent parsedEvent;

                    // deal with a value specified by + or -
                    if (l.Length > 0 && l[0] == '+')
                    {
                        String l2 = l.ToString().Substring(1);
                        parsedEvent       = new ParsedEvent(l2.Trim());
                        parsedEvent.Value = "true";
                    }
                    else if (l.Length > 0 && l[0] == '-')
                    {
                        String l2 = l.ToString().Substring(1);
                        parsedEvent       = new ParsedEvent(l2.Trim());
                        parsedEvent.Value = "false";
                    }
                    else
                    {
                        String l2 = l.ToString();
                        parsedEvent = new ParsedEvent(l2.Trim());
                    }

                    // parse choices
                    if (ch == '[')
                    {
                        parser.Advance();
                        int index = 0;
                        while (ch != ']' && !parser.EOL())
                        {
                            String labelName = parser.ReadToChars(":,]");
                            if (parser.Peek() == ':')
                            {
                                parser.Advance();
                                parser.EatWhiteSpace();
                                double min = double.Parse(parser.ReadToWhiteSpace());
                                parser.EatWhiteSpace();
                                if (!parser.LookAhead("to", true))
                                {
                                    throw new BayesianError("Expected \"to\" in probability choice range.");
                                }
                                parser.Advance(2);
                                double max = CSVFormat.EgFormat.Parse(parser.ReadToChars(",]"));
                                parsedEvent.ChoiceList.Add(new ParsedChoice(labelName, min, max));
                            }
                            else
                            {
                                parsedEvent.ChoiceList.Add(new ParsedChoice(labelName, index++));
                            }
                            parser.EatWhiteSpace();
                            ch = parser.Peek();

                            if (ch == ',')
                            {
                                parser.Advance();
                            }
                        }
                    }

                    // deal with a value specified by =
                    if (parser.Peek() == '=')
                    {
                        parser.ReadChar();
                        String value = parser.ReadToChars(delim);
                        //					BayesianEvent evt = this.network.getEvent(parsedEvent.getLabel());
                        parsedEvent.Value = value;
                    }

                    if (ch == ',')
                    {
                        parser.Advance();
                    }

                    if (ch == ']')
                    {
                        parser.Advance();
                    }

                    if (parsedEvent.Label.Length > 0)
                    {
                        results.Add(parsedEvent);
                    }
                    l.Length = 0;
                }
                else
                {
                    parser.Advance();
                    l.Append(ch);
                }
            }
        }
Пример #5
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;
                }
            }
Пример #6
0
            private static object ReadMethodCall(SimpleParser parser, object prevData, string name)
            {
                using (var la = parser.LookAround())
                {
                    parser.SkipSpaces();
                    if (parser.ReadChar('('))
                    {
                        var prevExecutor = (INode)prevData;
                        var type = prevData == null ? parser.GlobalType : prevExecutor.Compile(parser.GlobalType);
                        var isMethodGroup = type.GetMethods().Any(m => m.Name == name);
                        if (isMethodGroup)
                        {
                            var paramValues = parser.ReadList<ValueBuilder, INode>(ReadListSeparator);
                            if (paramValues.Count == 1 && paramValues[0] == null)
                                paramValues.Clear();

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

                    return null;
                }
            }
Пример #7
0
 private static bool ReadListSeparator(SimpleParser parser)
 {
     parser.SkipSpaces();
     return parser.ReadChar(',');
 }
Пример #8
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 = (INode)prevData;

                parser.SkipSpaces();

                if (prevExecutor == 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))
                        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, prevExecutor, 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;
            }