/* 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);
        }
Beispiel #2
0
        /* Paste tokens are inserted before the first of the two pasted
         * tokens, so it's a kind of bytecode notation. This method
         * swaps them around again. We know that there will never be two
         * sequential paste tokens, so a bool is sufficient. */
        public String getText()
        {
            StringBuilder buf   = new StringBuilder();
            bool          paste = false;

            for (int i = 0; i < tokens.Count; i++)
            {
                Token tok = tokens[i];
                if (tok.getType() == Token.M_PASTE)
                {
                    System.Diagnostics.Debug.Assert(paste == false, "Two sequential pastes.");
                    paste = true;
                    continue;
                }
                else
                {
                    buf.Append(tok.getText());
                }
                if (paste)
                {
                    buf.Append(" #" + "# ");
                    paste = false;
                }
                // buf.Append(tokens.get(i));
            }
            return(buf.ToString());
        }
        override public Token token()
        {
            for (;;)
            {
                /* Deal with lexed tokens first. */

                if (arg != null)
                {
                    if (arg.hasNext())
                    {
                        Token tok2 = arg.next();
                        /* XXX PASTE -> INVALID. */
                        Debug.Assert(tok2.getType() != Token.M_PASTE,
                                     "Unexpected paste token");
                        return(tok2);
                    }
                    arg = null;
                }

                if (!tokens.hasNext())
                {
                    return(new Token(Token.EOF, -1, -1, ""));                   /* End of macro. */
                }
                Token tok = tokens.next();
                int   idx;
                switch (tok.getType())
                {
                case Token.M_STRING:
                    /* Use the nonexpanded arg. */
                    idx = (int)tok.getValue();
                    return(stringify(tok, args.get(idx)));

                case Token.M_ARG:
                    /* Expand the arg. */
                    idx = (int)tok.getValue();
                    // System.out.println("Pushing arg " + args.get(idx));
                    arg = args.get(idx).expansion();
                    break;

                case Token.M_PASTE:
                    paste(tok);
                    break;

                default:
                    return(tok);
                }
            }     /* for */
        }
Beispiel #4
0
 private bool isWhite(Token tok)
 {
     int	type = tok.getType();
     return (type == Token.WHITESPACE)
     || (type == Token.CCOMMENT)
     || (type == Token.CPPCOMMENT);
 }
Beispiel #5
0
 private int expr_priority(Token op)
 {
     switch (op.getType()) {
     case '/': return 11;
     case '%': return 11;
     case '*': return 11;
     case '+': return 10;
     case '-': return 10;
     case Token.LSH: return 9;
     case Token.RSH: return 9;
     case '<': return 8;
     case '>': return 8;
     case Token.LE: return 8;
     case Token.GE: return 8;
     case Token.EQ: return 7;
     case Token.NE: return 7;
     case '&': return 6;
     case '^': return 5;
     case '|': return 4;
     case Token.LAND: return 3;
     case Token.LOR: return 2;
     case '?': return 1;
     default:
         // System.out.println("Unrecognised operator " + op);
         return 0;
     }
 }