Yes, using something like this: (updated version which counts also space-tokens)
\makeatletter
\newcount\tokencount
\def\counttoken#1{%
\tokencount\z@ % set it to zero
\def\x{\futurelet\@let@token\@counttoken}%
\x#1\end@counttoken
}
% Unique endmarker
\def\end@counttoken{\@gobble{end@counttoken}}
% A macro which eats a space, the \@firstofone is required to
% avoid that the space in the parameter text itself is eaten:
\@firstofone{\def\eatspace} {}
% Recursive Macro => Loop
\def\@counttoken{%
\ifx\@let@token\end@counttoken
\let\x\relax
\else
\advance\tokencount by 1\relax
\fi
\ifx\@let@token\@sptoken
% The space token will be eaten
% Note that two spaces will still be combined by TeX!
% If this is not what is wanted the catcode of space
% must be changed beforehand, e.g. using \obeyspaces!
\expandafter\expandafter
\expandafter\x
\expandafter\eatspace
\else
% Eat the next non-space token now, then call \x
\afterassignment\x
\expandafter\let\expandafter\@let@token\expandafter=%
\fi
}
Test:
\counttoken{A{something}\beta}
\showthe\tokencount
% Prints:> 13
\counttoken{123}
\showthe\tokencount
% Prints:> 3
Basically the next token is \let to \@let@token and afterwards (\afterassignment) the token is counted and checked against the endmarker. Then the macro calls itself until the end marker is reached. Counts all tokens except of course the endmarker. You should add some grouping at the correct places, which depend on the exact way you apply the code.
BUT
if you really just want to count macro arguments, i.e. A{something}B would count as 3:
\newcount\argcount
\def\countargs#1{%
\argcount\@z % set it to zero
\@countargs#1\end@countargs
}
% Unique endmarker
%\def\end@countargs{\@gobble{end@countargs}} % doesn't really have to be defined; never executed
\def\end@@countargs{\end@countargs}
% Recursive Macro => Loop
\def\@countargs#1{%
\def\@tempa{#1}%
\ifx\@tempa\@end@@counttoken\else
\advance\tokencount by 1\relax
\expandafter\@countargs
\fi
}
A{something}\betaare 13 tokens but only 3 macro arguments. – Martin Scharrer♦ Feb 3 '11 at 21:31{ }etc. The TeXBook will give you a more details explanation. In short: while{ }groups tokens together, it doesn't represent them as one token (but as one macro argument ;-) ). However, other programming languages mostly talk about expressions and allow{ }to group multiple expressions together while the group represents one expression by itself. (Sorry if this sounds now very complicated and may not even be 100% correct) – Martin Scharrer♦ Feb 3 '11 at 23:05{...}(assuming normal category codes). – Joseph Wright♦ Feb 4 '11 at 7:11ab{cd}eis 4 items of <balanced text> but 7 tokens. Which value do you actually want? (You might even want 5, ignoring the braces entirely.) – Joseph Wright♦ Feb 4 '11 at 7:13