+m4_pushdef([AT_CALC_LEX],
+[[#include <ctype.h>
+
+int ]AT_NAME_PREFIX[lex (]AT_LEX_FORMALS[);
+static int get_char (]AT_LEX_FORMALS[);
+static void unget_char (]AT_LEX_PRE_FORMALS[ int c);
+
+]AT_LOCATION_IF([
+static YYLTYPE last_yylloc;
+])[
+static int
+get_char (]AT_LEX_FORMALS[)
+{
+ int res = getc (input);
+ ]AT_USE_LEX_ARGS[;
+]AT_LOCATION_IF([
+ last_yylloc = AT_LOC;
+ if (res == '\n')
+ {
+ AT_LOC.last_line++;
+ AT_LOC.last_column = 1;
+ }
+ else
+ AT_LOC.last_column++;
+])[
+ return res;
+}
+
+static void
+unget_char (]AT_LEX_PRE_FORMALS[ int c)
+{
+ ]AT_USE_LEX_ARGS[;
+]AT_LOCATION_IF([
+ /* Wrong when C == `\n'. */
+ AT_LOC = last_yylloc;
+])[
+ ungetc (c, input);
+}
+
+static int
+read_signed_integer (]AT_LEX_FORMALS[)
+{
+ int c = get_char (]AT_LEX_ARGS[);
+ int sign = 1;
+ int n = 0;
+
+ ]AT_USE_LEX_ARGS[;
+ if (c == '-')
+ {
+ c = get_char (]AT_LEX_ARGS[);
+ sign = -1;
+ }
+
+ while (isdigit (c))
+ {
+ n = 10 * n + (c - '0');
+ c = get_char (]AT_LEX_ARGS[);
+ }
+
+ unget_char (]AT_LEX_PRE_ARGS[ c);
+
+ return sign * n;
+}
+
+
+/*---------------------------------------------------------------.
+| Lexical analyzer returns an integer on the stack and the token |
+| NUM, or the ASCII character read if not a number. Skips all |
+| blanks and tabs, returns 0 for EOF. |
+`---------------------------------------------------------------*/
+
+int
+]AT_NAME_PREFIX[lex (]AT_LEX_FORMALS[)
+{
+ static int init = 1;
+ int c;
+
+ if (init)
+ {
+ init = 0;
+]AT_LOCATION_IF([
+ AT_LOC.last_column = 1;
+ AT_LOC.last_line = 1;
+])[
+ }
+
+]AT_LOCATION_IF([
+ AT_LOC.first_column = AT_LOC.last_column;
+ AT_LOC.first_line = AT_LOC.last_line;
+])[
+
+ /* Skip white space. */
+ while ((c = get_char (]AT_LEX_ARGS[)) == ' ' || c == '\t')
+ {
+]AT_LOCATION_IF(
+[ AT_LOC.first_column = AT_LOC.last_column;
+ AT_LOC.first_line = AT_LOC.last_line;
+])[
+ }
+
+ /* process numbers */
+ if (c == '.' || isdigit (c))
+ {
+ unget_char (]AT_LEX_PRE_ARGS[ c);
+ ]AT_VAL[.ival = read_signed_integer (]AT_LEX_ARGS[);
+ return NUM;
+ }
+
+ /* Return end-of-file. */
+ if (c == EOF)
+ return CALC_EOF;
+
+ /* Return single chars. */
+ return c;
+}
+]])
+