示例#1
0
 void differ(string what, Attributes a1, Attributes a2)
 {
     System.Console.WriteLine("{0} {1} << {2} >> {3} {4}",
         a1.loc.PathPoint(),
         Enum.GetName(a1.token.GetType(), a1.token),
         what,
         a2.loc.PathPoint(),
         Enum.GetName(a2.token.GetType(), a2.token));
 }
示例#2
0
        void next()
        {
            m_attrib = m_scanner.scan();

            if (m_loc != null) m_loc.copy(m_attrib.loc);
        }
示例#3
0
        public Attributes interpret(Attributes attrib)
        {
            if (Token.STRING == attrib.token) {
                StringBuilder sb = new StringBuilder();

                int i = 1;
                while (i < attrib.literal.Length-1) {
                    if ('\\' == attrib.literal[i]) {
                        if ('"' == attrib.literal[i+1] || '\\' == attrib.literal[i+1]) {
                            i++;
                        }
                    }

                    sb.Append(attrib.literal[i]);
                    i++;
                }

                attrib.value = sb.ToString();
            } else if (Token.BOOL == attrib.token) {
                if ("#t" == attrib.literal) {
                    attrib.value = true;
                } else {
                    attrib.value = false;
                }
            } else if (Token.CHAR == attrib.token) {
                string value = attrib.literal.Substring(2);

                if (1 == value.Length) {
                    attrib.value = value[0];
                } else {
                    if (value.Equals("space", StringComparison.OrdinalIgnoreCase)) {
                        attrib.value = ' ';
                    } else if (value.Equals("newline", StringComparison.OrdinalIgnoreCase)) {
                        attrib.value = '\n';
                    } else {
                        throw lexical_error("invalid named character");
                    }
                }
            } else if (Token.NUM == attrib.token) {
                if (!Number.parse_number(attrib.literal, out attrib.value)) {
                    throw lexical_error(String.Format("invalid number literal '{0}'", attrib.literal));
                }
            } else if (Token.NAMED_CONSTANT == attrib.token) {
                if ("#!optional" == attrib.literal) {
                    attrib.value = "optional";
                } else if ("#!rest" == attrib.literal) {
                    attrib.value = "rest";
                } else {
                    throw lexical_error("invalid named constant");
                }
            } else if (Token.BIT_STRING == attrib.token) {
                throw lexical_error("bit strings not implemented");
            } else if (Token.HASH_NUMBER == attrib.token) {
                throw lexical_error("hash numbers not implemented");
            } else if (Token.ID == attrib.token) {
                object value;
                if (attrib.literal == ".") {
                    attrib.value = attrib.literal;
                    attrib.token = Token.DOT;
                } else if (Number.parse_number(attrib.literal, out value)) {
                    attrib.value = value;
                    attrib.token = Token.NUM;
                } else {
                    attrib.value = Symbol.get_symbol(attrib.literal);
                }
            } else {
                attrib.value = attrib.literal;
            }

            return attrib;
        }
示例#4
0
        public Attributes read()
        {
            next();

            Attributes attrib = new Attributes();
            attrib.loc = m_reader.loc.clone();

            while (';' == cin || ('#' == cin && '|' == peek) || is_whitespace(cin)) {
                line_comment();

                if (!nested_comment()) {
                    throw lexical_error("<eof> in comment");
                }

                if (is_whitespace(cin)) {
                    next();
                }
            }

            attrib.loc.copy(m_reader.loc);

            if ('\0' == cin) {
                attrib.token = Token.EOF;
            } else if ('(' == cin) {
                attrib.literal = "(";
                attrib.token = Token.OPEN_PAREN;
            } else if (')' == cin) {
                attrib.literal = ")";
                attrib.token = Token.CLOSE_PAREN;
            } else if ('\'' == cin) {
                attrib.literal = "'";
                attrib.token = Token.QUOTE;
            } else if ('`' == cin) {
                attrib.literal = "`";
                attrib.token = Token.BACKQUOTE;
            } else if ('"' == cin) {
                StringBuilder sb = new StringBuilder();
                sb.Append(cin);

                while (peek != '"') {
                    if ('\0' == cin) throw lexical_error("<eof> in string literal");

                    if ('\\' == peek) {
                        next();
                        sb.Append(cin);
                    }

                    next();
                    sb.Append(cin);
                }

                next();
                sb.Append(cin);

                attrib.literal = sb.ToString();
                attrib.token = Token.STRING;
            } else if ('#' == cin) {
                StringBuilder sb = new StringBuilder();
                sb.Append(cin);

                if ('t' == peek || 'f' == peek) {
                    next();
                    sb.Append(cin);
                    attrib.token = Token.BOOL;
                } else if ('\\' == peek) {
                    next();
                    sb.Append(cin);

                    if (is_letter(peek)) {
                        slurp(sb);
                    } else {
                        next();
                        sb.Append(cin);
                    }

                    attrib.token = Token.CHAR;
                } else if ('(' == peek) {
                    next();
                    sb.Append(cin);
                    attrib.token = Token.VECTOR;
                } else if (
                    'b' == peek || 'B' == peek ||
                    'e' == peek || 'E' == peek ||
                    'i' == peek || 'I' == peek ||
                    'd' == peek || 'D' == peek ||
                    'o' == peek || 'O' == peek ||
                    'x' == peek || 'X' == peek) {

                    slurp(sb);
                    attrib.token = Token.NUM;
                } else if ('!' == peek) {
                    slurp(sb);
                    attrib.token = Token.NAMED_CONSTANT;
                } else if ('*' == peek) {
                    slurp(sb);
                    attrib.token = Token.BIT_STRING;
                } else if ('[' == peek) {
                    next();
                    sb.Append(cin);
                    attrib.token = Token.EXTERNAL;
                } else if ('@' == peek) {
                    slurp(sb);
                    attrib.token = Token.HASH_NUMBER;
                } else if ('=' == peek) {
                    next();
                    sb.Append(cin);
                    attrib.token = Token.CIRCULAR_INPUT;
                } else if ('#' == peek) {
                    next();
                    sb.Append(cin);
                    attrib.token = Token.CIRCULAR_OUTPUT;
                } else {
                    throw lexical_error("invalid # sequence");
                }

                attrib.literal = sb.ToString();
            } else if (',' == cin) {
                if ('@' == peek) {
                    next();
                    attrib.literal = ",@";
                    attrib.token = Token.SPLICE;
                } else {
                    attrib.literal = ",";
                    attrib.token = Token.COMMA;
                }
            } else if (']' == cin) {
                attrib.literal = "]";
                attrib.token = Token.CLOSE_SQUARE;
            } else if (
                '|' == cin ||
                '[' == cin ||
                '{' == cin ||
                '}' == cin) {

                attrib.literal = char.ToString(cin);
                throw lexical_error("reserved token");
            } else {
                StringBuilder sb = new StringBuilder();
                sb.Append(cin);
                slurp(sb);
                attrib.literal = sb.ToString();
                attrib.token = Token.ID;
            }

            return attrib;
        }