Esempio n. 1
0
        /// <summary>
        /// Ported from format_t::element_t * format_t::parse_elements
        /// </summary>
        private FormatElement ParseElements(string fmt, Format tmpl = null)
        {
            FormatElement   result   = null;
            FormatElement   current  = null;
            string          q        = string.Empty;
            InputTextStream inStream = new InputTextStream(fmt);

            for (char p = inStream.Peek; !inStream.Eof; inStream.Get(), p = inStream.Peek)
            {
                if (p != '%' && p != '\\')
                {
                    q += p;
                    continue;
                }

                if (result == null)
                {
                    result  = new FormatElement();
                    current = result;
                }
                else
                {
                    current.Next = new FormatElement();
                    current      = current.Next;
                }

                if (!String.IsNullOrEmpty(q))
                {
                    current.Type = FormatElementEnum.STRING;
                    current.Data.SetValue(q);
                    q = string.Empty;

                    current.Next = new FormatElement();
                    current      = current.Next;
                }

                if (p == '\\')
                {
                    inStream.Get(); p = inStream.Peek;
                    current.Type      = FormatElementEnum.STRING;
                    switch (p)
                    {
                    case 'b': current.Data.SetValue("\b"); break;

                    case 'f': current.Data.SetValue("\f"); break;

                    case 'n': current.Data.SetValue("\n"); break;

                    case 'r': current.Data.SetValue("\r"); break;

                    case 't': current.Data.SetValue("\t"); break;

                    case 'v': current.Data.SetValue("\v"); break;

                    case '\\': current.Data.SetValue("\\"); break;

                    default: current.Data.SetValue(new string(p, 1)); break;
                    }
                    continue;
                }

                inStream.Get(); p = inStream.Peek;  // cut '%' or '\\'
                while (p == '-')
                {
                    current.IsElementAlignLeft = true;
                    inStream.Get(); p          = inStream.Peek;
                }

                current.MinWidth = inStream.ReadInt(0, out p);
                if (p == '.')
                {
                    current.MaxWidth = inStream.ReadInt(0, out p);
                    p = inStream.Peek;
                    if (current.MinWidth == 0)
                    {
                        current.MinWidth = current.MaxWidth;
                    }
                }

                if (Char.IsLetter(p))
                {
                    string sExpr;
                    if (SingleLetterMapping.TryGetValue(p, out sExpr))
                    {
                        if (sExpr.Contains('$'))
                        {
                            sExpr = sExpr.Replace("$min", current.MinWidth > 0 ? current.MinWidth.ToString() : "-1").
                                    Replace("$max", current.MaxWidth > 0 ? current.MaxWidth.ToString() : "-1").
                                    Replace("$left", current.IsElementAlignLeft ? "false" : "true");
                            if (sExpr.Contains('$'))
                            {
                                throw new InvalidOperationException("Unrecognized format substitution keyword");
                            }
                        }
                        current.Type = FormatElementEnum.EXPR;
                        current.Data.SetValue(new Expr(sExpr));
                    }
                    else
                    {
                        throw new FormatError(String.Format(FormatError.ErrorMessageUnrecognizedFormattingCharacterSmth, p));
                    }
                }
                else
                {
                    switch (p)
                    {
                    case '%':
                        current.Type = FormatElementEnum.STRING;
                        current.Data.SetValue("%");
                        break;

                    case '$':
                    {
                        if (tmpl == null)
                        {
                            throw new FormatError(FormatError.ErrorMessagePriorFieldReferenceButNoTemplate);
                        }

                        inStream.Get(); p = inStream.Peek;
                        if (p == '0' || (!Char.IsDigit(p) && p != 'A' && p != 'B' && p != 'C' && p != 'D' && p != 'E' && p != 'F'))
                        {
                            throw new FormatError(FormatError.ErrorMessageFieldReferenceMustBeADigitFrom1To9);
                        }

                        int           index    = char.IsDigit(p) ? p - '0' : (p - 'A' + 10);
                        FormatElement tmplElem = tmpl.Elements;

                        for (int i = 1; i < index && tmplElem != null; i++)
                        {
                            tmplElem = tmplElem.Next;
                            while (tmplElem != null && tmplElem.Type != FormatElementEnum.EXPR)
                            {
                                tmplElem = tmplElem.Next;
                            }
                        }

                        if (tmplElem == null)
                        {
                            throw new FormatError(FormatError.ErrorMessageReferenceToANonExistentPriorField);
                        }

                        current.Assign(tmplElem);
                        break;
                    }

                    case '(':
                    case '{':
                    {
                        bool formatAmount = p == '{';

                        current.Type = FormatElementEnum.EXPR;
                        current.Data.SetValue(ParseSingleExpression(inStream));

                        // Wrap the subexpression in calls to justify and scrub
                        if (!formatAmount)
                        {
                            break;
                        }

                        ExprOp op = current.Data.GetValue <Expr>().Op;

                        #region Create Expressions
                        ExprOp call2Node = new ExprOp(OpKindEnum.O_CALL);
                        call2Node.Left = IdentNode("justify");

                        ExprOp args3Node = new ExprOp(OpKindEnum.O_CONS);

                        ExprOp call1Node = new ExprOp(OpKindEnum.O_CALL);
                        call1Node.Left  = IdentNode("scrub");
                        call1Node.Right = op.Kind == OpKindEnum.O_CONS ? op.Left : op;

                        args3Node.Left = call1Node;

                        ExprOp args2Node = new ExprOp(OpKindEnum.O_CONS);

                        ExprOp arg1Node = new ExprOp(OpKindEnum.VALUE);
                        arg1Node.AsValue = Value.Get(current.MinWidth > 0 ? current.MinWidth : -1);

                        args2Node.Left = arg1Node;

                        ExprOp args1Node = new ExprOp(OpKindEnum.O_CONS);

                        ExprOp arg2Node = new ExprOp(OpKindEnum.VALUE);
                        arg2Node.AsValue = Value.Get(current.MaxWidth > 0 ? current.MaxWidth : -1);

                        args1Node.Left = arg2Node;

                        ExprOp arg3Node = new ExprOp(OpKindEnum.VALUE);
                        arg3Node.AsValue = Value.Get(!current.IsElementAlignLeft);

                        args1Node.Right = arg3Node;

                        args2Node.Right = args1Node;

                        args3Node.Right = args2Node;

                        call2Node.Right = args3Node;
                        #endregion

                        current.MinWidth = 0;
                        current.MaxWidth = 0;

                        string prevExpr = current.Data.GetValue <Expr>().Text;

                        ExprOp colorizeOp = null;
                        if (op.Kind == OpKindEnum.O_CONS && op.HasRight)
                        {
                            colorizeOp = op.Right;
                        }

                        if (colorizeOp != null)
                        {
                            ExprOp call3Node = new ExprOp(OpKindEnum.O_CALL);
                            call3Node.Left = IdentNode("ansify_if");
                            ExprOp args4Node = new ExprOp(OpKindEnum.O_CONS);
                            args4Node.Left  = call2Node;        // from above
                            args4Node.Right = colorizeOp;
                            call3Node.Right = args4Node;

                            current.Data.SetValue(new Expr(call3Node));
                        }
                        else
                        {
                            current.Data.SetValue(new Expr(call2Node));
                        }

                        current.Data.GetValue <Expr>().Text = prevExpr;
                        break;
                    }

                    default:
                        throw new FormatError(String.Format(FormatError.ErrorMessageUnrecognizedFormattingCharacterSmth, p));
                    }
                }
            }

            if (!string.IsNullOrEmpty(q))
            {
                if (result == null)
                {
                    result  = new FormatElement();
                    current = result;
                }
                else
                {
                    current.Next = new FormatElement();
                    current      = current.Next;
                }
                current.Type = FormatElementEnum.STRING;
                current.Data.SetValue(q);
            }

            return(result);
        }
