/// <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()); }
/// <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); } } }
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; } }
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; } }
private static bool ReadListSeparator(SimpleParser parser) { parser.SkipSpaces(); return parser.ReadChar(','); }
/// <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; }