/// <summary>
        /// Contructor
        /// </summary>
        /// <param name="parameters"></param>
        public DscParameterParser(string parameters)
        {
            byte[] bytes = System.Text.Encoding.ASCII.GetBytes(parameters);
            ms          = new MemoryStream(bytes);
            stream      = new StreamReader(ms);
            this.reader = new EpsStreamReader(stream);

            lexer = new LexerBase();
        }
Beispiel #2
0
        private LexerToken ScanHexadecimalString(EpsStreamReader reader)
        {
            Debug.Assert(reader.CurrentChar == Chars.Less);

            ClearToken();
            char[] hex = new char[2];
            ScanNextChar(reader);

            while (true)
            {
                MoveToNonWhiteSpace(reader);

                if (reader.CurrentChar == '>')
                {
                    ScanNextChar(reader);
                    break;
                }

                if (char.IsLetterOrDigit(reader.CurrentChar))
                {
                    hex[0] = char.ToUpper(reader.CurrentChar);

                    var nextChar = reader.NextChar;

                    if (nextChar != '>')
                    {
                        hex[1] = char.ToUpper(nextChar);
                    }
                    else
                    {
                        hex[1] = '0';
                    }

                    int ch = int.Parse(new string(hex), NumberStyles.AllowHexSpecifier);
                    Token.Append(Convert.ToChar(ch));
                    ScanNextChar(reader);
                    ScanNextChar(reader);
                }
            }

            string chars = Token.ToString();
            int    count = chars.Length;

            if (count > 2 && chars[0] == (char)0xFE && chars[1] == (char)0xFF)
            {
                Debug.Assert(count % 2 == 0);
                Token.Length = 0;

                for (int idx = 2; idx < count; idx += 2)
                {
                    Token.Append((char)(chars[idx] * 256 + chars[idx + 1]));
                }
            }

            return(Symbol = LexerToken.HexString);
        }
Beispiel #3
0
        /// <summary>
        /// Constructor
        /// </summary>
        public Parser(EpsStreamReader reader)
        {
            // The reader is passed in here but you should know
            // the reader is used at other places as well. The parser
            // has by design no exclusive access to it. That means
            // the state of the reader might change between calls to
            // the parser and to the lexer.

            this.reader = reader;
            lexer       = new Lexer();
        }
Beispiel #4
0
        /// <summary>
        /// Scans an operator.
        /// </summary>
        private LexerToken ScanOperator(EpsStreamReader reader)
        {
            ClearToken();
            char ch = reader.CurrentChar;

            while (IsOperatorFirstChar(ch) || char.IsDigit(ch) || ch == '-')
            {
                ch = AppendAndScanNextChar(reader);
            }

            return(Symbol = LexerToken.Operator);
        }
Beispiel #5
0
        /// <summary>
        /// Scans a dsc comment token
        /// </summary>
        private LexerToken ScanDscComment(EpsStreamReader reader)
        {
            Debug.Assert(reader.CurrentChar == Chars.Percent);

            ClearToken();
            char ch;

            do
            {
                ch = AppendAndScanNextChar(reader);
            }while (!IsWhiteSpace(ch) && ch != Chars.EOF);

            return(Symbol = LexerToken.DscComment);
        }
Beispiel #6
0
        /// <summary>
        /// Scans a name.
        /// </summary>
        private LexerToken ScanName(EpsStreamReader reader)
        {
            Debug.Assert(reader.CurrentChar == Chars.Slash);
            ScanNextChar(reader);

            ClearToken();
            char ch;

            do
            {
                ch = AppendAndScanNextChar(reader);
            }while (!IsWhiteSpace(ch) && !IsDelimiter(ch));

            return(Symbol = LexerToken.Name);
        }
Beispiel #7
0
        /// <summary>
        /// Continues scanning an integer or real number when the first char is already read
        /// </summary>
        /// <param name="reader"></param>
        protected LexerToken ScanNumberContinue(EpsStreamReader reader)
        {
            ClearToken();
            var ch = MoveToNonWhiteSpace(reader);

            while (char.IsDigit(ch) || ch == '+' || ch == '-' || ch == 'e' || ch == 'E' || ch == '.' || ch == '#')
            {
                ch = AppendAndScanNextChar(reader);
            }

            var match = radixRegex.Match(StringToken);

            if (match.Success)
            {
                var radix = int.Parse(match.Groups[1].Value);
                IntegerToken = Convert.ToInt32(match.Groups[2].Value, radix);

                return(LexerToken.Integer);
            }

            match = integerRegex.Match(StringToken);

            if (match.Success)
            {
                var dbl = double.Parse(StringToken);

                if (int.MinValue <= dbl && dbl <= int.MaxValue)
                {
                    IntegerToken = int.Parse(StringToken);

                    return(LexerToken.Integer);
                }

                RealToken = dbl;
                return(LexerToken.Real);
            }

            match = doubleRegex.Match(StringToken);

            if (match.Success)
            {
                RealToken = double.Parse(StringToken, CultureInfo.InvariantCulture);

                return(LexerToken.Real);
            }

            return(LexerToken.Name);
        }
Beispiel #8
0
        /// <summary>
        /// MoveToNonWhiteSpace
        /// </summary>
        protected char MoveToNonWhiteSpace(EpsStreamReader reader)
        {
            var currChar = reader.CurrentChar;

            while (currChar != Chars.EOF)
            {
                if (!whiteSpaceChars.Contains(currChar))
                {
                    return(currChar);
                }

                currChar = ScanNextChar(reader);
            }

            return(currChar);
        }
