Beispiel #1
0
 /// <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);
     }
 }
Beispiel #2
0
        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]));
        }
Beispiel #3
0
        /// <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.");
                }
            }
        }