Exemple #1
1
        protected IConceptInfo ParseNextConcept(TokenReader tokenReader, Stack<IConceptInfo> context, IEnumerable<IConceptParser> conceptParsers)
        {
            var errors = new List<ErrorContext>();
            List<Interpretation> possibleInterpretations = new List<Interpretation>();

            foreach (var conceptParser in conceptParsers)
            {
                TokenReader nextPosition = new TokenReader(tokenReader);
                var conceptInfoOrError = conceptParser.Parse(nextPosition, context);

                if (!conceptInfoOrError.IsError)
                    possibleInterpretations.Add(new Interpretation
                    {
                        ConceptInfo = conceptInfoOrError.Value,
                        NextPosition = nextPosition
                    });
                else if (!string.IsNullOrEmpty(conceptInfoOrError.Error)) // Empty error means that this parser is not for this keyword.
                    errors.Add(new ErrorContext
                    {
                        Error = conceptInfoOrError.Error,
                        Postion = tokenReader.CurrentPosition,
                        ParserName = conceptParser.GetType().Name,
                        DslSource = _dslSource
                    });
            }

            if (possibleInterpretations.Count == 0)
            {
                string msg = "Unrecognized concept. " + _dslSource.ReportError(tokenReader.CurrentPosition);
                if (errors.Count > 0)
                {
                    string listedErrors = string.Join("\r\n", errors);
                    if (listedErrors.Length > 500) listedErrors = listedErrors.Substring(0, 500) + "...";
                    msg = msg + "\r\n\r\nPossible causes:\r\n" + listedErrors;
                }
                throw new DslSyntaxException(msg);
            }

            int largest = possibleInterpretations.Max(i => i.NextPosition.PositionInTokenList);
            possibleInterpretations.RemoveAll(i => i.NextPosition.PositionInTokenList < largest);
            if (possibleInterpretations.Count > 1)
            {
                string msg = "Ambiguous syntax. " + _dslSource.ReportError(tokenReader.CurrentPosition)
                    + "\r\n Possible interpretations: "
                    + string.Join(", ", possibleInterpretations.Select(i => i.ConceptInfo.GetType().Name))
                    + ".";
                throw new DslSyntaxException(msg);
            }

            tokenReader.CopyFrom(possibleInterpretations.Single().NextPosition);
            return possibleInterpretations.Single().ConceptInfo;
        }
Exemple #2
0
        protected IConceptInfo ParseNextConcept(TokenReader tokenReader, Stack <IConceptInfo> context, IEnumerable <IConceptParser> conceptParsers)
        {
            var errors = new List <string>();
            List <Interpretation> possibleInterpretations = new List <Interpretation>();

            foreach (var conceptParser in conceptParsers)
            {
                TokenReader nextPosition       = new TokenReader(tokenReader);
                var         conceptInfoOrError = conceptParser.Parse(nextPosition, context);

                if (!conceptInfoOrError.IsError)
                {
                    possibleInterpretations.Add(new Interpretation
                    {
                        ConceptInfo  = conceptInfoOrError.Value,
                        NextPosition = nextPosition
                    });
                }
                else if (!string.IsNullOrEmpty(conceptInfoOrError.Error)) // Empty error means that this parser is not for this keyword.
                {
                    errors.Add(string.Format("{0}: {1}\r\n{2}", conceptParser.GetType().Name, conceptInfoOrError.Error, tokenReader.ReportPosition()));
                }
            }

            if (possibleInterpretations.Count == 0)
            {
                var    nextToken = new TokenReader(tokenReader).ReadText(); // Peek, without changing the original tokenReader's position.
                string keyword   = nextToken.IsError ? null : nextToken.Value;

                if (errors.Count > 0)
                {
                    string errorsReport = string.Join("\r\n", errors).Limit(500, "...");
                    throw new DslSyntaxException($"Invalid parameters after keyword '{keyword}'. {tokenReader.ReportPosition()}\r\n\r\nPossible causes:\r\n{errorsReport}");
                }
                else if (!string.IsNullOrEmpty(keyword))
                {
                    throw new DslSyntaxException($"Unrecognized concept keyword '{keyword}'. {tokenReader.ReportPosition()}");
                }
                else
                {
                    throw new DslSyntaxException($"Invalid DSL script syntax. {tokenReader.ReportPosition()}");
                }
            }

            int largest = possibleInterpretations.Max(i => i.NextPosition.PositionInTokenList);

            possibleInterpretations.RemoveAll(i => i.NextPosition.PositionInTokenList < largest);
            if (possibleInterpretations.Count > 1)
            {
                string msg = "Ambiguous syntax. " + tokenReader.ReportPosition()
                             + "\r\n Possible interpretations: "
                             + string.Join(", ", possibleInterpretations.Select(i => i.ConceptInfo.GetType().Name))
                             + ".";
                throw new DslSyntaxException(msg);
            }

            tokenReader.CopyFrom(possibleInterpretations.Single().NextPosition);
            return(possibleInterpretations.Single().ConceptInfo);
        }