Esempio n. 2
0
        /// <summary>
        /// Ported from void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags)
        /// </summary>
        public void Next(InputTextStream inStream, AmountParseFlagsEnum pflags)
        {
            if (inStream.Eof)
            {
                Kind = ExprTokenKind.TOK_EOF;
                return;
            }

            char c = inStream.PeekNextNonWS();

            if (inStream.Eof)
            {
                Kind = ExprTokenKind.TOK_EOF;
                return;
            }

            Symbol = new string(c, 1);
            Length = 1;

            switch (c)
            {
            case '&':
                inStream.Get();
                c = inStream.Peek;
                if (c == '&')
                {
                    c      = inStream.Get();
                    Length = 2;
                }
                Kind = ExprTokenKind.KW_AND;
                break;

            case '|':
                inStream.Get();
                c = inStream.Peek;
                if (c == '|')
                {
                    c      = inStream.Get();
                    Length = 2;
                }
                Kind = ExprTokenKind.KW_OR;
                break;

            case '(':
                c    = inStream.Get();
                Kind = ExprTokenKind.LPAREN;
                break;

            case ')':
                c    = inStream.Get();
                Kind = ExprTokenKind.RPAREN;
                break;

            case '[':
            {
                c = inStream.Get();
                string buf;
                Length += inStream.ReadInto(out buf, out c, ch => ch != ']');
                if (c != ']')
                {
                    Expected(']', c);
                }

                c = inStream.Get();
                Length++;

                DateInterval timespan = new DateInterval(buf);
                Date?        begin    = timespan.Begin;
                if (!begin.HasValue)
                {
                    throw new ParseError(ParseError.ParseError_DateSpecifierDoesNotReferToAStartingDate);
                }
                Kind  = ExprTokenKind.VALUE;
                Value = Value.Get(begin.Value);
                break;
            }

            case '\'':
            case '"':
            {
                char   delim = inStream.Get();
                string buf;
                Length += inStream.ReadInto(out buf, out c, ch => ch != delim);
                if (c != delim)
                {
                    Expected(delim, c);
                }
                c = inStream.Get();
                Length++;
                Kind  = ExprTokenKind.VALUE;
                Value = Value.Get(buf, true);          // [DM] It equals to 'value.set_string(buf);'
                break;
            }

            case '{':
            {
                c = inStream.Get();
                Amount temp = new Amount();
                temp.Parse(inStream, AmountParseFlagsEnum.PARSE_NO_MIGRATE);
                c = inStream.Get();
                if (c != '}')
                {
                    Expected('}', c);
                }
                Length++;
                Kind  = ExprTokenKind.VALUE;
                Value = Value.Get(temp);
                break;
            }

            case '!':
                inStream.Get();
                c = inStream.Peek;
                if (c == '=')
                {
                    c      = inStream.Get();
                    Symbol = "!=";
                    Kind   = ExprTokenKind.NEQUAL;
                    Length = 2;
                    break;
                }
                else if (c == '~')
                {
                    c      = inStream.Get();
                    Symbol = "!~";
                    Kind   = ExprTokenKind.NMATCH;
                    Length = 2;
                    break;
                }
                Kind = ExprTokenKind.EXCLAM;
                break;

            case '-':
                inStream.Get();
                c = inStream.Peek;
                if (c == '>')
                {
                    c      = inStream.Get();
                    Symbol = "->";
                    Kind   = ExprTokenKind.ARROW;
                    Length = 2;
                    break;
                }
                Kind = ExprTokenKind.MINUS;
                break;

            case '+':
                c    = inStream.Get();
                Kind = ExprTokenKind.PLUS;
                break;

            case '*':
                c    = inStream.Get();
                Kind = ExprTokenKind.STAR;
                break;

            case '?':
                c    = inStream.Get();
                Kind = ExprTokenKind.QUERY;
                break;

            case ':':
                inStream.Get();
                c    = inStream.Peek;
                Kind = ExprTokenKind.COLON;
                break;

            case '/':
            {
                c = inStream.Get();
                if (pflags.HasFlag(AmountParseFlagsEnum.PARSE_OP_CONTEXT))
                {
                    // operator context
                    Kind = ExprTokenKind.SLASH;
                }
                else
                {
                    // terminal context
                    // Read in the regexp
                    string buf;
                    Length += inStream.ReadInto(out buf, out c, ch => ch != '/');
                    if (c != '/')
                    {
                        Expected('/', c);
                    }
                    c = inStream.Get();
                    Length++;

                    Kind  = ExprTokenKind.VALUE;
                    Value = Value.Get(new Mask(buf));
                }
                break;
            }

            case '=':
            {
                inStream.Get();
                c = inStream.Peek;
                if (c == '~')
                {
                    c      = inStream.Get();
                    Symbol = "=~";
                    Kind   = ExprTokenKind.MATCH;
                    Length = 2;
                    break;
                }
                if (c == '=')
                {
                    c      = inStream.Get();
                    Symbol = "==";
                    Kind   = ExprTokenKind.EQUAL;
                    Length = 2;
                    break;
                }
                Kind = ExprTokenKind.ASSIGN;
                break;
            }

            case '<':
                c = inStream.Get();
                if (inStream.Peek == '=')
                {
                    c      = inStream.Get();
                    Symbol = "<=";
                    Kind   = ExprTokenKind.LESSEQ;
                    Length = 2;
                    break;
                }
                Kind = ExprTokenKind.LESS;
                break;

            case '>':
                c = inStream.Get();
                if (inStream.Peek == '=')
                {
                    c      = inStream.Get();
                    Symbol = ">=";
                    Kind   = ExprTokenKind.GREATEREQ;
                    Length = 2;
                    break;
                }
                Kind = ExprTokenKind.GREATER;
                break;

            case '.':
                c    = inStream.Get();
                Kind = ExprTokenKind.DOT;
                break;

            case ',':
                c    = inStream.Get();
                Kind = ExprTokenKind.COMMA;
                break;

            case ';':
                c    = inStream.Get();
                Kind = ExprTokenKind.SEMI;
                break;

            default:
            {
                int pos = inStream.Pos;

                // First, check to see if it's a reserved word, such as: and or not
                int result = ParseReservedWord(inStream);
                if (char.IsLetter(c) && result == 1)
                {
                    break;
                }

                // If not, rewind back to the beginning of the word to scan it
                // again.  If the result was -1, it means no identifier was scanned
                // so we don't have to rewind.
                if (result == 0 || inStream.Eof)
                {
                    inStream.Pos = pos;
                }

                if (inStream.Eof)
                {
                    throw new InvalidOperationException("eof");
                }

                // When in relaxed parsing mode, we want to migrate commodity flags
                // so that any precision specified by the user updates the current
                // maximum displayed precision.

                AmountParseFlagsEnum parseFlags = AmountParseFlagsEnum.PARSE_NO_ANNOT;
                if (pflags.HasFlag(AmountParseFlagsEnum.PARSE_NO_MIGRATE))
                {
                    parseFlags |= AmountParseFlagsEnum.PARSE_NO_MIGRATE;
                }
                if (pflags.HasFlag(AmountParseFlagsEnum.PARSE_NO_REDUCE))
                {
                    parseFlags |= AmountParseFlagsEnum.PARSE_NO_REDUCE;
                }

                try
                {
                    Amount temp = new Amount();
                    if (!temp.Parse(inStream, parseFlags | AmountParseFlagsEnum.PARSE_SOFT_FAIL))
                    {
                        inStream.Pos = pos;

                        c = inStream.Peek;
                        if (c != InputTextStream.EndOfFileChar)
                        {
                            if (!char.IsLetter(c) && c != '_')
                            {
                                Expected(default(char), c);
                            }
                            ParseIdent(inStream);
                        }
                        else
                        {
                            throw new ParseError(ParseError.ParseError_UnexpectedEOF);
                        }

                        if (Value.Type != ValueTypeEnum.String || Value.IsZero)
                        {
                            Kind   = ExprTokenKind.ERROR;
                            Symbol = new string(c, 1);
                            throw new ParseError(ParseError.ParseError_FailedToParseIdentifier);
                        }
                    }
                    else
                    {
                        Kind   = ExprTokenKind.VALUE;
                        Value  = Value.Get(temp);
                        Length = inStream.Pos - pos;
                    }
                }
                catch
                {
                    Kind   = ExprTokenKind.ERROR;
                    Length = inStream.Pos - pos;
                    throw;
                }
                break;
            }
            }
        }
Esempio n. 3
0
        protected string ReadField(ref string line)
        {
            StringBuilder   field    = new StringBuilder();
            InputTextStream inStream = new InputTextStream(line);

            char c;

            if (inStream.Peek == '"' || inStream.Peek == '|')
            {
                c = inStream.Get();
                char x;
                while (!inStream.Eof)
                {
                    x = inStream.Get();
                    if (x == '\\')
                    {
                        x = inStream.Get();
                    }
                    else if (x == '"' && inStream.Peek == '"')
                    {
                        x = inStream.Get();
                    }
                    else if (x == c)
                    {
                        if (x == '|')
                        {
                            inStream.Unget();
                        }
                        else if (inStream.Peek == ',')
                        {
                            c = inStream.Get();
                        }
                        break;
                    }
                    if (x != default(char))
                    {
                        field.Append(x);
                    }
                }
            }
            else
            {
                while (!inStream.Eof)
                {
                    c = inStream.Get();

                    if (c == ',')
                    {
                        break;
                    }

                    if (c != default(char))
                    {
                        field.Append(c);
                    }
                }
            }

            line = inStream.RemainSource;
            return(field.ToString().Trim());
        }