/// <summary> /// Attempts to parse an LSL list from a string and returns true if the parse succeeded. /// </summary> /// <param name="list">The string containing the list.</param> /// <param name="expressions"> /// The resulting expression list will be put at this location if the parse succeeded, otherwise /// it will be <c>null</c>. /// </param> /// <param name="parsingFlags">Optional parsing flags.</param> /// <returns><c>true</c> if the string representation of the LSL list was successfully parsed; otherwise <c>false</c>.</returns> public static bool TryParseList(string list, out List <ILSLListExpr> expressions, LSLListParsingFlags parsingFlags = LSLListParsingFlags.None) { try { expressions = ParseList(list, parsingFlags).ToList(); return(true); } catch (LSLListParserSyntaxException) { expressions = null; return(false); } }
private static ILSLListExpr ListExpressionFromRotation(LSLListParsingFlags parsingFlags, LSLParser.Expr_AtomContext atomToken) { object[] rotComponents = { atomToken.rotation_literal.rotation_x, atomToken.rotation_literal.rotation_y, atomToken.rotation_literal.rotation_z, atomToken.rotation_literal.rotation_s }; for (int i = 0; i < rotComponents.Length; i++) { var atom = rotComponents[i] as LSLParser.Expr_AtomContext; var prefix = rotComponents[i] as LSLParser.Expr_PrefixOperationContext; if (atom != null) { if (atom.float_literal != null || atom.integer_literal != null || atom.hex_literal != null) { rotComponents[i] = BasicAtomToExpr(atom); } else if (atom.variable != null) { if ((parsingFlags & LSLListParsingFlags.AllowVariableReferencesInRotations) == LSLListParsingFlags.AllowVariableReferencesInRotations) { rotComponents[i] = new LSLListVariableExpr(atomToken.GetText()); } throw new LSLListParserOptionsConstraintException( "Variable references are not allowed in Rotation literals."); } else { goto throw_type_error; } } else if (prefix != null) { var floatOrInt = prefix.expr_rvalue as LSLParser.Expr_AtomContext; var operation = prefix.operation.Text; var validType = floatOrInt != null && (floatOrInt.float_literal != null || floatOrInt.integer_literal != null); if (validType && (operation == "-" || operation == "+")) { rotComponents[i] = BasicAtomToExpr(floatOrInt, operation); } else { throw new LSLListParserSyntaxException( string.Format( "The Negative and Positive prefix operator can only be used on Floats and Integers inside of a Rotation, operator '{0}' is not valid.", operation)); } } else { goto throw_type_error; } continue; throw_type_error: throw new LSLListParserSyntaxException( "Rotations must contain only Float and Integer literal values."); } return(new LSLListRotationExpr((ILSLListExpr)rotComponents[0], (ILSLListExpr)rotComponents[1], (ILSLListExpr)rotComponents[2], (ILSLListExpr)rotComponents[3])); }
/// <summary> /// Parses an LSL list from a string and returns the simple expressions it contains as an enumerable. /// <remarks> /// Take note that parsing wont start to occur until you begin enumerating the returned value. /// </remarks> /// </summary> /// <param name="list">The string containing the list.</param> /// <param name="parsingFlags">Optional parsing flags.</param> /// <returns>An enumerable of <see cref="ILSLListExpr"/> nodes parsed from the list string.</returns> /// <exception cref="LSLListParserOptionsConstraintException"> /// When an /// <see cref="LSLListParsingFlags" /> constraint is violated. /// </exception> /// <exception cref="LSLListParserSyntaxException"> /// Rotations must contain only literal values to be parsed, and cannot contain these types of expressions: rotations, /// vectors, lists or strings. /// or /// Vectors must contain only literal values to be parsed, and cannot contain these types of expressions: rotations, /// vectors, lists or strings. /// or /// Lists cannot contain other lists. /// or /// Cast expressions can only be used to specify that a list element is a 'key' and not a 'string' /// or /// Encountered an un-parseable expression in the list, only literal values and possibly variable names are acceptable /// when parsing. /// </exception> public static IEnumerable <ILSLListExpr> ParseList(string list, LSLListParsingFlags parsingFlags = LSLListParsingFlags.None) { var strm = new AntlrInputStream(new StringReader(list)); var lex = new LSLLexer(strm); var parse = new LSLParser(new CommonTokenStream(lex)); parse.ErrorListeners.Clear(); lex.ErrorListeners.Clear(); var errorListener = new ErrorListener(); parse.AddErrorListener(errorListener); parse.AddErrorListener(errorListener); var production = parse.listLiteral(); if (production.expression_list == null) { throw new LSLListParserSyntaxException("List rule missing expression list, parsing error"); } var listProduction = production.expression_list.expressionList(); if (listProduction == null) { yield break; } foreach (var child in EnumerateExpressionList(listProduction)) { var atomToken = child as LSLParser.Expr_AtomContext; var castExpression = child as LSLParser.Expr_TypeCastContext; var negateOrPositive = child as LSLParser.Expr_PrefixOperationContext; if (atomToken != null) { var maybeBasic = BasicAtomToExpr(atomToken); if (maybeBasic != null) { yield return(maybeBasic); } if (atomToken.variable != null) { if ((parsingFlags & LSLListParsingFlags.AllowVariableReferencesInList) == LSLListParsingFlags.AllowVariableReferencesInList) { yield return(new LSLListStringExpr(atomToken.GetText())); } else { throw new LSLListParserOptionsConstraintException( "Variable references are not allowed in the list."); } } if (atomToken.rotation_literal != null) { yield return(ListExpressionFromRotation(parsingFlags, atomToken)); } if (atomToken.vector_literal != null) { yield return(ListExpressionFromVector(parsingFlags, atomToken)); } if (atomToken.list_literal != null) { throw new LSLListParserSyntaxException("Lists cannot contain other lists."); } } else if (castExpression != null) { var stringLiteral = castExpression.expr_rvalue as LSLParser.Expr_AtomContext; if (stringLiteral != null && stringLiteral.string_literal != null && castExpression.cast_type.Text == "key") { yield return(new LSLListKeyExpr(stringLiteral.GetText())); } else { throw new LSLListParserSyntaxException( "Cast expressions can only be used to specify that a list element is a 'key' and not a 'string'"); } } else if (negateOrPositive != null) { var floatOrInt = negateOrPositive.expr_rvalue as LSLParser.Expr_AtomContext; var operation = negateOrPositive.operation.Text; var validType = floatOrInt != null && (floatOrInt.float_literal != null || floatOrInt.integer_literal != null); if (validType && operation == "-" || operation == "+") { yield return(BasicAtomToExpr(floatOrInt, operation)); } else { throw new LSLListParserSyntaxException( string.Format( "The Negative and Positive prefix operator can only be used on Floats and Integer list elements, operator '{0}' is not valid.", operation)); } } else { throw new LSLListParserSyntaxException( "Encountered an un-parseable expression in the list, only LSL literals and possibly variable names are acceptable list elements."); } } }