Exemple #3
0
        protected IConceptInfo ParseNextConcept(TokenReader tokenReader, Stack <IConceptInfo> context, IEnumerable <IConceptParser> conceptParsers)
        {
            var errors = new List <string>();
            List <Interpretation> possibleInterpretations = new List <Interpretation>();

            foreach (var conceptParser in conceptParsers)
            {
                TokenReader nextPosition       = new TokenReader(tokenReader);
                var         conceptInfoOrError = conceptParser.Parse(nextPosition, context);

                if (!conceptInfoOrError.IsError)
                {
                    possibleInterpretations.Add(new Interpretation
                    {
                        ConceptInfo  = conceptInfoOrError.Value,
                        NextPosition = nextPosition
                    });
                }
                else if (!string.IsNullOrEmpty(conceptInfoOrError.Error)) // Empty error means that this parser is not for this keyword.
                {
                    errors.Add(string.Format("{0}: {1}\r\n{2}", conceptParser.GetType().Name, conceptInfoOrError.Error, tokenReader.ReportPosition()));
                }
            }

            if (possibleInterpretations.Count == 0)
            {
                string msg = "Unrecognized concept. " + tokenReader.ReportPosition();
                if (errors.Count > 0)
                {
                    string listedErrors = string.Join("\r\n", errors);
                    if (listedErrors.Length > 500)
                    {
                        listedErrors = listedErrors.Substring(0, 500) + "...";
                    }
                    msg = msg + "\r\n\r\nPossible causes:\r\n" + listedErrors;
                }
                throw new DslSyntaxException(msg);
            }

            int largest = possibleInterpretations.Max(i => i.NextPosition.PositionInTokenList);

            possibleInterpretations.RemoveAll(i => i.NextPosition.PositionInTokenList < largest);
            if (possibleInterpretations.Count > 1)
            {
                string msg = "Ambiguous syntax. " + tokenReader.ReportPosition()
                             + "\r\n Possible interpretations: "
                             + string.Join(", ", possibleInterpretations.Select(i => i.ConceptInfo.GetType().Name))
                             + ".";
                throw new DslSyntaxException(msg);
            }

            tokenReader.CopyFrom(possibleInterpretations.Single().NextPosition);
            return(possibleInterpretations.Single().ConceptInfo);
        }
Exemple #4
0
        private (IConceptInfo ConceptInfo, List <string> Warnings) ParseNextConcept(TokenReader tokenReader, Stack <IConceptInfo> context, MultiDictionary <string, IConceptParser> conceptParsers)
        {
            var errorReports = new List <Func <(string formattedError, string simpleError)> >();
            List <Interpretation> possibleInterpretations = new List <Interpretation>();

            var keywordReader = new TokenReader(tokenReader).ReadText(); // Peek, without changing the original tokenReader's position.
            var keyword       = keywordReader.IsError ? null : keywordReader.Value;

            _onKeyword?.Invoke(tokenReader, keyword);
            if (keyword != null)
            {
                foreach (var conceptParser in conceptParsers.Get(keyword))
                {
                    TokenReader nextPosition       = new TokenReader(tokenReader);
                    var         conceptInfoOrError = conceptParser.Parse(nextPosition, context, out var warnings);

                    if (!conceptInfoOrError.IsError)
                    {
                        possibleInterpretations.Add(new Interpretation
                        {
                            ConceptInfo  = conceptInfoOrError.Value,
                            NextPosition = nextPosition,
                            Warnings     = warnings
                        });
                    }
                    else if (!string.IsNullOrEmpty(conceptInfoOrError.Error)) // Empty error means that this parser is not for this keyword.
                    {
                        errorReports.Add(() =>
                                         (string.Format("{0}: {1}\r\n{2}", conceptParser.GetType().Name, conceptInfoOrError.Error, tokenReader.ReportPosition()), conceptInfoOrError.Error));
                    }
                }
            }

            if (possibleInterpretations.Count == 0)
            {
                var(dslScript, position) = tokenReader.GetPositionInScript();
                if (errorReports.Count > 0)
                {
                    var errorReportValues  = errorReports.Select(x => x.Invoke()).ToList();
                    var errorsReport       = string.Join("\r\n", errorReportValues.Select(x => x.formattedError)).Limit(500, "...");
                    var simpleErrorsReport = string.Join("\n", errorReportValues.Select(x => x.simpleError));
                    var simpleMessage      = $"Invalid parameters after keyword '{keyword}'. Possible causes: {simpleErrorsReport}";
                    var possibleCauses     = $"Possible causes:\r\n{errorsReport}";
                    throw new DslSyntaxException(simpleMessage, "RH0003", dslScript, position, 0, possibleCauses);
                }
                else if (!string.IsNullOrEmpty(keyword))
                {
                    var simpleMessage = $"Unrecognized concept keyword '{keyword}'.";
                    throw new DslSyntaxException(simpleMessage, "RH0004", dslScript, position, 0, null);
                }
                else
                {
                    var simpleMessage = $"Invalid DSL script syntax.";
                    throw new DslSyntaxException(simpleMessage, "RH0005", dslScript, position, 0, null);
                }
            }

            Disambiguate(possibleInterpretations);
            if (possibleInterpretations.Count > 1)
            {
                var interpretations = new List <string>();
                for (int i = 0; i < possibleInterpretations.Count; i++)
                {
                    interpretations.Add($"{i + 1}. {possibleInterpretations[i].ConceptInfo.GetType().AssemblyQualifiedName}");
                }

                var simpleMessage = $"Ambiguous syntax. There are multiple possible interpretations of keyword '{keyword}': {string.Join(", ", interpretations)}.";
                var(dslScript, position) = tokenReader.GetPositionInScript();

                throw new DslSyntaxException(simpleMessage, "RH0006", dslScript, position, 0, null);
            }

            var parsedStatement = possibleInterpretations.Single();

            tokenReader.CopyFrom(parsedStatement.NextPosition);
            return(parsedStatement.ConceptInfo, parsedStatement.Warnings);
        }
