Ejemplo n.º 1
0
        private void PrintLiteral(ILNode node)
        {
            object value = node.Value;

            if (!PrintLiteralCore(value, node.Style))
            {
                ErrorSink.Error(node, "LesNodePrinter: Encountered unprintable literal of type {0}", value.GetType().Name);

                bool   quote = _o.QuoteUnprintableLiterals;
                string unprintable;
                try {
                    unprintable = value.ToString();
                } catch (Exception ex) {
                    unprintable = ex.Message;
                    quote       = true;
                }
                if (quote)
                {
                    PrintStringCore('"', true, unprintable);
                }
                else
                {
                    _out.Write(unprintable, true);
                }
            }
        }
Ejemplo n.º 2
0
        LNode ParseHostReturnType(Token paren)
        {
            var list = ParseHostCode(paren, ParsingMode.FormalArguments);

            if (list.Count != 1)
            {
                Error(-1, "LLLPG: Expected a single variable declaration (or data type) after '{0}'", ToString(paren.TypeInt));
            }
            LNode result;

            if (list.Count > 0)
            {
                result = list[0];
            }
            else
            {
                result = LNode.Missing;
            }
            if (result.Calls(S.Var, 2))
            {
                if (!result[1].IsIdNamed("result"))
                {
                    ErrorSink.Error(result[1], "LLLPG requires that the result of a rule be called 'result'");
                }
                return(result[0]);
            }
            else
            {
                return(result);
            }
        }
Ejemplo n.º 3
0
        /// <summary>A method that is called when the indent level changed without
        /// a corresponding indent trigger.</summary>
        /// <param name="tokenBeforeNewline">Final non-whitespace token before the newline.</param>
        /// <param name="tokenAfterNewline">First non-whitespace token after the newline.
        /// Though it's a <see cref="Maybe{T}"/>, it always has a value, but this
        /// function can suppress its emission by setting it to NoValue.Value.</param>
        /// <param name="deltaIndent">Amount of unexpected indentation (positive or
        /// negative). On return, this parameter holds the amount by which to change
        /// the <see cref="CurrentIndent"/>; the default implementation leaves this
        /// value unchanged, which means that subsequent lines will be expected to
        /// be indented by the same (unexpected) amount.</param>
        /// <returns>true if <see cref="MakeEndOfLineToken"/> should be called as
        /// usual, or false to suppress EOL genertion. EOL can only be suppressed
        /// in case of an unexpected indent (<c>deltaIndent>0</c>), not an unindent.</returns>
        /// <remarks>The default implementation always returns true. It normally
        /// writes an error message, but switches to a warning in case
        /// <c>OuterIndents[OuterIndents.Count-1] == OuterIndents[OuterIndents.Count-2]</c>,
        /// which this class interprets as a single unindent.
        /// </remarks>
        protected virtual bool IndentChangedUnexpectedly(Token tokenBeforeNewline, ref Maybe <Token> tokenAfterNewline, ref int deltaIndent)
        {
            var pos = IndexToMsgContext(tokenAfterNewline.Or(default(Token)));

            if (deltaIndent > 0)
            {
                if (_errorBias >= 0)
                {
                    ErrorSink.Error(pos, "Unexpected indent");
                }
                _errorBias++;
            }
            else
            {
                if (_errorBias <= 0)
                {
                    var sev = Severity.Error;
                    if (_outerIndents.Count >= 2 && _outerIndents.Last == _outerIndents[_outerIndents.Count - 2])
                    {
                        sev = Severity.Warning;
                    }
                    ErrorSink.Write(sev, pos, "Unindent does not match any outer indentation level");
                }
                _errorBias--;
            }
            return(true);
        }
Ejemplo n.º 4
0
        protected override void Error(int lookaheadIndex, string message)
        {
            // the fast "blitting" code path may not be able to handle errors
            _parseNeeded = true;

            var pos = new SourceRange(SourceFile, InputPosition + lookaheadIndex);

            if (ErrorSink != null)
            {
                ErrorSink.Error(pos, message);
            }
            else
            {
                throw new FormatException(pos + ": " + message);
            }
        }
Ejemplo n.º 5
0
 private bool?Evaluate(LNode expr)
 {
     if (expr.IsId)
     {
         return(DefinedSymbols.Contains(expr.Name));
     }
     else if (expr.IsLiteral && expr.Value is bool)
     {
         return((bool)expr.Value);
     }
     else if (expr.Calls(S.And, 2))
     {
         return(Evaluate(expr.Args[0]) & Evaluate(expr.Args[1]));
     }
     else if (expr.Calls(S.Or, 2))
     {
         return(Evaluate(expr.Args[0]) | Evaluate(expr.Args[1]));
     }
     else if (expr.Calls(S.Not, 1))
     {
         return(!Evaluate(expr.Args[0]));
     }
     else if (expr.Calls(S.Eq, 2))
     {
         return(Evaluate(expr.Args[0]) == Evaluate(expr.Args[1]));
     }
     else if (expr.Calls(S.Neq, 2))
     {
         return(Evaluate(expr.Args[0]) != Evaluate(expr.Args[1]));
     }
     else
     {
         ErrorSink.Error(expr.Range, "Only simple boolean expressions with &&, ||, !, ==, !=, are supported in #if and #elif");
         return(null);
     }
 }