Beispiel #9
0
        /// <summary>
        /// Scan ASCII base85 string
        /// </summary>
        /// <param name="reader"></param>
        private LexerToken ScanAsciiBase85String(EpsStreamReader reader)
        {
            ClearToken();
            ScanNextChar(reader);
            ScanNextChar(reader);

            char ch = reader.CurrentChar;

            while (ch != '~' && ch != Chars.EOF)
            {
                ch = AppendAndScanNextChar(reader);
            }

            ScanNextChar(reader);
            ScanNextChar(reader);

            return(Symbol = LexerToken.AsciiBase85String);
        }
Beispiel #10
0
 /// <summary>
 /// Scans an integer or real number.
 /// </summary>
 public LexerToken ScanNumber(EpsStreamReader reader)
 {
     ScanNextChar(reader);
     return(ScanNumberContinue(reader));
 }
Beispiel #11
0
 /// <summary>
 /// Appends current character to the token and reads next one.
 /// </summary>
 protected char AppendAndScanNextChar(EpsStreamReader reader)
 {
     Token.Append(reader.CurrentChar);
     return(ScanNextChar(reader));
 }
Beispiel #12
0
        /// <summary>
        /// Move current position one character further in content stream.
        /// </summary>
        protected char ScanNextChar(EpsStreamReader reader)
        {
            var currChar = reader.Read();

            return(currChar);
        }
Beispiel #13
0
        /// <summary>
        /// Reads the next token and returns its type.
        /// </summary>
        public LexerToken ScanNextToken(EpsStreamReader reader)
        {
            while (true)
            {
                ClearToken();
                char ch = MoveToNonWhiteSpace(reader);

                switch (ch)
                {
                case Chars.EOF:
                {
                    return(Symbol = LexerToken.Eof);
                }

                case '%':
                {
                    if (reader.IsFirstCharOfLine)
                    {
                        return(Symbol = ScanDscComment(reader));
                    }

                    ScanComment(reader);
                    continue;
                }

                case '/':
                {
                    if (reader.NextChar == '/')
                    {
                        ScanNextChar(reader);
                        ScanNextChar(reader);

                        ScanOperator(reader);

                        return(Symbol = LexerToken.ImmediateOperator);
                    }

                    return(Symbol = ScanName(reader));
                }

                case '[':
                {
                    ScanNextChar(reader);
                    return(Symbol = LexerToken.BeginArray);
                }

                case ']':
                {
                    ScanNextChar(reader);
                    return(Symbol = LexerToken.EndArray);
                }

                case '{':
                {
                    ScanNextChar(reader);
                    return(Symbol = LexerToken.BeginProcedure);
                }

                case '}':
                {
                    ScanNextChar(reader);
                    return(Symbol = LexerToken.EndProcedure);
                }

                case '(':
                {
                    return(Symbol = ScanLiteralString(reader));
                }

                case '<':
                {
                    if (reader.NextChar == '<')
                    {
                        ScanNextChar(reader);
                        ScanNextChar(reader);
                        return(Symbol = LexerToken.BeginDictionary);
                    }

                    if (reader.NextChar == '~')
                    {
                        return(Symbol = ScanAsciiBase85String(reader));
                    }

                    return(Symbol = ScanHexadecimalString(reader));
                }

                case '>':
                {
                    if (reader.NextChar == '>')
                    {
                        ScanNextChar(reader);
                        ScanNextChar(reader);
                        return(Symbol = LexerToken.EndDictionary);
                    }

                    throw new Exception($"Unexpected Character {ch}");
                }
                }

                if (char.IsDigit(ch) || ch == '+' || ch == '-' || ch == '.')
                {
                    return(Symbol = ScanNumberContinue(reader));
                }

                if (IsOperatorFirstChar(ch))
                {
                    return(Symbol = ScanOperator(reader));
                }

                throw new Exception($"Unexpected Character {ch}");
            }
        }
Beispiel #14
0
        private LexerToken ScanLiteralString(EpsStreamReader reader)
        {
            Debug.Assert(reader.CurrentChar == Chars.ParenLeft);

            ClearToken();
            int  parenLevel = 0;
            char ch         = ScanNextChar(reader);

            while (true)
            {
SkipChar:
                switch (ch)
                {
                case '(':
                    parenLevel++;
                    break;

                case ')':
                    if (parenLevel == 0)
                    {
                        ScanNextChar(reader);
                        return(Symbol = LexerToken.String);
                    }

                    parenLevel--;
                    break;

                case '\\':
                {
                    ch = ScanNextChar(reader);
                    switch (ch)
                    {
                    case 'n':
                        ch = Chars.LF;
                        break;

                    case 'r':
                        ch = Chars.CR;
                        break;

                    case 't':
                        ch = Chars.HT;
                        break;

                    case 'b':
                        ch = Chars.BS;
                        break;

                    case 'f':
                        ch = Chars.FF;
                        break;

                    case '(':
                        ch = Chars.ParenLeft;
                        break;

                    case ')':
                        ch = Chars.ParenRight;
                        break;

                    case '\\':
                        ch = Chars.BackSlash;
                        break;

                    case Chars.LF:
                        ch = ScanNextChar(reader);
                        goto SkipChar;

                    default:
                        if (char.IsDigit(ch))
                        {
                            // Octal character code.
                            int n = ch - '0';

                            if (char.IsDigit(reader.NextChar))
                            {
                                n = n * 8 + ScanNextChar(reader) - '0';

                                if (char.IsDigit(reader.NextChar))
                                {
                                    n = n * 8 + ScanNextChar(reader) - '0';
                                }
                            }

                            ch = (char)n;
                        }
                        break;
                    }
                    break;
                }

                default:
                    // Every other char is appended to the token.
                    break;
                }

                Token.Append(ch);
                ch = ScanNextChar(reader);
            }
        }