Пример #1
0
        /* At this point, we have consumed the first M_PASTE.
         * @see Macro#addPaste(Token) */
        private void paste(Token ptok)
        {
            StringBuilder buf = new StringBuilder();
            Token         err = null;

            /* We know here that arg is null or expired,
             * since we cannot paste an expanded arg. */

            int count = 2;

            for (int i = 0; i < count; i++)
            {
                if (!tokens.hasNext())
                {
                    /* XXX This one really should throw. */
                    error(ptok.getLine(), ptok.getColumn(),
                          "Paste at end of expansion");
                    buf.append(' ').append(ptok.getText());
                    break;
                }
                Token tok = tokens.next();
                // System.out.println("Paste " + tok);
                switch (tok.getType())
                {
                case Token.M_PASTE:
                    /* One extra to paste, plus one because the
                     * paste token didn't count. */
                    count += 2;
                    ptok   = tok;
                    break;

                case Token.M_ARG:
                    int idx = (int)tok.getValue();
                    concat(buf, args.get(idx));
                    break;

                /* XXX Test this. */
                case Token.CCOMMENT:
                case Token.CPPCOMMENT:
                    break;

                default:
                    buf.append(tok.getText());
                    break;
                }
            }

            /* Push and re-lex. */

            /*
             * StringBuilder		src = new StringBuilder();
             * escape(src, buf);
             * StringLexerSource	sl = new StringLexerSource(src.toString());
             */
            StringLexerSource sl = new StringLexerSource(buf.toString());

            /* XXX Check that concatenation produces a valid token. */

            arg = new SourceIterator(sl);
        }
Пример #2
0
        private Token stringify(Token pos, Argument arg)
        {
            StringBuilder buf = new StringBuilder();

            concat(buf, arg);
            // System.out.println("Concat: " + arg + " -> " + buf);
            StringBuilder str = new StringBuilder("\"");

            escape(str, buf.ToString());
            str.append("\"");
            // System.out.println("Escape: " + buf + " -> " + str);
            return(new Token(Token.STRING,
                             pos.getLine(), pos.getColumn(),
                             str.toString(), buf.toString()));
        }
Пример #3
0
 /**
  * Handles a warning.
  *
  * If a PreprocessorListener is installed, it receives the
  * warning. Otherwise, an exception is thrown.
  *
  * @see #warning(int, int, String)
  */
 protected void warning(Token tok, String msg)
 {
     warning(tok.getLine(), tok.getColumn(), msg);
 }
Пример #4
0
 /**
  * Handles an error.
  *
  * If a PreprocessorListener is installed, it receives the
  * error. Otherwise, an exception is thrown.
  *
  * @see #error(int, int, String)
  */
 protected void error(Token tok, String msg)
 {
     error(tok.getLine(), tok.getColumn(), msg);
 }
Пример #5
0
        private Token toWhitespace(Token tok)
        {
            String	text = tok.getText();
            int len = text.Length;
            bool	cr = false;
            int		nls = 0;

            for (int i = 0; i < len; i++) {
            char	c = text[i];

            switch (c) {
                case '\r':
                    cr = true;
                    nls++;
                    break;
                case '\n':
                    if (cr) {
                        cr = false;
                        break;
                    }
                    goto case '\u2028';
                /* fallthrough */
                case '\u2028':
                case '\u2029':
                case '\u000B':
                case '\u000C':
                case '\u0085':
                    cr = false;
                    nls++;
                    break;
            }
            }

            char[] cbuf = new char[nls];
            for(int i = 0; i < nls; i++) { cbuf[i] = '\n'; }

            return new Token(Token.WHITESPACE,
                tok.getLine(), tok.getColumn(),
                new String(cbuf));
        }