Exemple #5
0
        protected IConceptInfo ParseNextConcept(TokenReader tokenReader, Stack <IConceptInfo> context, MultiDictionary <string, IConceptParser> conceptParsers)
        {
            var errorReports = new List <Func <string> >();
            List <Interpretation> possibleInterpretations = new List <Interpretation>();

            var keywordReader = new TokenReader(tokenReader).ReadText(); // Peek, without changing the original tokenReader's position.
            var keyword       = keywordReader.IsError ? null : keywordReader.Value;

            if (keyword != null)
            {
                foreach (var conceptParser in conceptParsers.Get(keyword))
                {
                    TokenReader nextPosition       = new TokenReader(tokenReader);
                    var         conceptInfoOrError = conceptParser.Parse(nextPosition, context);

                    if (!conceptInfoOrError.IsError)
                    {
                        possibleInterpretations.Add(new Interpretation
                        {
                            ConceptInfo  = conceptInfoOrError.Value,
                            NextPosition = nextPosition
                        });
                    }
                    else if (!string.IsNullOrEmpty(conceptInfoOrError.Error)) // Empty error means that this parser is not for this keyword.
                    {
                        errorReports.Add(() => string.Format("{0}: {1}\r\n{2}", conceptParser.GetType().Name, conceptInfoOrError.Error, tokenReader.ReportPosition()));
                    }
                }
            }

            if (possibleInterpretations.Count == 0)
            {
                if (errorReports.Count > 0)
                {
                    string errorsReport = string.Join("\r\n", errorReports.Select(x => x.Invoke())).Limit(500, "...");
                    throw new DslSyntaxException($"Invalid parameters after keyword '{keyword}'. {tokenReader.ReportPosition()}\r\n\r\nPossible causes:\r\n{errorsReport}");
                }
                else if (!string.IsNullOrEmpty(keyword))
                {
                    throw new DslSyntaxException($"Unrecognized concept keyword '{keyword}'. {tokenReader.ReportPosition()}");
                }
                else
                {
                    throw new DslSyntaxException($"Invalid DSL script syntax. {tokenReader.ReportPosition()}");
                }
            }

            int largest = possibleInterpretations.Max(i => i.NextPosition.PositionInTokenList);

            possibleInterpretations.RemoveAll(i => i.NextPosition.PositionInTokenList < largest);
            if (possibleInterpretations.Count > 1)
            {
                var report = new List <string>();
                report.Add($"Ambiguous syntax. {tokenReader.ReportPosition()}");
                report.Add($"There are multiple possible interpretations of keyword '{keyword}':");
                for (int i = 0; i < possibleInterpretations.Count; i++)
                {
                    report.Add($"{i + 1}. {possibleInterpretations[i].ConceptInfo.GetType().AssemblyQualifiedName}");
                }

                throw new DslSyntaxException(string.Join("\r\n", report));
            }

            tokenReader.CopyFrom(possibleInterpretations.Single().NextPosition);
            return(possibleInterpretations.Single().ConceptInfo);
        }