Ejemplo n.º 6
0
 private void Error(Token pptoken, string message)
 {
     ErrorSink.Error(pptoken.ToSourceRange(SourceFile), message);
 }
Ejemplo n.º 7
0
        public override Maybe <Token> NextToken()
        {
            do
            {
                Maybe <Token> t_ = Lexer.NextToken();
redo:
                if (!t_.HasValue)
                {
                    break;
                }
                var t = t_.Value;
                if (t.IsWhitespace)
                {
                    AddWSToken(t);
                    continue;
                }
                else if (t.Kind == TokenKind.Other)
                {
                    switch (t.Type())
                    {
                    case TokenType.PPdefine:
                    case TokenType.PPundef:
                        ReadRest(_rest);
                        bool undef = t.Type() == TokenType.PPundef;
                        if (_rest.Count == 1 && _rest[0].Type() == TokenType.Id)
                        {
                            if (undef)
                            {
                                DefinedSymbols.Remove((Symbol)_rest[0].Value);
                            }
                            else
                            {
                                DefinedSymbols.Add((Symbol)_rest[0].Value);
                            }
                        }
                        else
                        {
                            ErrorSink.Error(t.ToSourceRange(SourceFile), "'{0}' should be followed by a single, simple identifier", undef ? "#undef" : "#define");
                        }
                        continue;

                    case TokenType.PPif:
                        var   tree = ReadRestAsTokenTree();
                        LNode expr = ParseExpr(tree);

                        var cond = Evaluate(expr) ?? false;
                        _ifRegions.Push(Pair.Create(t, cond));
                        t_ = SaveDirectiveAndAutoSkip(t, cond);
                        goto redo;

                    case TokenType.PPelse:
                    case TokenType.PPelif:
                        var tree_ = ReadRestAsTokenTree();

                        if (_ifRegions.Count == 0)
                        {
                            ErrorSink.Error(t.ToSourceRange(SourceFile),
                                            "Missing #if clause before '{0}'", t);
                            _ifRegions.Push(Pair.Create(t, false));
                        }
                        bool isElif = t.Type() == TokenType.PPelif, hasExpr = tree_.HasIndex(0);
                        if (hasExpr != isElif)
                        {
                            Error(t, isElif ? "Missing condition on #elif" : "Unexpected tokens after #else");
                        }
                        bool cond_ = true;
                        if (hasExpr)
                        {
                            LNode expr_ = ParseExpr(tree_);
                            cond_ = Evaluate(expr_) ?? false;
                        }
                        if (_ifRegions.Peek().B)
                        {
                            cond_ = false;
                        }
                        t_ = SaveDirectiveAndAutoSkip(t, cond_);
                        if (cond_)
                        {
                            _ifRegions.Push(Pair.Create(_ifRegions.Pop().A, cond_));
                        }
                        goto redo;

                    case TokenType.PPendif:
                        var tree__ = ReadRestAsTokenTree();
                        if (_ifRegions.Count == 0)
                        {
                            Error(t, "Missing #if before #endif");
                        }
                        else
                        {
                            _ifRegions.Pop();
                            if (tree__.Count > 0)
                            {
                                Error(t, "Unexpected tokens after #endif");
                            }
                        }
                        _triviaList.Add(t);
                        continue;

                    case TokenType.PPerror:
                        _triviaList.Add(t);
                        Error(t, t.Value.ToString());
                        continue;

                    case TokenType.PPwarning:
                        _triviaList.Add(t);
                        ErrorSink.Warning(t.ToSourceRange(SourceFile), t.Value.ToString());
                        continue;

                    case TokenType.PPregion:
                        _triviaList.Add(t);
                        _regions.Push(t);
                        continue;

                    case TokenType.PPendregion:
                        _triviaList.Add(t);
                        if (_regions.Count == 0)
                        {
                            ErrorSink.Warning(t.ToSourceRange(SourceFile), "#endregion without matching #region");
                        }
                        else
                        {
                            _regions.Pop();
                        }
                        continue;

                    case TokenType.PPline:
                        _triviaList.Add(new Token(t.TypeInt, t.StartIndex, Lexer.InputPosition));
                        var rest = ReadRestAsTokenTree();
                        // TODO: use LineRemapper
                        ErrorSink.Write(Severity.Note, t.ToSourceRange(SourceFile), "Support for #line is not implemented");
                        continue;

                    case TokenType.PPpragma:
                        _triviaList.Add(new Token(t.TypeInt, t.StartIndex, Lexer.InputPosition));
                        var rest_ = ReadRestAsTokenTree();
                        // TODO
                        ErrorSink.Write(Severity.Note, t.ToSourceRange(SourceFile), "Support for #pragma is not implemented");
                        continue;
                    }
                }
                return(t_);
            } while (true);
            // end of stream
            if (_ifRegions.Count > 0)
            {
                ErrorSink.Error(_ifRegions.Peek().A.ToSourceRange(SourceFile), "#if without matching #endif");
            }
            if (_regions.Count > 0)
            {
                ErrorSink.Warning(_regions.Peek().ToSourceRange(SourceFile), "#region without matching #endregion");
            }
            return(Maybe <Token> .NoValue);
        }
