RFC 138
Status report on proposed Data Reconfiguration Service
STATUS REPORT ON PROPOSED DATA RECONFIGURATION SERVICE ๐ฆ
okay bestie, so this is RFC 138 ๐ It came out of the Network Working Group and is dated 28 April 1971. The header has the NIC 6715 number, and it's a status report on a proposed Network experiment. There's no category, obsoletes, or updates line in the header, so I'm not inventing one ๐
The authors are Bob Anderson (Rand), Vint Cerf (UCLA), Eric Harslem (Rand), John Heafner (Rand), Jim Madden (U. of Illinois), Bob Metcalfe (MIT), Arie Shoshani (SDC), Jim White (UCSB), and David Wood (Mitre). That's a whole squad ๐ โจ
Contents
CONTENTS
I. INTRODUCTION ................................. 2
Purpose of this RFC .......................... 2
Motivation ................................... 2
II. OVERVIEW OF DATA RECONFIGURATION SERVICE ..... 3
Elements of Data Reconfiguration Service ..... 3
Conceptual Network Connections ............... 3
Connection Protocols and Message Formats ..... 4
Example Connection Configurations ............ 6
III. THE FORM MACHINE ............................. 7
Input/Output Stream and Forms ................ 7
Form Machine BNF Syntax ...................... 7
Alternate Specification of Form Machine Syntax 8
Forms ........................................ 9
Rules ........................................ 10
Terms ........................................ 10
Term Format 1 .............................. 11
Term Format 2 .............................. 11
Term Format 3 .............................. 13
Term Format 4 .............................. 13
Application of a Term ...................... 14
Restrictions and Interpretations of
Term Functions ........................... 14
Term and Rule Sequencing ..................... 16
IV. EXAMPLES ..................................... 16
Remarks ...................................... 16
Field Insertion .............................. 17
Deletion ..................................... 17
Variable Length Records ...................... 17
String Length Computation .................... 18
Transposition ................................ 18
Character Packing and Unpacking .............. 18
V. PROPOSED USES OF DATA RECONFIGURATION SERVICE 19
VI. IMPLEMENTATION PLANS ......................... 20
Appendix A ......................................... 21
Note 1 to the DRS Working Group .............. 21
Note 2 to the DRS Working Group .............. 22
I. INTRODUCTION ๐ธ
PURPOSE OF THIS RFC ๐
okay so the whole point of this RFC is to describe, in part, a proposed Network experiment ๐ง and to ask everyone for comments on literally any aspect of it. The experiment is a software mechanism that reformats Network data streams, and it can be adapted to loads of Network application programs โจ The big hope is that the results lead to a further standard service that embodies the principles in this RFC ๐ We'd love comments on whether this work is appropriate as a Network experiment, and also on any particular Network data reformatting needs that these techniques couldn't easily handle ๐
MOTIVATION ๐ซถ
application programs need specific data I/O formats, and those formats are different from program to program ๐ค our position is that the Network should adapt to each program's requirements instead of making every program change to match a standard. this doesn't rule out standards that describe the formats of regular message contents. it's just a way of reading a standard as a desirable mode of operation, but not a necessary one ๐
there's also a format mismatch problem when users want to hook lots of different kinds of consoles up to one service program ๐ it's way better for the Network to adapt to each console configuration than to need a unique software package for every console transformation ๐
one approach is for sites with substantial computing power to offer a data reconfiguration service, and a proposed example of one is described here ๐
the envisioned modus operandi is that an applications programmer defines forms that describe data reconfigurations. the service stores the forms by name. later on, a user (maybe not a programmer!) uses the service to do a particular transformation of a Network data stream, simply by calling the form by name ๐
we tried to make a notation tailored to some specifically needed instances of data reformatting. we kept the notation and its underlying implementation inside a utility range. on the lower end, it's expressive enough to make the experimental service useful. on the upper end, it stays short of a general-purpose programming language ๐
II. OVERVIEW OF THE DATA RECONFIGURATION SERVICE โจ
ELEMENTS OF THE DATA RECONFIGURATION SERVICE ๐ฆ
an implementation of the Data Reconfiguration Service (DRS) includes modules for connection protocols, a handler for some requests that can be made of the service, a compiler and/or interpreter (called the Form Machine) to act on those requests, and a file storage module for saving and retrieving definitions of data reconfigurations (forms) ๐๏ธ
this section highlights connection protocols and requests. the next section covers the Form Machine language in some detail. file storage isn't described in this document, because it's transparent to the use of the service and its implementation is different at each DRS host ๐
CONCEPTUAL NETWORK CONNECTIONS ๐
okay so there are three conceptual Network connections to the DRS, see Fig. 1 ๐
- The control connection (CC) is between an originating user and the DRS. a form specifying data reconfiguration is defined over this connection, and it's applied to data passing over the two connections below.
- The user connection (UC) is between a user process and the DRS.
- The server connection (SC) is between the DRS and the serving process.
since the goal is to adapt the Network to user and server processes, a minimum of requirements are imposed on the UC and SC ๐ซถ
+-------------+ CC +-----------+ SC +-----------+
| ORIGINATING +--------+ DRS +--------+ SERVER |
| USER | ^ | | ^ | PROCESS |
+-------------+ | +------+----+ | +-----------+
| / |
Telnet / <------ Simplex or Duplex
Protocol UC/ Connections
Connection /
/
+-----+-----+
| USER |
| PROCESS |
+-----------+
Figure 1. DRS Network Connections
CONNECTION PROTOCOLS AND MESSAGE FORMATS ๐ฅ
over a control connection, the dialog is directly between an originating user and the DRS. here, the user is defining forms or assigning forms to connections for reformatting ๐
the user connects to the DRS via the initial connection protocol (ICP) specified in NWG/RFC #80, version 1. rather than going through a logger, the user calls on a particular socket that the DRS always listens on. DRS switches the user to another socket pair โจ
messages sent over a control connection are of the types and formats to be specified for TELNET. so a user at a terminal should be able to connect to a DRS via their local TELNET, for example, as shown in Fig. 2 ๐ง
+--------------+
+--------+ CC | |
+-------+ TELNET +-------+ DRS |
| +--------+ | |
| +--------------+
+----------+---------+
| USER |
|(TERMINAL OR PROGRAM|
+--------------------+
Figure 2. A TELNET Connection to DRS
when a user connects to DRS, he supplies a six-character user ID (UID) as a qualifier, which guarantees the uniqueness of his form names. he'll have (at least) the following commands ๐
DEFFORM (name)ENDFORM (name)
these two commands define a form, whose text is chronologically entered between them. the (name) is six characters. the form is stored in the DRS local file system ๐๏ธ
PURGE (name)
the named form, as qualified by the current UID, is purged from the DRS file system ๐๏ธ
LISTNAMES (UID)
the unqualified names of all forms assigned to UID are returned ๐
LISTFORM (name)
the source text of a named form is returned ๐
DUPLEXCONNECT (user site, user send, user receive, user method, server site, server send, server receive, server method, user-to-server form, server-to-user form)SIMPLEXCONNECT (send site, send socket, send method, receive site, receive socket, receive method, form)
either one, both, or neither of the two parties specified in 6 or 7 may be at the same host as the party issuing the request ๐ธ sites and sockets specify user and server for the connection. method indicates the way in which the connection is established. three options are provided:
- site/socket already connected to DRS as a dummy control connection. (a dummy control connection should not also be the real control connection.)
- connect via standard ICP. (Only for command no. 6.)
- connect directly via STR, RTS. ๐
EXAMPLE CONNECTION CONFIGURATIONS ๐
okay so there are basically two modes of DRS operation, and they're both giving main character energy ๐ โจ
- the user wants a DRS UC/SC connection (or connections) between two programs
- the user wants to set up those same connections where they (their terminal) sit at one end of the UC or the SC ๐ฆ
The second one is perfect when you want to chat with the serving process straight from your terminal, like a logger ๐ชต๐
For the first case (Fig. 1, where the originating user is either a terminal or a program), the user just issues the right CONNECT command ๐ฅ The UC/SC can be simplex or duplex, so you pick what fits.
The second case has two possible setups, shown in Figs. 3 and 4 ๐
+--------+ CC +--------+ +------+
| +------+ | SC | |
+------+ /| TELNET | UC | DRS +------+ SP |
| |/ | +------+ | | |
| USER | /+--------+ +--------+ +------+
| |/
+------+
Figure 3. Use of Dummy Control Connection
+--------+
+------+ /| USER | CC +--------+ +------+
| |/ | SIDE +------+ | SC | |
| USER | +--------+ UC | DRS +------+ SP |
| |\ | SERVING+------+ | | |
+------+ \| SIDE | +--------+ +------+
+--------+
Figure 4. Use of Server TELNET
In Fig. 3 the user tells their TELNET to make two duplex connections to DRS ๐ง One is for control info (the CC) and the other is a dummy. When they issue the CONNECT, they reference the dummy duplex connection (UC) using the "already connected" option. bestie, that's so clever ๐ญ
In Fig. 4 the user has their TELNET (user side) call the DRS. When they issue the CONNECT, the DRS calls the TELNET (server side), which accepts the call on behalf of the console ๐ Here's the tea: this distinction is only known to the user. To the DRS, the Fig. 4 setup looks exactly like Fig. 1 ๐ซถ Two things to note:
- TELNET protocol is needed only to define forms and direct connections. It is not required for the using and serving processes.
- The using and serving processes need only a minimum of modification for Network use, i.e., an NCP interface.
III. THE FORM MACHINE โจ
INPUT/OUTPUT STREAMS AND FORMS ๐ธ
okay so this section explains the syntax and semantics of the forms that describe the data reconfigurations ๐ The Form Machine takes in an input stream, reformats it according to a form describing the reconfiguration, and emits the reformatted data as an output stream. iconic behavior tbh ๐
When you're reading this, it helps to picture a form getting applied to the data stream, like in Fig. 5 ๐ฆ There are two pointers to keep track of. An input stream pointer marks where the data being analyzed right now sits in the input stream, and an output stream pointer marks where data is being emitted in the output stream ๐
/\/\ /\/\
^ | | FORM | | ^
| | | ----------------- | | |
| | | +- ----------------- -+ | | |
| | | | CURRENT PART OF | | | |
INPUT | |<= CURRENT < ----------------- > CURRENT => | | OUTPUT
STREAM | | POINTER | FORM BEING APPLIED | POINTER | | STREAM
| | +- ----------------- -+ | |
| | ----------------- | |
| | ----------------- | |
| | ----------------- | |
\/\/ \/\/
Figure 5. Application of Form to Data Streams
FORM MACHINE BNF SYNTAX ๐ง
Here's the grammar, bestie. Read it carefully because every piece matters ๐ฅ
form ::= rule | rule form
rule ;;= label inputstream outputstream ;
label ::= INTEGER | <null>
inputstream ::= terms | <null>
terms ::= term | terms , term
outputstream ::= : terms | <null>
term ::= identifier | identifier descriptor |
descriptor | comparator
identifier ::= an alpha character followed by 0 to 3
alphamerics
descriptor ::= (replicationexpression , datatype ,
valueexpression , lengthexpression control)
comparator ::= (value connective value control) |
(identifier .<=>. control)
replicationexpression ::= arithmeticexpression | <null>
datatype ::= B | O | X | E | A
valueexpression ::= value | <null>
lengthexpression ::= # | arithmeticexpression | <null>
connective ::= .LE. | .LT. | .GE. | .GT. | .EQ. | .NE.
value ::= literal | arithmeticexpression
arithmeticexpression ::= primary | primary operator
arithmeticexpression
primary ::= identifier | L(identifier) | V(identifier) |
INTEGER
operator ::= + | - | * | /
literal ::= literaltype "string"
literaltype ::= B | O | X | E | A
string ::= from 0 to 256 characters
control ::= : options | <null>
options ::= S(where) | F(where) | U(where) |
S(where) , F(where) |
F(where) , S(where)
where ::= arithmeticexpression | R(arithmeticexpression)
ALTERNATE SPECIFICATION OF FORM MACHINE SYNTAX ๐ฆ
same grammar, just written in a different notation, so you can pick whichever one clicks for you โจ
infinity
form ::= {rule}
1
1 1 1
rule ::= {INTEGER} {terms} {:terms} ;
0 0 0
infinity
terms ::= term {,term}
0
1
term ::= identifier | {identifier} descriptor
0
| comparator
1
descriptor ::= ({arithmeticexpression} , datatype ,
0
1 1 1
{value} , {lengthexpression} {:options}
0 0 0
1
comparator ::= (value connective value {:options} ) |
0
1
(identifier .<=. value {:options} )
0
connective ::= .LE. | .LT. | .GE. | .GT. | .EQ. | .NE.
lengthexpression ::= # | arithmeticexpression
datatype ::= B | O | X | E | A
value ::= literal | arithmeticexpression
infinity
arithmeticexpression ::= primary {operator primary}
0
operator ::= + | - | * | /
primary ::= identifier | L(identifier) |
V(identifier) | INTEGER
256
literal ::= literaltype "{CHARACTER} "
0
literaltype ::= B | O | X | A | E
1
options ::= S(where) {,F(where)} |
0
1
F(where) {,S(where)} | U(where)
0
where ::= arithmeticexpression |
R(arithmeticexpression)
3
identifier ::= ALPHABETIC {ALPHAMERIC}
0
FORMS ๐
a form is an ordered set of rules ๐
form ::= rule | rule form
the current rule gets applied at the current spot in the input stream. if the input-stream part of a rule fails to correctly describe the current input, then another rule becomes current and gets applied at that same spot. which rule comes next is either spelled out explicitly by the current term in the current rule, or it's just the next sequential rule by default. the flow of control is explained more fully under TERM AND RULE SEQUENCING ๐ง
if the input-stream part of a rule succeeds in correctly describing the current input, then some data may be emitted at the current spot in the output stream, according to the rule. both pointers then move forward past the described and emitted data, and the next rule gets applied to the new current spot in the input stream ๐ฅ
the application of the form ends when an explicit return, R(arithmeticexpression), shows up in a rule. the user and server connections get closed, and the return code (arithmeticexpression) is sent to the originating user ๐
RULES ๐
a rule is a replacement, comparison, and/or assignment operation, shaped like this ๐
rule ::= label inputstream outputstream ;
a label is the name of a rule. it exists so the rule can be referenced elsewhere in the form for explicit transfer of control. labels look like this ๐
label ::= INTEGER | <null>
the optional integer labels are in the range 0 >= INTEGER >= 9999. the rules don't need to be labeled in ascending numerical order, so you do you ๐ฆ
TERMS ๐ง
the inputstream (describing the input stream to be matched) and the outputstream (describing data to be emitted in the output stream) each consist of zero or more terms, and they look like this โจ
inputstream ::= terms | <null>
outputstream ::= :terms | <null>
terms ::= term | terms , term
terms come in one of four formats, as shown below ๐
term ::= identifier | identifier descriptor |
descriptor | comparator
Term Format 1 ๐ธ
the first term format looks like this ๐
identifier
the identifier is a symbolic reference to a previously identified term (term format 2) in the form. it takes on the same attributes (value, length, type) as the term with that name. term format 1 is normally used to emit data in the output stream ๐ซถ
identifiers are formed by an alpha character followed by 0 to 3 alphameric characters ๐
Term Format 2 ๐
Okay bestie, term format 2 is the one with an identifier sitting right in front of the descriptor ๐
identifier descriptor
It's mostly used as an input stream term, but it can totally be used as an output stream term too ๐ฆ
Here's how a descriptor is defined โจ
descriptor ::= (replicationexpression, datatype,
valueexpression, lengthexpression
control)
The identifier is the term's symbolic name, like in any programming language ๐ It picks up the type, length, and value attributes of the term, and it can be referenced somewhere else in the form ๐ธ
The replication expression is defined below ๐ฅ
replicationexpression ::= arithmeticexpression | <null>
arithmeticexpression ::= primary | primary operator
arithmeticexpression
operator ::= + | - | * | /
primary ::= identifier | L(identifier) | V(identifier) |
INTEGER
Think of the replication expression as a repeat function that gets applied to the combined data type and value expression ๐ง It tells you how many times the value (from the data type/value expression) gets repeated inside the field length set by the data type/length expression ๐
A null replication expression has the value of one โจ Arithmetic expressions get evaluated left-to-right with no precedence ๐ (It's anticipated this interpretation might change if needed, so keep an eye out ๐)
The L(identifier) is a length operator ๐ It generates a 32-bit binary integer matching the length of the named term. The V(identifier) is a value operator ๐ข It generates a 32-bit binary integer matching the value of the named term. (See Restrictions and Interpretations of Term Functions.) The value operator is meant to turn character strings into their numerical versions ๐
The data type is defined below ๐
datatype ::= B | O | X | E | A
The data type tells you what kind of data the term represents ๐ (It's expected that more data types, like floating point and user-defined types, will get added as needed ๐)
Data Type Meaning Unit Length
B Bit string 1 bit
O Bit string 3 bits
X Bit string 4 bits
E EBCDIC character 8 bits
A Network ASCII character 8 bits
The value expression is defined below ๐ซถ
valueexpression ::= value | <null>
value ::= literal | arithmeticexpression
literal ::= literaltype "string"
literaltype ::= B | O | X | E | A
The value expression is the unit value of a term, written in the format the data type gives ๐ฆ It gets repeated according to the replication expression, inside a field whose length is limited by the length expression ๐
A null value expression in the input stream defaults to whatever data is actually in the input stream ๐ The data still has to match the datatype attribute though, no skipping that part ๐ญ
A null value expression generates padding based on the Restrictions and Interpretations of Term Functions ๐
The length expression is defined below โจ
lengthexpression ::= # | arithmeticexpression | <null>
The length expression says how long the field holding the value expression is, after it's been expanded by the replication expression ๐ If the length expression is less than the length the expanded value expression implies, then the expanded value expression gets truncated (see Restrictions and Interpretations of Term Functions) โ๏ธ
The terminal symbol # means an arbitrary length, which gets explicitly ended by the value of the next term ๐ธ The # is only legal in the input stream, not the output stream ๐ โโ๏ธ
If the length expression is less than or equal to zero, the term still succeeds, but the stream pointer doesn't move forward ๐ซง Positive lengths move the stream pointer forward if the term succeeds otherwise ๐โโ๏ธ
Control is defined under TERM AND RULE SEQUENCING ๐งญ
Term Format 3 ๐ท
Term format 3 looks like this ๐
descriptor
It's basically term format 2 with the identifier left out ๐ฆ Term format 3 is usually used in the output stream ๐ It also shows up in the input stream, for when input data needs to be skipped over but doesn't need to be kept for emission or later reference ๐
Term Format 4 ๐
The fourth term format is shown below ๐
comparator ::= (value connective value control) |
(identifier .<=. value control)
value ::= literal | arithmeticexpression
literal ::= literaltype "string"
literaltype ::= B | O | X | E | A
string ::= from 0 to 256 characters
connective ::= .LE. | .LT. | .GE. | .GT. | .EQ. | .NE.
This one is for assignment and comparison, so it's giving "decide stuff" energy โจ
The assignment operator .<=. assigns the value to the identifier ๐ The connectives mean what they usually mean ๐ Values you're comparing have to have the same type and length attributes. If they don't, an error condition pops up and the form fails ๐
The Application of a Term ๐ง
The elements of a term get applied through these steps, in order โจ
- The data type and value expression together specify a unit value, call it x.
- The replication expression specifies how many times x gets repeated (or copied) in a concatenated fashion. The value of the concatenated xs becomes, say, y of length L1.
- The data type and the length expression together specify a field length of the input area (call it L2) that starts at the current stream pointer position.
- The value of y gets truncated to y' if L1 > L2. Call the truncated length L1'.
- If the term is an input stream term, then the value y' of length L1' gets compared to the input value starting at the current input pointer position.
- If the values match over the length L1', then the input value of length L2 (which may be greater than L1') starting at the current pointer position in the input area becomes the value of the term.
In an output stream term, it's the same process, except the source of input is the value of the term(s) named in the value expression, and the data gets emitted in the output stream ๐ฆ
The procedure above gets a little tweak with one term look-ahead when lengths are indefinite because of the # symbol ๐
Restrictions and Interpretations of Term Functions ๐ฅ
- Terms with indefinite lengths (using the # symbol) must be separated by some type-specific data, like a literal. (A literal isn't specifically required, though. An arbitrary number of ASCII characters could be ended by a non-ASCII character.) # is only legal in the input stream, not the output stream ๐
- Truncation and padding go like this ๐
- a) Character to character (A <--> E) conversion is left justified, and gets truncated or padded on the right with blanks.
- b) Character to numeric and numeric to numeric conversions are right-justified, and get truncated or padded on the left with zeros.
- c) Numeric to character conversion is right-justified and left-padded with blanks.
- The following get ignored in a form definition over the control connection ๐ซง
- a) TAB, carriage return, etc.
- b) blanks, except within quotes.
- c)
/* string */is treated as comments, except within quotes.
- The following defaults kick in when the term part is left out ๐
- a) The replication expression defaults to one.
- b) The data type defaults to type B.
- c) The value expression of an input stream term defaults to the value found in the input stream, but that input stream has to match the data type and length expression. The value expression of an output stream term defaults to padding only.
- d) The length expression defaults to the size of the quantity determined by the replication expression, data type, and value expression.
- e) Control defaults to the next sequential term if a term gets applied successfully. Otherwise, control defaults to the next sequential rule. If where evaluates to an undefined label, the form fails ๐
- Arithmetic expressions are evaluated left-to-right with no precedence ๐งฎ
- The following limits apply ๐ง
- a) Binary lengths are
<= 32bits - b) Character strings are
<= 2568-bit characters - c) Identifier names are
<= 4characters - d) The maximum number of identifiers is
<= 256 - e) Label integers are
>= 0and<= 9999
- a) Binary lengths are
- Value and length operators produce 32-bit binary integers. The value operator is currently meant for converting A or E type decimal character strings into their binary versions ๐ข For example, the value of
E'12'would be0......01100. The value ofE'AB'would make the form fail ๐ญ
TERM AND RULE SEQUENCING ๐งญ
Sequencing can be explicitly controlled by including control in a term ๐
control ::= :options | <null>
options ::= S(where) | F(where) | U(where)
S(where) , F(where) |
F(where) , S(where)
where ::= arithmeticexpression | R(arithmeticexpression)
S, F, and U stand for success, fail, and unconditional transfers ๐ฆ Where evaluates to a rule label, so a transfer can happen from inside a rule (at the end of a term) to the beginning of another rule ๐ R means terminate the form and send the evaluated expression back to the initiator over the control connection (if it's still open) ๐จ
If terms aren't explicitly sequenced, these defaults kick in โจ
- When a term fails, go to the next sequential rule.
- When a term succeeds, go to the next sequential term within the rule.
- At the end of a rule, go to the next sequential rule.
Check out this example to see how transfer of control connects to movement of the input pointer ๐
1 XYZ(,B,,8:S(2),F(3)) : XYZ ;
2 . . . . . . .
3 . . . . . . .
The value of XYZ never gets emitted in the output stream, because control jumps out of the rule on either success or failure ๐ If the term succeeds, the 8 bits of input get assigned as the value of XYZ, and rule 2 is then applied to the same input stream data ๐ Since the complete rule 1 wasn't applied successfully, the input stream pointer doesn't move forward ๐ซง
Heads up bestie: the pointer staying put is the whole point of this example, so don't skip past it ๐
IV. EXAMPLES ๐
REMARKS ๐
The following examples (forms and also single rules) are simple, representative uses of the Form Machine โจ The examples are written one term per line just to make the explanation easier to follow ๐ Usually, a single rule could be written as one line ๐ง
FIELD INSERTION โจ
okay bestie, to insert a field you split the input into two terms so the new field can slide right in between them ๐ say you want line numbers on a 121 character/line printer that has a leading carriage control character. the form looks like this:
(NUMB.<=>.1); /*initialize line number counter to one*/
1 CC(,E,,1:F(R(99))), /*pick up control character and save
as CC*/
/*return a code of 99 upon exhaustion*/
LINE(,E,,121 : F(R(98))) /*save text as LINE*/
:CC, /*emit control character*/
(,E,NUMB,2), /*emit counter in first two columns*/
(,E,E".",1), /*emit period after line number*/
(,E,LINE,117), /*emit text, truncated in 117 byte field*/
(NUMB.<=.NUMB+1:U(1)); /*increment line counter and go to
rule one*/;;
DELETION ๐
for deleting, the data you want gone has to be its own separate term on the left. then you just skip emitting it on the right, and poof ๐ฆ
(,B,,8), /*isolate 8 bits to ignore*/
SAVE(,A,,10) /*extract 10 ASCII characters from
input stream*/
:(,E,SAVE,); /*emit the characters in SAVE as EBCDIC
characters whose length defaults to the
length of SAVE, i.e., 10, and advance to
the next rule*/
in that example, if either input stream term fails, the next sequential rule gets applied ๐
VARIABLE LENGTH RECORDS ๐ผ
some devices, terminals and programs produce variable length records, and this next rule grabs those EBCDIC records and translates them into ASCII ๐
CHAR(,E,,#), /*pick up all (an arbitrary number of)
EBCDIC characters in the input stream*/
(,X,X"FF",2) /*followed by a hexadecimal literal,
FF (terminal signal)*/
:(,A,CHAR,), /*emit them as ASCII*/
(,X,X"25",2); /*emit an ASCII carriage return*/
STRING LENGTH COMPUTATION ๐ง
it's super common to stick a length field in front of a really long character string. this rule puts a one-byte length field onto an EBCDIC string
Q(,E,,#), /*pick up all EBCDIC characters*/
TS(,X,X"FF",2) /*followed by a hexadecimal literal, FF*/
:(,B,L(Q)+2,8), /*emit the length of the characters
plus the length of the literal plus
the length of the count field itself,
in an 8-bit field*/
Q, */emit the characters*/
TS; */emit the terminal*/
TRANSPOSITION ๐
reordering fields is also super common, like this one:
Q(,E,,20), R(,E,,10) , S(,E,,15), T(,E,,5) : R, T, S, Q ;
the terms come out in a totally different order ๐
CHARACTER PACKING AND UNPACKING ๐ฆ
in systems like HASP, repeated characters get squished into a count followed by the character, so storage and transmission are more efficient ๐ง the first form packs and the second form unpacks
/*form to pack EBCDIC streams*/
/*returns 99 if OK, input exhausted*/
/*returns 98 if illegal EBCDIC*/
/*look for terminal signal FF which is not a legal EBCDIC*/
/*duplication count must be 0-254*/
1 (,X,X"FF",2 : S(R(99))) ;
/*pick up the EBCDIC and initialize count/*
CHAR(,E,,1 : F(R(98))) , (CNT .<=. 1) ;
/*count consecutive EBCDICs like CHAR*/
2 (,E,CHAR,1 : F(3)) , (CNT .<=. CNT+1 : U(2)) ;
/*emit count and current character*/
3 : (,B,CNT,8), CHAR, (:U(1));
/*end of form*/;;
/*form to unpack EBCDIC streams*/
/*look for terminal*/
1 (,X,X"FF",2 : S(R(99))) ;
/*emit character the number of times indicated*/
/*by the counter contents*/
CNT(,B,,8), CHAR(,E,,1) : (CNT,E,CHAR,CNT:U(1));
/*failure of form*/
(:U(R(98))) ;;
V. PROPOSED USES OF DATA RECONFIGURATION SERVICE ๐ธ
here are some DRS use ideas that different sites sent in ๐
UCLA
- Pack/unpack text files.
- Preprocessor to scan META compiler input.
- Perhaps graphics.
MIT
- Reformatting within file transfer service.
- Character conversions.
- Possible graphics service (Evans and Sutherland output format).
- Reformat arguments of subroutines remote to each other.
U. OF ILLINOIS
- Dependent upon remote use of DRS for many remote services.
SDC
- Would be essential to data transfer in general.
- Could be used in relation to data management language.
UCSB
- Checkout of I/O formats of file system.
- Debugging Network services in general.
- Mapping their services into future standards.
RAND
- To describe RJO/RJE message formats at UCSB.
- To describe RJS message formats at UCLA.
- To adapt Network to existing services, in general.
MITRE
- Character conversions.
- Testing data formats going into data bases for correct field formatting.
VI. IMPLEMENTATION PLANS ๐งช
four sites are currently planning to build and offer the service as an experiment โจ
- MIT: Implementation of forms interpreter in MIDAS (assembly). Perhaps Tree Meta compiler of forms. Implementation on PDP-10.
- UCLA: Implementation on SIGMA-7 employing META-7 to compile forms.
- UCSB: Implementation on 360/75.
- RAND: Initial implementation on 360/65; compiler to be written in graphics CPS; compiled intermediate forms to be interpreted by assembler language subroutine. Later implemented on PDP-10.
on top of those, the University of Illinois and Mitre also plan to experiment with the service ๐ฆ
APPENDIX A ๐
Note 1 to the DRS Working Group
bestie, as you remember, we spent ages talking about how the arbitrary symbol, #, gets used. to sum up, it was clear that putting # in both replication and length expressions caused ambiguities. we settled on a restricted use in the length expression of an input term, although nobody was 100% happy with that definition ๐
Jim White has been commenting on the # again. Jim thinks it's kind of weird that you can pick up an arbitrary number of EBCDIC characters, for example, but you can't pick up an arbitrary number of specific EBCDIC characters, like EBCDIC A's. Jim feels a more natural way to interpret the length, value, and replication expressions would be the way the IBM OS assembler interprets the attributes of the pseudo instruction, define constant (CD).
the IBM OS assembler uses this format:
1 2 3 4
duplication type modifiers nominal value
factor
the duplication factor, if specified, makes the constant get generated the number of times the factor says. the type defines what kind of constant is being specified. modifiers describe the length, scaling, and exponent of the constant. the nominal value supplies the constant described by the subfields that come before it.
assume we only use the # as a duplication factor (replication expression). then, in the example of the form to pack EBCDIC characters, the counter and looping can be eliminated ๐
CHAR(,E,,1) ;
LEN(#,#,CHAR,1) : (,B,L(LEN)+1,*) , CHAR ;
so the idea is that the data type, length expression, and value expression make up the unit value, and that quantity can then be replicated. right now, in our document, only the data type and value expression make up the unit value.
here's how applying a term works with Jim's suggestion:
- The data type, value expression, and length expression together specify a unit value, call it x.
- The replication expression specifies the number of times x is to be repeated. The value of the concatenated xs becomes y of length L.
- If the term is an input stream term then the value beginning at the current input pointer position.
- If the input value satisfies the constraints of y over length L then the input value of length L becomes the value of the term.
Note 2 to the DRS Working Group
there's been recent debate about whether the input pointer should advance after a rule finishes successfully (the way it's defined now) or after each term finishes successfully. see the example on page 22. if the input pointer advances after a term succeeds, then rules become equivalent to terms ๐
i'd love for us to talk about both the term attributes and the input pointer advance issues at the SJCC ๐
John
[ This RFC was put into machine readable form for entry ] [ into the online RFC archives by Katsunori Tanaka 4/99 ]
๐ฆ where this page comes from
- ietf: rfc138 1971-04
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms