La Form Machine
I. Forme
Una forma è un insieme ordinato di regole.
F = {R1, ...,Rn}
La prima regola (R1) è la regola con la priorità più alta; l'ultima regola (Rn) è la regola con la priorità più bassa.
La Form Machine riceve come input: 1) un elenco di indirizzi e lunghezze che delimitano il flusso o i flussi di input; 2) un elenco di indirizzi e lunghezze che delimitano l'area o le aree di output; 3) un puntatore a un elenco di forme; 4) un puntatore alla posizione iniziale del flusso di input; e 5) un puntatore alla posizione iniziale dell'area di output. La Form Machine applica una forma alla stringa di input emettendo una stringa di output nell'area di output. La forma viene applicata nel modo seguente:
Passo 1: R1 diventa la regola corrente.
Passo 2: La regola corrente viene applicata ai dati di input.
Passo 3: a) Se la regola fallisce, diventa corrente la regola con priorità immediatamente inferiore.
b) Se la regola ha successo, diventa corrente la regola con la priorità più alta
c) Quando la regola con la priorità più bassa fallisce, la forma fallisce e l'applicazione della forma ai dati di input termina.
Passo 4: Continua dal Passo 2.
Inoltre, durante il Passo 2, se il resto della stringa di input non è sufficiente a soddisfare una regola, quella regola fallisce e i risultati parziali non vengono emessi. Se una regola riempie la stringa di output, l'applicazione della forma termina.
II. Regole
Una regola è un'operazione di sostituzione della forma:
left-hand-side -> right-hand-side
Entrambi i lati di una regola consistono in una serie di zero o più termini (si veda sotto) separati da virgole.
Il lato sinistro della regola viene applicato alla stringa di input nella posizione corrente come operazione di confronto di modello. Se descrive esattamente l'input, 1) il puntatore alla posizione corrente di input viene avanzato oltre l'input confrontato, 2) il lato destro emette dati nella posizione corrente della stringa di output, e 3) il puntatore alla posizione corrente di output viene avanzato oltre i dati emessi.
III. Termini
Un termine è una variabile che descrive la stringa di input da confrontare o la stringa di output da emettere. Un termine ha tre formati.
Formato di termine 1
+---------------------------------------------------------------------+
| |
| name ( data replication . value : length ) |
| type expression expression expression |
| |
|_____________________________________________________________________|
Qualsiasi campo può essere assente.
Il nome è un nome simbolico del termine nel senso usuale dei linguaggi di programmazione. È un singolo carattere alfabetico minuscolo, unico all'interno di una regola.
Il tipo di dati descrive il tipo di dati che il termine rappresenta. È un membro dell'insieme:
{D, O, X, A, E, B}
I tipi di dati hanno i seguenti significati e lunghezze unitarie implicite:
Char. Meaning Length
----- -------- -------
D decimal number 1 bit
O octal number 3 bits
X hexadecimal number 4 bits
A ASCII character 8 bits
E EBCDIC character 8 bits
B binary number 1 bit
L'espressione di replica è un moltiplicatore dell'espressione di valore. Un'espressione di replica ha i formati.
- un'espressione aritmetica dei membri dell'insieme:
{v(name), L(name) , numerals, programming variables}
Il v(name) è un operatore di valore che genera un valore numerico del tipo di dati denominato e L(name) è un operatore di lunghezza che genera un valore numerico della lunghezza di stringa denominata.
La variabile di programmazione è descritta nel formato di termine tre. Gli operatori aritmetici sono mostrati sotto e hanno i loro significati usuali.
{*, /, +, -}
oppure 2) il terminale '#' che indica un multiplo arbitrario dell'espressione di valore.
L'espressione di valore è il valore unitario di un termine espresso nel formato indicato dal tipo di dati. L'espressione di valore viene ripetuta secondo l'espressione di replica. Un'espressione di valore ha il formato:
- come la parte 1) dell'espressione di replica, dove ancora v(name) produce un valore numerico
oppure 2) un singolo membro dell'insieme
{v(name), quoted literal}
dove v(name) produce un valore di tipo di dati (E o A)). (Si noti che la concatenazione si ottiene tramite più termini.)
L'espressione di lunghezza è la lunghezza del campo che contiene l'espressione di valore così come modificata dall'espressione di replica. Ha gli stessi formati di un'espressione di replica.
Quindi, il termine
x(E(7.'F'):L(x)) si chiama x, è di tipo EBCDIC, ha il valore 'FFFFFFF' ed è di lunghezza 7.
Il termine
y(A:8) sul lato sinistro di una regola riceverebbe come valore i successivi 64 bit di input; sul lato destro farebbe soltanto avanzare il puntatore di output di 64 posizioni di bit, poiché non ha alcuna espressione di valore (contenuto) per generare dati nell'area di output.
Formato di termine 2
+---------------------------------------------------------------------+
| |
| name (label) |
| |
+---------------------------------------------------------------------+
L'etichetta è un riferimento simbolico a un termine precedentemente denominato nella regola. Ha lo stesso valore del termine con quel nome.
L'operazione di identità riportata sotto illustra l'uso della notazione con etichetta.
a(A:10) -> (a)
La (a) sul lato destro fa sì che il termine a venga emesso nell'area di output. È equivalente alla regola riportata sotto.
a(A:10) -> (Av(a):L(a))
Formato di termine 3
+---------------------------------------------------------------------+
| |
| name ( programming connective operand ) |
| variable expression |
| |
+---------------------------------------------------------------------+
Una variabile di programmazione è un elemento di dati controllato dall'utente che non compare esplicitamente nei flussi di input/output. Il suo valore può essere confrontato con i dati di input, con costanti, e usato per generare dati di output. Le variabili di programmazione sono singoli simboli greci minuscoli.
Sono usate: per generare indici, contatori, ecc. nell'area di output; per confrontare indici, contatori, ecc. nell'area di input, e; per vincolare le regole di sostituzione dove i dati dipendono dal contesto (spiegato più avanti).
Un connettivo è un membro dell'insieme:
{<-, =, !=, >=, <=, <, >}
La freccia sinistra indica la sostituzione della parte sinistra con la parte destra; gli altri connettivi sono comparatori.
L'espressione di operando è un'espressione aritmetica di membri dell'insieme:
{programming variables, v(name), l(name), numerals}
Per esempio, se la variabile di programmazione [alpha] ha il valore 0 e la regola
a(H[alpha]:1) -> (a), ([alpha]<-[alpha]+1), (H[alpha]:1)
viene applicata esaustivamente a una stringa di cifre esadecimali
0 1 2 3 4 5
l'output sarebbe la stringa esadecimale
0 1 1 2 2 3 3 4 4 5 5 6 .
Nota: la regola sopra è equivalente a
a(B[alpha]:4) -> (a), ([alpha]<-[alpha]+1), (B[alpha]:4)
IV. Restrizioni e interpretazioni delle funzioni di termine
Quando una regola ha successo viene generato output. Nella regola
a(A:#),(A'/':1)->(Ev(a):74),(E'?':1)
nella stringa di input si cerca un numero arbitrario di caratteri ASCII seguiti da un terminale '/'. I caratteri ASCII (a) vengono convertiti in EBCDIC in un campo di 74 byte seguito da un terminale '?'. Ciò mette in luce tre questioni:
-
I termini di lunghezza arbitraria devono essere separati da letterali, poiché i dati non sono specifici per tipo.
-
Il # può essere usato solo sul lato sinistro di una regola.
-
È necessario uno schema di troncamento e riempimento.
Lo schema di troncamento e riempimento è il seguente:
-
Da carattere a carattere (tipi: A, E) L'output è allineato a sinistra con troncamento o riempimento (con spazi) a destra.
-
Da carattere a numerico (da A, E a D, O, H, B)
-
Da numerico a carattere (da D, O, H, B a A, E)
-
Da numerico a numerico (D, O, H, B) L'output è allineato a destra con riempimento o troncamento a sinistra. Il riempimento è a zeri se l'output è numerico.