Пример #6
0
        /* processes and expands a macro. */
        private bool macro(Macro m, Token orig)
        {
            Token			tok;
            List<Argument>	args;

            // System.out.println("pp: expanding " + m);

            if (m.isFunctionLike()) {
            for (;;) {
                tok = source_token();
                // System.out.println("pp: open: token is " + tok);
                switch (tok.getType()) {
                    case Token.WHITESPACE:	/* XXX Really? */
                    case Token.CCOMMENT:
                    case Token.CPPCOMMENT:
                    case Token.NL:
                        break;	/* continue */
                    case '(':
                        goto BREAK_OPEN;
                    default:
                        source_untoken(tok);
                        return false;
                }
            }
            BREAK_OPEN:

            // tok = expanded_token_nonwhite();
            tok = source_token_nonwhite();

            /* We either have, or we should have args.
             * This deals elegantly with the case that we have
             * one empty arg. */
            if (tok.getType() != ')' || m.getArgs() > 0) {
                args = new List<Argument>();

                Argument		arg = new Argument();
                int				depth = 0;
                bool			space = false;

                ARGS: for (;;) {
                    // System.out.println("pp: arg: token is " + tok);
                    switch (tok.getType()) {
                        case Token.EOF:
                            error(tok, "EOF in macro args");
                            return false;

                        case ',':
                            if (depth == 0) {
                                if (m.isVariadic() &&
                                    /* We are building the last arg. */
                                    args.Count == m.getArgs() - 1) {
                                    /* Just add the comma. */
                                    arg.addToken(tok);
                                }
                                else {
                                    args.Add(arg);
                                    arg = new Argument();
                                }
                            }
                            else {
                                arg.addToken(tok);
                            }
                            space = false;
                            break;
                        case ')':
                            if (depth == 0) {
                                args.Add(arg);
                                goto BREAK_ARGS;
                            }
                            else {
                                depth--;
                                arg.addToken(tok);
                            }
                            space = false;
                            break;
                        case '(':
                            depth++;
                            arg.addToken(tok);
                            space = false;
                            break;

                        case Token.WHITESPACE:
                        case Token.CCOMMENT:
                        case Token.CPPCOMMENT:
                            /* Avoid duplicating spaces. */
                            space = true;
                            break;

                        default:
                            /* Do not put space on the beginning of
                             * an argument token. */
                            if (space && arg.Count != 0)
                                arg.addToken(Token.space);
                            arg.addToken(tok);
                            space = false;
                            break;

                    }
                    // tok = expanded_token();
                    tok = source_token();
                }
            BREAK_ARGS:

                if(m.isVariadic() && args.Count < m.getArgs()) {
                    args.Add(new Argument());
                }
                /* space may still be true here, thus trailing space
                 * is stripped from arguments. */

                if (args.Count != m.getArgs()) {
                    error(tok,
                            "macro " + m.getName() +
                            " has " + m.getArgs() + " parameters " +
                            "but given " + args.Count + " args");
                    /* We could replay the arg tokens, but I
                     * note that GNU cpp does exactly what we do,
                     * i.e. output the macro name and chew the args.
                     */
                    return false;
                }

                /*
                for (Argument a : args)
                    a.expand(this);
                */

                for (int i = 0; i < args.Count; i++) {
                    args[i].expand(this);
                }

                // System.out.println("Macro " + m + " args " + args);
            }
            else {
                /* nargs == 0 and we (correctly) got () */
                args = null;
            }

            }
            else {
            /* Macro without args. */
                args = null;
            }

            if (m == __LINE__) {
            push_source(new FixedTokenSource(
                    new Token[] { new Token(Token.INTEGER,
                            orig.getLine(), orig.getColumn(),
                            orig.getLine().ToString(),
                            orig.getLine()) }
                        ), true);
            }
            else if (m == __FILE__) {
            StringBuilder	buf = new StringBuilder("\"");
            String			name = getSource().getName();
            if (name == null)
                name = "<no file>";
            for (int i = 0; i < name.Length; i++) {
                char	c = name[i];
                switch (c) {
                    case '\\':
                        buf.Append("\\\\");
                        break;
                    case '"':
                        buf.Append("\\\"");
                        break;
                    default:
                        buf.Append(c);
                        break;
                }
            }
            buf.Append("\"");
            String			text = buf.ToString();
            push_source(new FixedTokenSource(
                    new Token[] { new Token(Token.STRING,
                            orig.getLine(), orig.getColumn(),
                            text, text) }
                        ), true);
            }
            else if (m == __COUNTER__) {
            /* This could equivalently have been done by adding
             * a special Macro subclass which overrides getTokens(). */
            int	value = this.counter++;
            push_source(new FixedTokenSource(
                    new Token[] { new Token(Token.INTEGER,
                            orig.getLine(), orig.getColumn(),
                            value.ToString(),
                            value) }
                        ), true);
            }
            else {
            push_source(new MacroTokenSource(m, args), true);
            }

            return true;
        }
Пример #7
0
	/* At this point, we have consumed the first M_PASTE.
	 * @see Macro#addPaste(Token) */
	private void paste(Token ptok)  {
		StringBuilder	buf = new StringBuilder();
		Token			err = null;
		/* We know here that arg is null or expired,
		 * since we cannot paste an expanded arg. */

		int	count = 2;
		for (int i = 0; i < count; i++) {
			if (!tokens.hasNext()) {
				/* XXX This one really should throw. */
				error(ptok.getLine(), ptok.getColumn(),
						"Paste at end of expansion");
				buf.append(' ').append(ptok.getText());
				break;
			}
			Token	tok = tokens.next();
			// System.out.println("Paste " + tok);
			switch (tok.getType()) {
				case Token.M_PASTE:
					/* One extra to paste, plus one because the
					 * paste token didn't count. */
					count += 2;
					ptok = tok;
					break;
                case Token.M_ARG:
					int idx = (int)tok.getValue();
					concat(buf, args.get(idx));
					break;
				/* XXX Test this. */
                case Token.CCOMMENT:
                case Token.CPPCOMMENT:
					break;
				default:
					buf.append(tok.getText());
					break;
			}
		}

		/* Push and re-lex. */
		/*
		StringBuilder		src = new StringBuilder();
		escape(src, buf);
		StringLexerSource	sl = new StringLexerSource(src.toString());
		*/
		StringLexerSource	sl = new StringLexerSource(buf.toString());

		/* XXX Check that concatenation produces a valid token. */

		arg = new SourceIterator(sl);
	}
Пример #8
0
	private Token stringify(Token pos, Argument arg) {
		StringBuilder	buf = new StringBuilder();
		concat(buf, arg);
		// System.out.println("Concat: " + arg + " -> " + buf);
		StringBuilder	str = new StringBuilder("\"");
		escape(str, buf.ToString());
		str.append("\"");
		// System.out.println("Escape: " + buf + " -> " + str);
		return new Token(Token.STRING,
				pos.getLine(), pos.getColumn(),
				str.toString(), buf.toString());
	}