Ejemplo n.º 8
0
        // An Particle is:
        // - an (expression) in parenthesis or a tuple
        // - a literal or simple identifier
        //   - simple calls are also handled here, as a space optimization
        // - a token literal @{ ... }
        // - a prefix operator followed by an Expr
        // - a { block } in braces
        // - a [ list  ] in square brackets
        LNode Particle()
        {
            TT        la0;
            Token     c      = default(Token);
            Token     o      = default(Token);
            LNode     result = default(LNode);
            TokenTree tree   = default(TokenTree);

            // Line 192: ( TT.Id | TT.Literal | TT.At (TT.LBrack TokenTree TT.RBrack | TT.LBrace TokenTree TT.RBrace) | TT.LBrace StmtList TT.RBrace | TT.LBrack ExprList TT.RBrack | (TT.LParen|TT.SpaceLParen) ExprList TT.RParen )
            switch ((TT)LA0)
            {
            case TT.Id:
            {
                var id = MatchAny();
                // line 193
                result = F.Id(id).SetStyle(id.Style);
            }
            break;

            case TT.Literal:
            {
                var lit = MatchAny();
                // line 195
                result = F.Literal(lit).SetStyle(lit.Style);
            }
            break;

            case TT.At:
            {
                o = MatchAny();
                // Line 198: (TT.LBrack TokenTree TT.RBrack | TT.LBrace TokenTree TT.RBrace)
                la0 = (TT)LA0;
                if (la0 == TT.LBrack)
                {
                    Skip();
                    tree = TokenTree();
                    c    = Match((int)TT.RBrack);
                }
                else
                {
                    Match((int)TT.LBrace);
                    tree = TokenTree();
                    c    = Match((int)TT.RBrace);
                }
                // line 200
                result = F.Literal(tree, o.StartIndex, c.EndIndex);
            }
            break;

            case TT.LBrace:
            {
                o = MatchAny();
                var list = StmtList();
                c = Match((int)TT.RBrace);
                // line 203
                result = F.Braces(list, o.StartIndex, c.EndIndex).SetStyle(NodeStyle.StatementBlock);
            }
            break;

            case TT.LBrack:
            {
                o = MatchAny();
                var list = ExprList();
                c = Match((int)TT.RBrack);
                // line 205
                result = F.Call(S.Array, list, o.StartIndex, c.EndIndex, o.StartIndex, o.EndIndex, NodeStyle.Expression);
            }
            break;

            case TT.LParen:
            case TT.SpaceLParen:
            {
                // line 207
                var endMarker = default(TT);
                o = MatchAny();
                // line 208
                var hasAttrList = ((TT)LA0) == TT.LBrack || ((TT)LA0) == TT.At;
                var list        = ExprList(ref endMarker);
                c = Match((int)TT.RParen);
                // line 211
                if ((endMarker == TT.Semicolon || list.Count != 1))
                {
                    result = F.Call(S.Tuple, list, o.StartIndex, c.EndIndex, o.StartIndex, o.EndIndex, NodeStyle.Expression);
                    if ((endMarker == TT.Comma))
                    {
                        var msg = "Tuples require ';' as a separator.";
                        if ((o.Type() == TT.SpaceLParen))
                        {
                            msg += " If a function call was intended, remove the space(s) before '('.";
                        }
                        ErrorSink.Error(list[0].Range.End, msg);
                    }
                }
                else
                {
                    result = hasAttrList ? list[0] : F.InParens(list[0], o.StartIndex, c.EndIndex);
                }
            }
            break;

            default:
            {
                // line 225
                Error(0, "Expected a particle (id, literal, {braces} or (parens)).");
                result = MissingExpr(LT0);
            }
            break;
            }
            return(result);
        }