-
Notifications
You must be signed in to change notification settings - Fork 9
/
io.tex
6227 lines (5504 loc) · 300 KB
/
io.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
%Part{Io, Root = "CLM.MSS"}
%%%Chapter of Common Lisp Manual. Copyright 1984, 1988, 1989 Guy L. Steele Jr.
\clearpage\def\pagestatus{FINAL PROOF}
\chapter{Input/Output}
\label{IO}
%\chapter{Система ввода/вывода}
%\label{IO}
Common Lisp provides a rich set of facilities for performing input/output.
All input/output operations are performed on streams of various kinds.
This chapter is devoted to stream data transfer operations.
Streams are discussed in chapter~\ref{STREAM}, and
ways of manipulating files through streams are discussed in
chapter~\ref{FILES}.
While there is provision for reading and writing binary data,
most of the I/O operations in Common Lisp read or write characters.
There are simple primitives for reading and writing single characters
or lines of data. The \cdf{format} function can perform complex
formatting of output data, directed by a control string
in manner similar to a Fortran \cdf{FORMAT} statement
or a \cd{PL/I} \cd{PUT EDIT} statement. The most useful I/O operations,
however, read and write printed representations of arbitrary
Lisp objects.
Common Lisp содержит богатый функционал для выполнения операций ввода/вывода.
Все эти операции производятся на различного вида потоках.
Данная глава посвящена тому, как оперировать данными в потоках.
Потоки обсуждаются в главе~\ref{STREAM}, а способы работы с файлами
через потоки в главе~\ref{FILES}.
Большинство операций ввода/вывода в Common Lisp'е читают и записывают
буквы, но также есть функции и для бинарных данных. Есть
простые примитивы для чтения и записи одного символа или строк
данных. Функция \cdf{format} может выполнять сложное форматирование
выходных данных, с помощью управляющей строки как в выражении
\cdf{FORMAT} в Fortran'е или в \cd{PUT EDIT} в \cd{PL/I}. Однако,
самые полезные операции ввода/вывода читают и записывает выводимые
представления произвольных Lisp'овых объектов.
\section{Printed Representation of Lisp Objects}
%\section{Строковое представление Lisp'овых объектов}
Lisp objects in general are not text strings but complex data structures.
They have very different properties from text strings as a consequence of
their internal representation. However, to make it possible to get at
and talk about Lisp objects, Lisp provides a representation of
most objects in the form of printed text; this is called the \emph{printed
representation}, which is used for input/output purposes and in the
examples throughout this book. Functions such as \cdf{print} take a
Lisp object and send the characters of its printed representation to a
stream. The collection of routines that does this is known as the
(Lisp) \emph{printer}. The \cdf{read} function takes characters from a
stream, interprets them as a printed representation of a Lisp object,
builds that object, and returns it; the collection of routines
that does this is called the (Lisp) \emph{reader}.
\indexterm{printer}
\indexterm{printed representation}
\indexterm{reader}
В общем случае Lisp'овые объекты являются не строками, а сложными структурами
данных. Как следствие их внутреннего представления, свойства этих объектов
очень отличается от свойств строк. Однако, для того, чтобы можно было
повествовать о Lisp'овых объектах, Lisp большинство объектов отображает в форме
текста. Это называется \emph{строковое представление}, которое используется для
ввода/вывода, а также в примерах в данной книге. Такие функции, как \cdf{print},
принимают Lisp'овый объект и посылают строку представления
в поток. Коллекция этих функций называется (Lisp'овым) \emph{принтером}. Функция
\cdf{read} принимает буквы из потока, интерпретирует их как
представление некоторого Lisp'ового объекта, создаёт этот объект и возвращает
его. Коллекция этих функций называется (Lisp'овым) \emph{считывателем}.
\indexterm{printer}
\indexterm{printed representation}
\indexterm{reader}
Ideally, one could print a Lisp object and
then read the printed representation back in, and so obtain the same identical
object. In practice this is difficult and for some purposes not even desirable.
Instead, reading a printed representation produces an object that is (with
obscure technical exceptions) \cdf{equal} to the originally printed object.
В идеале, можно вывести Lisp'овый объект, а затем прочесть его обратно и
получить идентичный первому объект. На практике это сделать сложнее, а в
некоторых случаях это и не желательно. Вместо этого, считывание выводимого
представления создаёт объект, который равен \cdf{equal} оригинальному объекту.
Most Lisp objects have more than one possible printed representation.
For example, the integer twenty-seven can be written in any of these ways:
\begin{lisp}
27~~~~27.~~~~\#o33~~~~\#x1B~~~~\#b11011~~~~\#.(* 3 3 3)~~~~81/3
\end{lisp}
A list of two symbols \cdf{A} and \cdf{B} can be printed in many ways:
\begin{lisp}
~~~~(A B)~~~~(a b)~~~~(~~a~~b~)~~~~({\Xbackslash}A |B|) \\
~~~~(|{\Xbackslash}A| \\
~~B \\
)
\end{lisp}
The last example, which is spread over three lines, may be ugly, but it
is legitimate. In general, wherever whitespace is permissible in a printed
representation, any number of spaces and newlines may appear.
Большинство Lisp'овых объектов имеют более одного представления. Например, целое
число двадцать семь может быть записано одним из способов:
\begin{lisp}
27~~~~27.~~~~\#o33~~~~\#x1B~~~~\#b11011~~~~\#.(* 3 3 3)~~~~81/3
\end{lisp}
Список двух символов \cdf{A} и \cdf{B} может быть записан в виде:
\begin{lisp}
~~~~(A B)~~~~(a b)~~~~(~~a~~b~)~~~~({\Xbackslash}A |B|) \\
~~~~(|{\Xbackslash}A| \\
~~B \\
)
\end{lisp}
Последний пример, который занимает три строки, может и некрасив, но вполне
законен. В общем случае, везде в представлении, где разрешены пробелы, может
встречаться любое количество пробелов или знаков перевода строки.
When \cdf{print} produces a printed representation, it must choose arbitrarily
from among many possible printed representations. It attempts to choose
one that is readable. There are a number of global variables that can
be used to control the actions of \cdf{print}, and a number of different
printing functions.
Когда \cdf{print} выводит представление объекта, она должна произвольно выбрать
одно из возможных представлений. Она пытается выбрать то, которое может быть
прочитано считывателем. В Common Lisp'е представлено некоторое количество
глобальных переменных, которые могут изменять поведение \cdf{print}, и некоторое
количество различных функций для вывода.
This section describes in detail what is the standard printed
representation for any Lisp object and also describes how \cdf{read} operates.
Этот раздел детально описывает, что является стандартным выводимым
представлением для любого Lisp'ового объекта, и также описывает то, как работает
\cdf{read}.
\subsection{What the Read Function Accepts}
\label{READER}
\indexterm{reader}
%\subsection{Что принимает функция read}
%\label{READER}
%\indexterm{reader}
The purpose of the Lisp reader is to accept characters, interpret them
as the printed representation of a Lisp object, and construct and
return such an object. The reader cannot accept everything that the
printer produces; for example, the printed representations of compiled
code objects cannot be read in. However, the reader has
many features that are not used by the output of the printer at all,
such as comments, alternative representations, and convenient
abbreviations for frequently used but unwieldy constructs. The reader is
also parameterized in such a way that it can be used as a lexical
analyzer for a more general user-written parser.
Целью Lisp'ового считывателя (ридера) является чтение строки,
интерпретация как Lisp'ового объекта, создание и возврат этого
объекта. Считыватель (ридер) не может прочесть все возможные
выводимые представления объектов, например невозможно прочесть
представление скомпилированного кода. Однако считыватель (ридер)
содержит много таких возможностей, которые не используются при
выводе. К ним относятся комментарии, альтернативные представления и
удобные аббревиатуры для часто используемых, но тяжеловесных
конструкций. Считыватель также может быть настроен так, чтобы
использоваться в качестве лексического анализатора для более общих
пользовательских парсеров.
The reader is organized as a recursive-descent parser.
Broadly speaking,
the reader operates by reading a character from
the input stream and treating it in one of three ways.
Whitespace characters serve as separators but are otherwise
ignored. Constituent and escape characters are accumulated
to make a \emph{token}, which is then interpreted as a number or symbol.
Macro characters trigger the invocation of functions (possibly
user-supplied) that can perform arbitrary parsing actions,
including recursive invocation of the reader.
Считыватель выполнен как рекурсивный нисходящий парсер. Проще говоря,
считыватель считывает букву из входящего потока и обрабатывает его
одним из трёх способов. Пробельные буквы расцениваются как
разделители, более одного игнорируются. Обычные и экранирующие буквы
накапливаются и составляют \emph{токен}, которые затем интерпретирует как число
или символ. Макросимволы запускают (вызывают) функцию (возможно
пользовательскую), которая выполняет произвольный парсинг, которые может
содержать рекурсивный вызов считывателя.
More precisely,
when the reader is invoked, it reads a single character from the input stream
and dispatches according to the syntactic type of that character.
Every character that can appear in the input stream
must be of exactly one of the following kinds:
\emph{illegal},
\emph{whitespace},
\emph{constituent},
\emph{single escape},
\emph{multiple escape}, or
\emph{macro}.
Macro characters are further divided
into the types \emph{terminating} and \emph{non-terminating} (of tokens).
(Note that macro characters have nothing whatever to do with macros
in their operation. There is a superficial similarity in that macros allow
the user to extend the syntax of Common Lisp at the level of forms,
while macro characters allow the user to extend the syntax at the
level of characters.)
Constituents additionally have one or more attributes,
the most important of which is \emph{alphabetic}; these attributes are discussed
further in section~\ref{PARSE-TOKENS-SECTION}.
Более точное описание: когда вызывается считыватель, он читает один строковый
символ из входящего потока и действует в зависимости от типа данного символа.
Каждый символ, который может встретиться во входящем потоке должен принадлежать
только определённым типам:
\emph{некорректный},
\emph{пробельный},
\emph{обычный},
\emph{одиночный экранирующий},
\emph{много экранирующий}, or
\emph{макросимвол}.
Макросимволы в свою очередь делятся на \emph{терминальные} и
\emph{нетерминальные}. (Следует отметить, что макросимволы не имеют ничего
общего с макросами. Подобие заключается в том, что макросы позволяют расширить
синтаксис Common Lisp'а на уровне форм, тогда как макросимволы позволяют
расширить синтаксис на уровне букв.)
Обычные символы имеют один или более атрибутов, наиболее важный из них это
\emph{алфавитный}. Эти атрибуты описаны далее в разделе~\ref{PARSE-TOKENS-SECTION}.
The parsing of Common Lisp expressions is discussed in terms of these
syntactic character types because the types of individual characters
are not fixed
but may be altered by the user (see \cdf{set-syntax-from-char}
and \cdf{set-macro-character}).
The characters of the standard character set initially have the
syntactic types shown in table~\ref{Standard-Character-Syntax-Table}.
Note that
the brackets, braces, question mark, and exclamation point
(that is, \cd{{\Xlbracket}}, \cd{{\Xrbracket}}, \cd{{\Xlbrace}},
\cd{{\Xrbrace}}, \cd{?},
and \cd{!}) are normally defined to be constituents, but they
are not used for any purpose in standard Common Lisp syntax and do not occur
in the names of built-in Common Lisp functions or variables.
These characters are explicitly reserved to the user.
The primary intent
is that they be used as macro characters; but a user might choose,
for example, to make \cd{!} be a \emph{single escape} character
(as it is in Portable Standard Lisp).
Парсинг Common Lisp'овых выражений описан в терминах типов синтаксических
символов, так как типы отдельных символов не фиксированы и могут быть изменены
пользователем (смотрите \cdf{set-syntax-from-char} и \cdf{set-macro-character}).
Символы из стандартного множества имеют типы указанные в
таблице~\ref{Standard-Character-Syntax-Table}. Следует отметить, что
квадратные, фигурные скобки, вопросительные знак и восклицательный знак (то
есть, \cd{{\Xlbracket}}, \cd{{\Xrbracket}}, \cd{{\Xlbrace}}, \cd{{\Xrbrace}},
\cd{?}, и \cd{!}) являются обычными символами, но они не используются в
стандартном Common Lisp'е и не встречаются в именах системных функций и
переменных. Эти символы явно зарезервированы для нужд пользователя. Главная
цель в том, чтобы использовать эти символы в качестве макросимволов, но
пользователь также может, например, сделать символ \cd{!} \emph{одиночным
экранирующим} символом (как в Portable Standard Lisp).
\begin{table}
\caption{Standard Character Syntax Types}
\label{Standard-Character-Syntax-Table}
\begin{tabular*}{\textwidth}{@{}l@{\extracolsep{\fill}}ll@{}}
$\langle$tab$\rangle$\cd{~~}\emph{whitespace}&$\langle$page$\rangle$\cd{~~}\emph{whitespace}&$\langle$newline$\rangle$\cd{~~}\emph{whitespace} \\
$\langle$space$\rangle$\cd{~~}\emph{whitespace}&\cd{{\Xatsign}~~}\emph{constituent}&\cd{{\Xbq}~~}\emph{terminating macro} \\
\cd{!~~}\emph{constituent} *&\cd{A~~}\emph{constituent}&\cd{a~~}\emph{constituent} \\
\cd{"~~}\emph{terminating macro}&\cd{B~~}\emph{constituent}&\cd{b~~}\emph{constituent} \\
\cd{\#~~}\emph{non-terminating macro}&\cd{C~~}\emph{constituent}&\cd{c~~}\emph{constituent} \\
\cd{\$~~}\emph{constituent}&\cd{D~~}\emph{constituent}&\cd{d~~}\emph{constituent} \\
\cd{\%~~}\emph{constituent}&\cd{E~~}\emph{constituent}&\cd{e~~}\emph{constituent} \\
\cd{\&~~}\emph{constituent}&\cd{F~~}\emph{constituent}&\cd{f~~}\emph{constituent} \\
\cd{'~~}\emph{terminating macro}&\cd{G~~}\emph{constituent}&\cd{g~~}\emph{constituent} \\
\cd{(~~}\emph{terminating macro}&\cd{H~~}\emph{constituent}&\cd{h~~}\emph{constituent} \\
\cd{)~~}\emph{terminating macro}&\cd{I~~}\emph{constituent}&\cd{i~~}\emph{constituent} \\
\cd{*~~}\emph{constituent}&\cd{J~~}\emph{constituent}&\cd{j~~}\emph{constituent} \\
\cd{+~~}\emph{constituent}&\cd{K~~}\emph{constituent}&\cd{k~~}\emph{constituent} \\
\cd{,~~}\emph{terminating macro}&\cd{L~~}\emph{constituent}&\cd{l~~}\emph{constituent} \\
\cd{-~~}\emph{constituent}&\cd{M~~}\emph{constituent}&\cd{m~~}\emph{constituent} \\
\cd{.~~}\emph{constituent}&\cd{N~~}\emph{constituent}&\cd{n~~}\emph{constituent} \\
\cd{/~~}\emph{constituent}&\cd{O~~}\emph{constituent}&\cd{o~~}\emph{constituent} \\
\cd{0~~}\emph{constituent}&\cd{P~~}\emph{constituent}&\cd{p~~}\emph{constituent} \\
\cd{1~~}\emph{constituent}&\cd{Q~~}\emph{constituent}&\cd{q~~}\emph{constituent} \\
\cd{2~~}\emph{constituent}&\cd{R~~}\emph{constituent}&\cd{r~~}\emph{constituent} \\
\cd{3~~}\emph{constituent}&\cd{S~~}\emph{constituent}&\cd{s~~}\emph{constituent} \\
\cd{4~~}\emph{constituent}&\cd{T~~}\emph{constituent}&\cd{t~~}\emph{constituent} \\
\cd{5~~}\emph{constituent}&\cd{U~~}\emph{constituent}&\cd{u~~}\emph{constituent} \\
\cd{6~~}\emph{constituent}&\cd{V~~}\emph{constituent}&\cd{v~~}\emph{constituent} \\
\cd{7~~}\emph{constituent}&\cd{W~~}\emph{constituent}&\cd{w~~}\emph{constituent} \\
\cd{8~~}\emph{constituent}&\cd{X~~}\emph{constituent}&\cd{x~~}\emph{constituent} \\
\cd{9~~}\emph{constituent}&\cd{Y~~}\emph{constituent}&\cd{y~~}\emph{constituent} \\
\cd{:~~}\emph{constituent}&\cd{Z~~}\emph{constituent}&\cd{z~~}\emph{constituent} \\
\cd{;~~}\emph{terminating macro}&\cd{{\Xlbracket}~~}\emph{constituent} *&\cd{{\Xlbrace}~~}\emph{constituent} * \\
\cd{<~~}\emph{constituent}&\cd{{\Xbackslash}~~}\emph{single escape}&\cd{|~~}\emph{multiple escape} \\
\cd{=~~}\emph{constituent}&\cd{{\Xrbracket}~~}\emph{constituent} *&\cd{{\Xrbrace}~~}\emph{constituent} * \\
\cd{>~~}\emph{constituent}&\cd{{\Xcircumflex}~~}\emph{constituent}&\cd{{\Xtilde}~~}\emph{constituent} \\
\cd{?~~}\emph{constituent} *&\cd{{\Xunderscore}~~}\emph{constituent}&$\langle$rubout$\rangle$\cd{~~}\emph{constituent} \\
$\langle$backspace$\rangle$\cd{~~}\emph{constituent}&$\langle$return$\rangle$\cd{~~}\emph{whitespace}&$\langle$linefeed$\rangle$\cd{~~}\emph{whitespace}
\end{tabular*}
\vfill
\begin{small}
\noindent
The characters marked with an asterisk are initially constituents
but are reserved to the user for use as macro characters or for
any other desired purpose.
\end{small}
\end{table}
\begin{table}
\caption{Стандартные типы символьного синтаксиса}
\label{Standard-Character-Syntax-Table}
\begin{tabular*}{\textwidth}{@{}l@{\extracolsep{\fill}}ll@{}}
$\langle$tab$\rangle$\cd{~~}\emph{пробел}&$\langle$page$\rangle$\cd{~~}\emph{пробел}&$\langle$newline$\rangle$\cd{~~}\emph{пробел} \\
$\langle$space$\rangle$\cd{~~}\emph{пробел}&\cd{{\Xatsign}~~}\emph{обычный}&\cd{{\Xbq}~~}\emph{терминальный макрос} \\
\cd{!~~}\emph{обычный} *&\cd{A~~}\emph{обычный}&\cd{a~~}\emph{обычный} \\
\cd{"~~}\emph{терминальный макрос}&\cd{B~~}\emph{обычный}&\cd{b~~}\emph{обычный} \\
\cd{\#~~}\emph{не-терминальный макрос}&\cd{C~~}\emph{обычный}&\cd{c~~}\emph{обычный} \\
\cd{\$~~}\emph{обычный}&\cd{D~~}\emph{обычный}&\cd{d~~}\emph{обычный} \\
\cd{\%~~}\emph{обычный}&\cd{E~~}\emph{обычный}&\cd{e~~}\emph{обычный} \\
\cd{\&~~}\emph{обычный}&\cd{F~~}\emph{обычный}&\cd{f~~}\emph{обычный} \\
\cd{'~~}\emph{терминальный макрос}&\cd{G~~}\emph{обычный}&\cd{g~~}\emph{обычный} \\
\cd{(~~}\emph{терминальный макрос}&\cd{H~~}\emph{обычный}&\cd{h~~}\emph{обычный} \\
\cd{)~~}\emph{терминальный макрос}&\cd{I~~}\emph{обычный}&\cd{i~~}\emph{обычный} \\
\cd{*~~}\emph{обычный}&\cd{J~~}\emph{обычный}&\cd{j~~}\emph{обычный} \\
\cd{+~~}\emph{обычный}&\cd{K~~}\emph{обычный}&\cd{k~~}\emph{обычный} \\
\cd{,~~}\emph{терминальный макрос}&\cd{L~~}\emph{обычный}&\cd{l~~}\emph{обычный} \\
\cd{-~~}\emph{обычный}&\cd{M~~}\emph{обычный}&\cd{m~~}\emph{обычный} \\
\cd{.~~}\emph{обычный}&\cd{N~~}\emph{обычный}&\cd{n~~}\emph{обычный} \\
\cd{/~~}\emph{обычный}&\cd{O~~}\emph{обычный}&\cd{o~~}\emph{обычный} \\
\cd{0~~}\emph{обычный}&\cd{P~~}\emph{обычный}&\cd{p~~}\emph{обычный} \\
\cd{1~~}\emph{обычный}&\cd{Q~~}\emph{обычный}&\cd{q~~}\emph{обычный} \\
\cd{2~~}\emph{обычный}&\cd{R~~}\emph{обычный}&\cd{r~~}\emph{обычный} \\
\cd{3~~}\emph{обычный}&\cd{S~~}\emph{обычный}&\cd{s~~}\emph{обычный} \\
\cd{4~~}\emph{обычный}&\cd{T~~}\emph{обычный}&\cd{t~~}\emph{обычный} \\
\cd{5~~}\emph{обычный}&\cd{U~~}\emph{обычный}&\cd{u~~}\emph{обычный} \\
\cd{6~~}\emph{обычный}&\cd{V~~}\emph{обычный}&\cd{v~~}\emph{обычный} \\
\cd{7~~}\emph{обычный}&\cd{W~~}\emph{обычный}&\cd{w~~}\emph{обычный} \\
\cd{8~~}\emph{обычный}&\cd{X~~}\emph{обычный}&\cd{x~~}\emph{обычный} \\
\cd{9~~}\emph{обычный}&\cd{Y~~}\emph{обычный}&\cd{y~~}\emph{обычный} \\
\cd{:~~}\emph{обычный}&\cd{Z~~}\emph{обычный}&\cd{z~~}\emph{обычный} \\
\cd{;~~}\emph{терминальный макрос}&\cd{{\Xlbracket}~~}\emph{обычный} *&\cd{{\Xlbrace}~~}\emph{обычный} * \\
\cd{<~~}\emph{обычный}&\cd{{\Xbackslash}~~}\emph{экранирующий один}&\cd{|~~}\emph{экранирующий много} \\
\cd{=~~}\emph{обычный}&\cd{{\Xrbracket}~~}\emph{обычный} *&\cd{{\Xrbrace}~~}\emph{обычный} * \\
\cd{>~~}\emph{обычный}&\cd{{\Xcircumflex}~~}\emph{обычный}&\cd{{\Xtilde}~~}\emph{обычный} \\
\cd{?~~}\emph{обычный} *&\cd{{\Xunderscore}~~}\emph{обычный}&$\langle$rubout$\rangle$\cd{~~}\emph{обычный} \\
$\langle$backspace$\rangle$\cd{~~}\emph{обычный}&$\langle$return$\rangle$\cd{~~}\emph{пробел}&$\langle$linefeed$\rangle$\cd{~~}\emph{пробел}
\end{tabular*}
\vfill
\begin{small}
\noindent
Символы помеченные звездочкой первоначально являются составной частью, но
зарезервированы для пользователя в качестве использования макросимволов или для
других целей.
\end{small}
\end{table}
The algorithm performed by the Common Lisp reader is roughly as follows:
Алгоритм, выполняемый Common Lisp'овым считывателем, примерно такой:
\begingroup\leftmargini 1.5em
\begin{enumerate}
\item
If at end of file, perform end-of-file processing (as specified
by the caller of the \cdf{read} function).
Otherwise,
read one character from the input stream, call it \emph{x}, and
dispatch according to the syntactic type of \emph{x} to one
of steps~\ref{READER-ILLEGAL} to~\ref{READER-CONSTITUENT}.
\label{READER-START}
\item Если достигнут конец файл, обработать эту ситуацию так как
указал вызвавший функцию \cdf{read}. В противном случае, прочесть
один символ из входящего потока, назвать его \emph{x}, и обработать
в соответствии с синтаксическим типом \emph{x} одним из
способов~\ref{READER-ILLEGAL} или~\ref{READER-CONSTITUENT}.
\label{READER-START}
\item
If \emph{x} is an \emph{illegal} character, signal an error.
\label{READER-ILLEGAL}
\item Если \emph{x} является \emph{некорректным} символом,
сигнализировать ошибку.
\label{READER-ILLEGAL}
\item
If \emph{x} is a \emph{whitespace} character,
then discard it and go back to step~\ref{READER-START}.
\label{READER-WHITESPACE}
\item Если \emph{x} является \emph{пробелом}, игнорировать его и
вернуться на шаг~\ref{READER-START}.
\label{READER-WHITESPACE}
\item
If \emph{x} is a \emph{macro} character (at this point the
distinction between \emph{terminating} and \emph{non-terminating} macro characters
does not matter), then execute the function associated
with that character. The function may return zero values or one value
(see \cdf{values}).
The macro-character function may of course read characters from the input
stream; if it does, it will see those characters following the macro
character. The function may even invoke the reader recursively.
This is how the macro character \cd{(} constructs a list:
by invoking the reader recursively to read the elements of the list.
If one value is returned, then return that value as the result of the
read operation; the algorithm is done.
If zero values are returned, then go back to step~\ref{READER-START}.
\item Если \emph{x} является \emph{макросимволом} (в данном случае
различие между \emph{терминальным} и \emph{нетерминальным})
макросимволами не имеет значения), тогда вызвать функцию связанную с
этим макросимволом. Функция может вернуть ноль или одно значение
(смотрите \cdf{values}).
Функция связанная с макросимволом, конечно, может считывать символы из
входящего потока, в этом случае она увидит символы, идущие после
данного макросимвола. Функция даже может рекурсивно вызвать
считыватель. Это например способ, которым создаётся список для
макросимвола \cd{(}: рекурсивным вызовом считывателя для каждого
элемента списка.
Если функция вернула одно значение, тогда это значение возвращается
в качестве результата операции чтения, алгоритм выполнен. Если
функция не вернула значений, тогда приходит шаг~\ref{READER-START}.
\item
If \emph{x} is a \emph{single escape} character (normally \cd{{\Xbackslash}}),
then read the next character and call it \emph{y}
(but if at end of file, signal an error instead).
Ignore the usual syntax of \emph{y}
and pretend it is a \emph{constituent} whose only attribute is
\emph{alphabetic}.
For the purposes of \cdf{readtable-case}, \emph{y} is not replaceable.
Use \emph{y} to begin a token, and go to step~\ref{READER-PLAIN-TOKEN}.
\item Если \emph{x} является \emph{одиночным экранирующим символом}
(обычно это \cd{{\Xbackslash}}), тогда считать следующий символ и
называеть его \emph{y} (но если был конец файла, сигнализировать
ошибка). Игнорировать обычный синтаксис \emph{y}, и трактовать его
как \emph{обычный}, у которого только \emph{алфавитный} атрибут.
В целях использования \cdf{readtable-case}, \emph{y} является незамещаемым.
Использовать \emph{y} для начала токена, и перейти к
шагу~\ref{READER-PLAIN-TOKEN}.
\item
If \emph{x} is a \emph{multiple escape} character (normally \cd{|}),
then begin a token (initially
containing no characters) and go to step~\ref{READER-MULTI-TOKEN}.
\item Если \emph{x} является \emph{много экранирующим символом}
(обычно \cd{|}), тогда начать запись токена (первоначально нулевой
длины) и перейти к шагу~\ref{READER-MULTI-TOKEN}.
\item
If \emph{x} is a \emph{constituent} character, then it begins an extended token.
\label{READER-CONSTITUENT}\relax
After the entire token is read in, it will be interpreted
either as representing a Lisp object such as a symbol or number
(in which case that object is returned as the result of the read operation),
or as being of illegal syntax (in which case an error is signaled).
The case of \emph{x\/} should not be altered; instead,
\emph{x} should be regarded as replaceable.
Use \emph{x} to begin a token, and go on to step~\ref{READER-PLAIN-TOKEN}.
\item Если \emph{x} \emph{обычный} символ, тогда начать запись расширенного токена.
\label{READER-CONSTITUENT}\relax
После того как токен был считан, он будет интерпретирован как
представление Lisp'ового объекта: или символа, или числа (в этом
случае объект будет возвращён как результат функции чтения), или как
некорректный синтаксис (в этом случае будет сигнализирована ошибка).
Регистр символа \emph{x} не должен меняться, вместо этого \emph{x}
помечается как замещаемый.
Использовать \emph{x} для токена, и перейти к шагу~\ref{READER-PLAIN-TOKEN}.
\item
(At this point a token is being accumulated, and an even number
of \emph{multiple escape} characters have been encountered.)
If at end of file, go to step~\ref{READER-TOKEN-END}.
Otherwise, read a character (call it \emph{y}), and
perform one of the following actions according to its syntactic type:
\label{READER-PLAIN-TOKEN}
\item (В данной точке начинается запись токена, и FIXME ) Если конец файла, перейти к
шагу~\ref{READER-TOKEN-END}. Иначе прочесть символ (назвать его
\emph{y}), и выполнить одно из следующих действий в зависимости от
синтаксического типа:
\label{READER-PLAIN-TOKEN}
\begin{itemize}
\item
If \emph{y} is a \emph{constituent} or \emph{non-terminating macro},
then do the following.
The case of \emph{y\/} should not be altered; instead,
\emph{y} should be regarded as replaceable.
Append \emph{y} to the token being built,
and repeat step~\ref{READER-PLAIN-TOKEN}.
\item Если \emph{y} обычный или \emph{нетерминальный макросимвол},
тогда выполнить следующее.
Регистр \emph{y} не должен быть изменён, вместо этого \emph{y}
помечается как замещаемый.
Добавить \emph{y} в конец записываемого токена и повторить
шаг~\ref{READER-PLAIN-TOKEN}.
\item
If \emph{y} is a \emph{single escape} character, then read the next character
and call it \emph{z}
(but if at end of file, signal an error instead).
Ignore the usual syntax of \emph{z}
and pretend it is a \emph{constituent} whose only attribute is
\emph{alphabetic}.
For the purposes of \cdf{readtable-case}, \emph{z} is not replaceable.
Append \emph{z} to the token being built,
and repeat step~\ref{READER-PLAIN-TOKEN}.
\item Если \emph{y} является \emph{одинарным экранирующим символом},
тогда прочесть следующий символ и назвать его \emph{z} (но если это
конец файла, сигнализировать ошибку). Игнорировать обычный
синтаксис \emph{z} и трактовать его как \emph{обычный} символ, а
которого только \emph{алфавитный} атрибут.
В целях функции \cdf{readtable-case}, \emph{z} не является замещаемым.
Добавить \emph{z} в конец записываемого токена и повторить
шаг~\ref{READER-PLAIN-TOKEN}.
\item
If \emph{y} is a \emph{multiple escape} character,
then go to step~\ref{READER-MULTI-TOKEN}.
\item Если \emph{y} это \emph{много экранирующий символ}, тогда
перейти к шагу~\ref{READER-MULTI-TOKEN}.
\item
If \emph{y} is an \emph{illegal} character, signal an error.
\item Если \emph{y} это \emph{некорректный символ}, сигнализировать
ошибку.
\item
If \emph{y} is a \emph{terminating macro} character, it terminates
the token. First ``unread'' the character \emph{y}
(see \cdf{unread-char}), then go to step~\ref{READER-TOKEN-END}.
\item Если \emph{y} это \emph{терминальный макросимвол}, он завершает
запись токена. Сначала <<отменить>> чтение символа \emph{y}
(смотрите \cdf{unread-char}), затем перейти к шагу~\ref{READER-TOKEN-END}.
\item
If \emph{y} is a \emph{whitespace} character, it terminates
the token. First ``unread'' \emph{y}
if appropriate (see \cdf{read-preserving-whitespace}),
then go to step~\ref{READER-TOKEN-END}.
\item Если \emph{y} это \emph{пробел}, он завершает запись
токена. Сначала, если необходимо (смотрите
\cdf{read-preserving-whitespace}) <<отменить>> чтение \emph{y},
затем перейти к шагу~\ref{READER-TOKEN-END}.
\end{itemize}
\item
(At this point a token is being accumulated, and an odd number
of \emph{multiple escape} characters have been encountered.)
If at end of file, signal an error.
Otherwise, read a character (call it \emph{y}), and
perform one of the following actions according to its syntactic type:
\label{READER-MULTI-TOKEN}
\item (В данной точке начинается запись токена, и FIXME ) Если конец
файла, сигнализировать ошибку. Иначе прочесть символ (назвать его
\emph{y}), и выполнить одно из следующих действий в зависимости от
синтаксического типа:
\label{READER-MULTI-TOKEN}
\begin{itemize}
\item
If \emph{y} is a \emph{constituent}, \emph{macro}, or \emph{whitespace}
character, then ignore the usual syntax of that character
and pretend it is a \emph{constituent} whose only attribute is
\emph{alphabetic}.
For the purposes of \cdf{readtable-case}, \emph{y} is not replaceable.
Append \emph{y} to the token being built,
and repeat step~\ref{READER-MULTI-TOKEN}.
\item Если \emph{y} \emph{обычный}, \emph{макросимвол} или
\emph{пробел}, тогда игнорировать обычный синтаксис данного символа
и трактовать его как \emph{обычный}, у которого есть только
\emph{алфавитный} атрибут.
\item
If \emph{y} is a \emph{single escape} character, then read the next character
and call it \emph{z}
(but if at end of file, signal an error instead).
Ignore the usual syntax of \emph{z}
and pretend it is a \emph{constituent} whose only attribute is
\emph{alphabetic}.
For the purposes of \cdf{readtable-case}, \emph{z} is not replaceable.
Append \emph{z} to the token being built,
and repeat step~\ref{READER-MULTI-TOKEN}.
\item Если \emph{y} \emph{одинарный экранирующий символ}, тогда
прочесть следующий символ и назвать его \emph{z} (но если конец
файла, сигнализировать ошибку). Игнорировать обычный синтаксис
\emph{z} и трактовать его как \emph{обычный} символ, у которого
только \emph{алфавитный атрибут}.
Для функции \cdf{readtable-case} \emph{z} незамещаемый.
Добавить \emph{z} в конец записываемого токена и повторить
шаг~\ref{READER-MULTI-TOKEN}.
\item
If \emph{y} is a \emph{multiple escape} character,
then go to step~\ref{READER-PLAIN-TOKEN}.
\item Если \emph{y} \emph{много экранирующий символ}, тогда перейти к
шагу~\ref{READER-PLAIN-TOKEN}.
\item
If \emph{y} is an \emph{illegal} character, signal an error.
\item Если \emph{y} \emph{некорректный символ}, сигнализировать ошибку.
\end{itemize}
\item
An entire token has been accumulated.
\begin{newer}
X3J13 voted in June 1989 \issue{READ-CASE-SENSITIVITY} to introduce
\cdf{readtable-case}. If the accumulated token
is to be interpreted as a symbol, any case conversion of replaceable
characters should be performed at this point according to the value
of the \cdf{readtable-case} slot of the current readtable (the value
of \cdf{*readtable*}).
\end{newer}
Interpret the token as representing
a Lisp object and return that object as the result
of the read operation, or signal an error if the token
is not of legal syntax.
\begin{newer}
X3J13 voted in March 1989 \issue{CHARACTER-PROPOSAL}
to specify that implementation-defined
attributes may be removed from the characters of a symbol token
when constructing the print name.
It is implementation-dependent which attributes are removed.
\end{newer}
\label{READER-TOKEN-END}
\item Данный токен был записан. Если записанный токен трактуется как
символ, в данной точке, если указано в слоте \cdf{readtable-case}
текущей таблицы чтения из переменной \cdf{*readtable*}, все
заменяемые символы должны быть возведены в верхний регистр.
Интерпретировать токен как представление Lisp'ового объекта и
вернуть этот объект в качестве результата операции чтения, или
сигнализировать ошибку, если у токена некорректный синтаксис.
\label{READER-TOKEN-END}
\end{enumerate}
\endgroup
As a rule, a \emph{single escape} character never stands for itself but always
serves to cause the following character to be treated as a simple alphabetic
character. A \emph{single escape} character can be included in a token only
if preceded by another \emph{single escape} character.
Как правило. \emph{одинарный экранирующий символ} никогда не стоит сам
по себе, а всегда указывает, что следующий символ нужно трактовать,
как \emph{обычный алфавитный символ}. \emph{Одинарный экранирующий
символ} можно включить в токен только с помощью другого
\emph{одинарного экранирующего символа}.
A \emph{multiple escape} character also never stands for itself. The characters
between a pair of \emph{multiple escape} characters are all treated as
simple alphabetic characters, except that \emph{single escape} and
\emph{multiple escape} characters must nevertheless be preceded by
a \emph{single escape} character to be included.
\emph{Много экранирующий символ} также никогда не стоит сам по
себе. Все символы между парой \emph{много экранирующих символов}
трактуются как \emph{обычный алфавитные символы}, за исключением
\emph{одинарного экранирующего символа}, и \emph{много экранирующий
символ} FIXME
\subsection{Parsing of Numbers and Symbols}
\label{PARSE-TOKENS-SECTION}
%\subsection{Считывание чисел и символов}
%\label{PARSE-TOKENS-SECTION}
When an extended token is read, it is interpreted as a number or symbol.
In general, the token is interpreted as a number if it satisfies
the syntax for numbers specified in table~\ref{NUMBER-SYNTAX-TABLE};
this is discussed in more detail below.
The characters of the extended token may serve various syntactic
functions as shown
in table~\ref{Standard-Readtable-Attributes-Table}, but it must be
remembered that any character included in a token under the control
of an escape character is treated as \emph{alphabetic} rather than
according to the attributes shown in the table.
One consequence of this rule is that a whitespace, macro, or escape
character will always be treated as alphabetic within an extended token
because such a character cannot be included in an extended
token except under the control of an escape character.
To allow for extensions to the syntax of numbers, a
syntax for \emph{potential numbers} is defined in Common Lisp that is
more general than the actual syntax for numbers.
Any token that is not a potential number and does not consist
entirely of dots will always be taken to be a symbol,
now and in the future; programs may rely on this fact.
Any token that is a potential number but does not fit the
actual number syntax defined below is a \emph{reserved token} and
has an implementation-dependent interpretation;
an implementation may signal an error, quietly treat the token
as a symbol, or take some other action. Programmers should avoid
the use of such reserved tokens. (A symbol whose name looks like a reserved
token can always be written using one or more escape characters.)
Just as \emph{bignum} is the standard term used by Lisp implementors for
very large integers, and \emph{flonum} (rhymes with ``low hum'') refers
to a floating-point number, the term \emph{potnum} has been used widely
as an abbreviation for ``potential number.'' ``Potnum'' rhymes with ``hot rum.''
\goodbreak
A token is a potential number if it satisfies the following
requirements:
\begin{table}[t]
\caption{Actual Syntax of Numbers}
\label{NUMBER-SYNTAX-TABLE}
\tabbingsep=0pt
\normalsize
\begin{tabbing}
\emph{number} ::= \emph{integer} {\Mor} \emph{ratio} {\Mor} \emph{floating-point-number} \\
\emph{integer} ::= \Mopt{\emph{sign}} \Mplus{\emph{digit}} \Mopt{\emph{decimal-point}} \\
\emph{ratio} ::= \Mopt{\emph{sign}} \Mplus{\emph{digit}} \cdf{/} \Mplus{\emph{digit}} \\
\emph{floating-point-number} ::=\= \Mopt{\emph{sign}} \Mstar{\emph{digit}} \emph{decimal-point} \Mplus{\emph{digit}} \Mopt{\emph{exponent}} \\
\>{\Mor} \'\Mopt{\emph{sign}} \Mplus{\emph{digit}} \Mopt{\emph{decimal-point}
\Mstar{\emph{digit}}} \emph{exponent} \\ \emph{sign} ::= \cdf{+} {\Mor} \cdf{-} \\
\emph{decimal-point} ::= \cd{.} \\
\emph{digit} ::= \cd{0} {\Mor} \cd{1} {\Mor} \cd{2} {\Mor} \cd{3} {\Mor} \cd{4}
{\Mor} \cd{5} {\Mor} \cd{6} {\Mor} \cd{7} {\Mor} \cd{8} {\Mor} \cd{9} \\
\emph{exponent} ::= \emph{exponent-marker} \Mopt{\emph{sign}} \Mplus{\emph{digit}} \\
\emph{exponent-marker} ::= \cdf{e} {\Mor} \cdf{s} {\Mor} \cdf{f} {\Mor} \cdf{d} {\Mor} \cdf{l}
{\Mor} \cdf{E} {\Mor} \cdf{S} {\Mor} \cdf{F} {\Mor} \cdf{D} {\Mor} \cdf{L}
\end{tabbing}
\end{table}
\begin{itemize}
\item
It consists entirely of digits, signs (\cdf{+} or \cdf{-}),
ratio markers (\cdf{/}), decimal points (\cd{.}), extension characters
(\cd{{\Xcircumflex}} or \cd{{\Xunderscore}}), and number markers. (A number marker is
a letter. Whether a letter may be treated as a number marker depends
on context, but no letter that is adjacent to another letter may ever be
treated as a number marker. Floating-point exponent markers are instances
of number markers.)
\item
It contains at least one digit. (Letters may be considered to be
digits, depending on the value of \cd{*read-base*}, but only
in tokens containing no decimal points.)
\item
It begins with a digit, sign, decimal point, or extension character.
\item
It does not end with a sign.
\end{itemize}
As examples, the following tokens are potential numbers,
but they are \emph{not} actually numbers as defined below, and so are
reserved tokens. (They do indicate some interesting possibilities
for future extensions.)
\begin{table}
\caption{Standard Constituent Character Attributes}
\label{Standard-Readtable-Attributes-Table}
\begin{tabular*}{\textwidth}{@{\extracolsep{\fill}}l@{\extracolsep{\fill}}lllll@{}}
\cd{!}&\emph{alphabetic}&$\langle$page$\rangle$&\emph{illegal}&$\langle$backspace$\rangle$&\emph{illegal} \\
\cd{"}&\emph{alphabetic} *&$\langle$return$\rangle$&\emph{illegal} *&$\langle$tab$\rangle$&\emph{illegal} * \\
\cd{\#}&\emph{alphabetic} *&$\langle$space$\rangle$&\emph{illegal} *&$\langle$newline$\rangle$&\emph{illegal} * \\
\cd{\$}&\emph{alphabetic}&$\langle$rubout$\rangle$&\emph{illegal}&$\langle$linefeed$\rangle$&\emph{illegal} * \\
\cd{\%}&\emph{alphabetic}&\cd{.}&\multicolumn{3}{l}{\emph{alphabetic}, \emph{dot}, \emph{decimal point}}\\
\cd{\&}&\emph{alphabetic}&\cdf{+}&\multicolumn{3}{l}{\emph{alphabetic}, \emph{plus sign}} \\
\cd{'}&\emph{alphabetic} *&\cdf{-}&\multicolumn{3}{l}{\emph{alphabetic}, \emph{minus sign}} \\
\cd{(}&\emph{alphabetic} *&\cdf{*}&\emph{alphabetic} \\
\cd{)}&\emph{alphabetic} *&\cdf{/}&\multicolumn{3}{l}{\emph{alphabetic}, \emph{ratio marker}} \\
\cd{,}&\emph{alphabetic} *&\cd{{\Xatsign}}&\emph{alphabetic} \\
\cd{0}&\emph{alphadigit}&\cdf{A}, \cdf{a}&\emph{alphadigit} \\
\cd{1}&\emph{alphadigit}&\cdf{B}, \cdf{b}&\emph{alphadigit} \\
\cd{2}&\emph{alphadigit}&\cdf{C}, \cdf{c}&\emph{alphadigit} \\
\cd{3}&\emph{alphadigit}&\cdf{D}, \cdf{d}&\multicolumn{3}{l}{\emph{alphadigit}, \emph{double-float exponent marker}} \\
\cd{4}&\emph{alphadigit}&\cdf{E}, \cdf{e}&\multicolumn{3}{l}{\emph{alphadigit}, \emph{float exponent marker}} \\
\cd{5}&\emph{alphadigit}&\cdf{F}, \cdf{f}&\multicolumn{3}{l}{\emph{alphadigit}, \emph{single-float exponent marker}} \\
\cd{6}&\emph{alphadigit}&\cdf{G}, \cdf{g}&\emph{alphadigit} \\
\cd{7}&\emph{alphadigit}&\cdf{H}, \cdf{h}&\emph{alphadigit} \\
\cd{8}&\emph{alphadigit}&\cdf{I}, \cdf{i}&\emph{alphadigit} \\
\cd{9}&\emph{alphadigit}&\cdf{J}, \cdf{j}&\emph{alphadigit} \\
\cd{:}&\emph{package marker}~~~~~~&\cdf{K}, \cdf{k}&\emph{alphadigit} \\
\cd{;}&\emph{alphabetic} *&\cdf{L}, \cdf{l}&\multicolumn{3}{l}{\emph{alphadigit}, \emph{long-float exponent marker}} \\
\cdf{<}&\emph{alphabetic}&\cdf{M}, \cdf{m}&\emph{alphadigit} \\
\cdf{=}&\emph{alphabetic}&\cdf{N}, \cdf{n}&\emph{alphadigit} \\
\cdf{>}&\emph{alphabetic}&\cdf{O}, \cdf{o}&\emph{alphadigit} \\
\cd{?}&\emph{alphabetic}&\cdf{P}, \cdf{p}&\emph{alphadigit} \\
\cd{{\Xlbracket}}&\emph{alphabetic}&\cdf{Q}, \cdf{q}&\emph{alphadigit} \\
\cd{{\Xbackslash}}&\emph{alphabetic} *&\cdf{R}, \cdf{r}&\emph{alphadigit} \\
\cd{{\Xrbracket}}&\emph{alphabetic}&\cdf{S}, \cdf{s}&\multicolumn{3}{l}{\emph{alphadigit}, \emph{short-float exponent marker}} \\
\cd{{\Xcircumflex}}&\emph{alphabetic}&\cdf{T}, \cdf{t}&\emph{alphadigit} \\
\cd{{\Xunderscore}}&\emph{alphabetic}&\cdf{U}, \cdf{u}&\emph{alphadigit} \\
\cd{{\Xbq}}&\emph{alphabetic} *&\cdf{V}, \cdf{v}&\emph{alphadigit} \\
\cd{{\Xlbrace}}&\emph{alphabetic}&\cdf{W}, \cdf{w}&\emph{alphadigit} \\
\cd{|}&\emph{alphabetic} *&\cdf{X}, \cdf{x}&\emph{alphadigit} \\
\cd{{\Xrbrace}}&\emph{alphabetic}&\cdf{Y}, \cdf{y}&\emph{alphadigit} \\
\cd{{\Xtilde}}&\emph{alphabetic}&\cdf{Z}, \cdf{z}&\emph{alphadigit} \\
\end{tabular*}
\vfill
\begin{footnotesize}
\noindent
These interpretations apply only to characters whose
syntactic type is \emph{constituent}. Entries marked
with an asterisk are normally shadowed because the characters
are of syntactic type
\emph{whitespace}, \emph{macro}, \emph{single escape}, or \emph{multiple escape}.
An \emph{alphadigit} character is interpreted as a
digit if it is a valid digit in the radix specified by {\small \cd{*read-base*}};
otherwise it is alphabetic.
Characters with an \emph{illegal} attribute can never appear in
a token except under the control of an escape character.
\end{footnotesize}
\end{table}
\begin{table}
\caption{Свойства стандартных символов}
\label{Standard-Readtable-Attributes-Table}
\begin{tabular*}{\textwidth}{@{\extracolsep{\fill}}l@{\extracolsep{\fill}}lllll@{}}
\cd{!}&\emph{алфавитный}&$\langle$page$\rangle$&\emph{недопустимый}&$\langle$backspace$\rangle$&\emph{недопустимый} \\
\cd{"}&\emph{алфавитный} *&$\langle$return$\rangle$&\emph{недопустимый} *&$\langle$tab$\rangle$&\emph{недопустимый} * \\
\cd{\#}&\emph{алфавитный} *&$\langle$space$\rangle$&\emph{недопустимый} *&$\langle$newline$\rangle$&\emph{недопустимый} * \\
\cd{\$}&\emph{алфавитный}&$\langle$rubout$\rangle$&\emph{недопустимый}&$\langle$linefeed$\rangle$&\emph{недопустимый} * \\
\cd{\%}&\emph{алфавитный}&\cd{.}&\multicolumn{3}{l}{\emph{алфавитный},
\emph{точка}, \emph{разделитель десятичной части}}\\
\cd{\&}&\emph{алфавитный}&\cdf{+}&\multicolumn{3}{l}{\emph{алфавитный},
\emph{знак плюс}} \\
\cd{'}&\emph{алфавитный} *&\cdf{-}&\multicolumn{3}{l}{\emph{алфавитный},
\emph{знак минус}} \\
\cd{(}&\emph{алфавитный} *&\cdf{*}&\emph{алфавитный} \\
\cd{)}&\emph{алфавитный} *&\cdf{/}&\multicolumn{3}{l}{\emph{алфавитный},
\emph{маркер дроби}} \\
\cd{,}&\emph{алфавитный} *&\cd{{\Xatsign}}&\emph{алфавитный} \\
\cd{0}&\emph{алфавитно-цифровой}&\cdf{A}, \cdf{a}&\emph{алфавитно-цифровой} \\
\cd{1}&\emph{алфавитно-цифровой}&\cdf{B}, \cdf{b}&\emph{алфавитно-цифровой} \\
\cd{2}&\emph{алфавитно-цифровой}&\cdf{C}, \cdf{c}&\emph{алфавитно-цифровой} \\
\cd{3}&\emph{алфавитно-цифровой}&\cdf{D}, \cdf{d}&\multicolumn{3}{l}{\emph{алфавитно-цифровой}, \emph{маркер экспоненты
для двойного с плавающей точкой}} \\
\cd{4}&\emph{алфавитно-цифровой}&\cdf{E}, \cdf{e}&\multicolumn{3}{l}{\emph{алфавитно-цифровой}, \emph{маркер экспоненты
для числа с плавающей точкой}} \\
\cd{5}&\emph{алфавитно-цифровой}&\cdf{F}, \cdf{f}&\multicolumn{3}{l}{\emph{алфавитно-цифровой}, \emph{маркер экспоненты
для одинарного с плавающей точкой}} \\
\cd{6}&\emph{алфавитно-цифровой}&\cdf{G}, \cdf{g}&\emph{алфавитно-цифровой} \\
\cd{7}&\emph{алфавитно-цифровой}&\cdf{H}, \cdf{h}&\emph{алфавитно-цифровой} \\
\cd{8}&\emph{алфавитно-цифровой}&\cdf{I}, \cdf{i}&\emph{алфавитно-цифровой} \\
\cd{9}&\emph{алфавитно-цифровой}&\cdf{J}, \cdf{j}&\emph{алфавитно-цифровой} \\
\cd{:}&\emph{package marker}~~~~~~&\cdf{K}, \cdf{k}&\emph{алфавитно-цифровой} \\
\cd{;}&\emph{алфавитный} *&\cdf{L}, \cdf{l}&\multicolumn{3}{l}{\emph{алфавитно-цифровой}, \emph{маркер экспоненты
для длинного с плавающей точкой}} \\
\cdf{<}&\emph{алфавитный}&\cdf{M}, \cdf{m}&\emph{алфавитно-цифровой} \\
\cdf{=}&\emph{алфавитный}&\cdf{N}, \cdf{n}&\emph{алфавитно-цифровой} \\
\cdf{>}&\emph{алфавитный}&\cdf{O}, \cdf{o}&\emph{алфавитно-цифровой} \\
\cd{?}&\emph{алфавитный}&\cdf{P}, \cdf{p}&\emph{алфавитно-цифровой} \\
\cd{{\Xlbracket}}&\emph{алфавитный}&\cdf{Q}, \cdf{q}&\emph{алфавитно-цифровой} \\
\cd{{\Xbackslash}}&\emph{алфавитный} *&\cdf{R}, \cdf{r}&\emph{алфавитно-цифровой} \\
\cd{{\Xrbracket}}&\emph{алфавитный}&\cdf{S},
\cdf{s}&\multicolumn{3}{l}{\emph{алфавитно-цифровой}, \emph{маркер экспоненты
для короткого с плавающей точкой}} \\
\cd{{\Xcircumflex}}&\emph{алфавитный}&\cdf{T}, \cdf{t}&\emph{алфавитно-цифровой} \\
\cd{{\Xunderscore}}&\emph{алфавитный}&\cdf{U}, \cdf{u}&\emph{алфавитно-цифровой} \\
\cd{{\Xbq}}&\emph{алфавитный} *&\cdf{V}, \cdf{v}&\emph{алфавитно-цифровой} \\
\cd{{\Xlbrace}}&\emph{алфавитный}&\cdf{W}, \cdf{w}&\emph{алфавитно-цифровой} \\
\cd{|}&\emph{алфавитный} *&\cdf{X}, \cdf{x}&\emph{алфавитно-цифровой} \\
\cd{{\Xrbrace}}&\emph{алфавитный}&\cdf{Y}, \cdf{y}&\emph{алфавитно-цифровой} \\
\cd{{\Xtilde}}&\emph{алфавитный}&\cdf{Z}, \cdf{z}&\emph{алфавитно-цифровой} \\
\end{tabular*}
\vfill
\begin{footnotesize}
\noindent
These interpretations apply only to characters whose
syntactic type is \emph{constituent}. Entries marked
with an asterisk are normally shadowed because the characters
are of syntactic type
\emph{whitespace}, \emph{macro}, \emph{single escape}, or \emph{multiple escape}.
An \emph{alphadigit} character is interpreted as a
digit if it is a valid digit in the radix specified by {\small \cd{*read-base*}};
otherwise it is alphabetic.
Characters with an \emph{illegal} attribute can never appear in
a token except under the control of an escape character.
\end{footnotesize}
\end{table}
\begin{lisp}
\hskip 0.2\linewidth\=\hskip 0.2\linewidth\=\hskip 0.2\linewidth\=\hskip 0.2\linewidth\=\kill
1b5000\>777777q\>1.7J\>-3/4+6.7J\>12/25/83 \\
27{\Xcircumflex}19\>3{\Xcircumflex}4/5\>6//7\>3.1.2.6\>{\Xcircumflex}-43{\Xcircumflex} \\
3.141{\Xunderscore}592{\Xunderscore}653{\Xunderscore}589{\Xunderscore}793{\Xunderscore}238{\Xunderscore}4\>\>\>-3.7+2.6i-6.17j+19.6k
\end{lisp}
The following tokens are \emph{not} potential numbers but are always
treated as symbols:
\begin{lisp}
\hskip 0.2\linewidth\=\hskip 0.2\linewidth\=\hskip 0.2\linewidth\=\hskip 0.2\linewidth\=\kill
/\>/5\>+\>1+\>1- \\*
foo+\>ab.cd\>{\Xunderscore}\>{\Xcircumflex}\>{\Xcircumflex}/-
\end{lisp}
The following tokens are potential numbers if the value of
\cd{*read-base*} is \cd{16} (an abnormal situation), but they are
always treated as symbols if the value of \cd{*read-base*}
is \cd{10} (the usual value):
\begin{lisp}
\hskip 0.2\linewidth\=\hskip 0.2\linewidth\=\hskip 0.2\linewidth\=\hskip 0.2\linewidth\=\kill
bad-face\>25-dec-83\>a/b\>fad{\Xunderscore}cafe\>f{\Xcircumflex}
\end{lisp}
It is possible for there to be an ambiguity as to whether
a letter should be treated as a digit or as a number marker.
In such a case, the letter is always treated as a digit
rather than as a number marker.
Note that the printed representation for a potential
number may not contain any escape characters.
An escape character robs the following character of all syntactic
qualities, forcing it to be strictly alphabetic and therefore unsuitable
for use in a potential number. For example,
all of the following representations are interpreted as symbols, not numbers:
\begin{lisp}
{\Xbackslash}256~~~25{\Xbackslash}64~~~1.0{\Xbackslash}E6~~~|100|~~~3{\Xbackslash}.14159~~~|3/4|~~~3{\Xbackslash}/4~~~5||
\end{lisp}
In each case, removing the escape character(s) would allow the token
to be treated as a number.
If a potential number can in fact
be interpreted as a number according to the BNF
syntax in table~\ref{NUMBER-SYNTAX-TABLE}, then a number object of the
appropriate type is constructed and returned. It should be noted that in
a given implementation it may be that not all tokens conforming to the
actual syntax for numbers can actually be converted into number objects.
For example, specifying too large or too small an exponent for a floating-point
number may make the number impossible to represent in the implementation.
Similarly, a ratio with denominator zero (such as \cd{-35/000})
cannot be represented in \emph{any} implementation.
In any such circumstance where
a token with the syntax of a number cannot be converted to an internal
number object, an error is signaled. (On the other hand, an error
must not be signaled for specifying too many significant digits
for a floating-point number; an appropriately truncated or rounded
value should be produced.)
There is an omission in the syntax of numbers
as described in table~\ref{NUMBER-SYNTAX-TABLE},
in that the syntax does not account for the possible
use of letters as digits.
The radix used for reading integers and ratios is normally decimal.
However, this radix is actually determined by the value of
the variable \cd{*read-base*}, whose initial value is \cd{10}.
\cd{*read-base*} may take on any integral value between \cd{2} and \cd{36};
let this value be \emph{n}. Then a token \emph{x} is interpreted as
an integer or ratio in base \emph{n} if it could be properly
so interpreted in the syntax \cd{\#\emph{n}R\emph{x}}
(see section~\ref{SHARP-SIGN-MACRO-CHARACTER-SECTION}).
So, for example, if the value of \cd{*read-base*} is \cd{16},