Skip to main content

Dichiarazione del modulo

La dichiarazione dei moduli viene eseguita con un proprio linguaggio di descrizione che è simile alla dichiarazione delle variabili nel codice testo strutturato (ST).

Formato della dichiarazione del modulo

Un'intestazione del modulo MODULE<name> inizia la dichiarazione. Questo è seguito da un elenco di "sezioni".

Ogni sezione è introdotta dalla parola chiave SEC (per "sezione") e un nome univoco. La parola chiave END_SEC chiude la sezione. Il contenuto di una sezione contiene un elenco di voci composto da ulteriori sezioni o cosiddette definizioni.

Una definizione è composta da un nome e un valore opzionale e termina con un punto e virgola.

I commenti possono essere utilizzati come nel codice ST: "//"" per commenti a riga singola e "(*" e "*)" per commenti su più righe. È possibile utilizzare spazi bianchi (tabulazioni e spazi) e fine riga/avanzamento riga per separare le parti di una dichiarazione, altrimenti vengono ignorati durante l'ulteriore elaborazione.

Come con il codice ST, la distinzione tra maiuscole e minuscole non fa differenza.

Esempio 14. L'esempio seguente spiega gli elementi di una dichiarazione di modulo
01    MODULE Persistence IMPLEMENTED_BY PersistenceFB
02    SEC MetaData
03        NAME       := TL.ChannelName ;
04        DESC       := TL.ChannelDesc ;
05        COLLECTION CATEGORY := ’Persistence’TL.Collection  ;
06        ICON_16    := IP.Channel16 ;
07        ICON_32    := IP.Channel32 ;
08    END_SEC
09    SEC Toplevel
10              SEC STANDARD_TASK : LOW
11                      NAME  := LOW ;
12                      DESC  := TL.TaskLow ;
13                      FLAGS := CREATE_IF_MISSING | READONLY ;
14              END_SEC
15              GVL_NAME := 'GVL_%InstanceName%' ;
16     END_SEC

Nella riga 01 c'è la definizione del nome del modulo "Persistenza". IMPLEMENTED_BY definisce il blocco funzione "PersitenceFB" che contiene la logica del modulo. Questo blocco funzione deve derivare da IModule. Nella riga 02 la sezione MetaData inizia e termina con la riga 08. Questa sezione contiene cinque definizioni. La possibilità di sezioni nidificate è mostrata nella sezione Toplevel (righe 09–16) che contiene la sottosezione STANDARD_TASK (riga 10).



Sintassi della dichiarazione del modulo

In questa sezione verrà spiegata la sintassi e la struttura sintattica consentita per una dichiarazione di modulo.

Nello scanner seguente i token verranno scritti in maiuscolo (esempio: ID). I non terminali della grammatica saranno scritti tra parentesi graffe (esempio: {Entry}).

Analisi lessicale (scanner)

Nel primo passo verranno creati i cosiddetti token (o lessemi) dai caratteri della dichiarazione del modulo (esempio: parole chiave, costanti, identificatori).

Gli spazi bianchi e i caratteri newline/linefeed separano i token, ma altrimenti verranno ignorati. Anche i commenti verranno ignorati per l'ulteriore trattamento della dichiarazione. (I commenti possono essere scritti su una sola riga (//") o commenti su più righe ((* E *)) come nel linguaggio ST. I commenti su più righe possono essere nidificati.

Fondamentalmente un token ha sempre una lunghezza massima. Per esempio a123 verrà interpretato come un identificatore e non come un identificatore a seguito da un letterale 123.

L'ordine dei token nell'elenco seguente mostra la loro priorità. Ad esempio l'input MODULE verrà intesa come parola chiave e non come identificatore.

. Elenco di tutti i token disponibili:
  • Parole chiave: MODULE, SEC, END_SEC, IMPORTS, E IMPLEMENTED_BY

  • OP: una sequenza non vuota dei seguenti caratteri: .:,%()[]{}<>|+-*/@!?^°=\~

    Nota: gli indicatori di commento //, (*, E *) hanno una priorità più alta rispetto agli operatori. Non può esserci alcun commento all'interno di un operatore, nessun commento può essere, ad esempio: +//+ verrà, secondo la regola della massima lunghezza, interpretato come un operatore e non come + seguito da un commento.

  • LIT: un valore letterale IEC, come viene utilizzato in ST, esempio: 1.4, tod#12:13:14. Ciò include i valori letterali booleani TRUE E FALSE (maiuscolo o minuscolo non è rilevante).

    Nota: letterali non tipizzati con segno negativo (-1, -3.2) verranno letti come due token, cioè come operatore - seguito da un letterale non tipizzato. Il risultato di questi valori letterali numerici non tipizzati non può mai essere negativo. Letterali digitati (INT#-34) verrà sempre interpretato come un token.

  • ID: un identificatore IEC valido ([a-zA-Z_][a-zA-Z0-9_]*), per cui non sono ammesse due sottolineature consecutive. Ciò include, contrariamente a ST, anche le parole chiave di ST (cioè: FUNCTION, INT, EXTENDS,…)

  • Punto e virgola: il carattere ;

Sintassi (parser)

La sintassi della dichiarazione del modulo è definita dalla seguente grammatica. µ è una sequenza vuota.

{MDecl}        ::= MODULE {QID} {ImplSpec} {ImportsSpec} {MBody}
{ImplSpec}     ::= IMPLEMENTED_BY {QID} | µ
{ImportsSpec}  ::= IMPORTS {QID} | µ
{MBody}        ::= {SecList}
{SecList}      ::= {Modifiers} {Sec} {SecList} | µ
{Sec}          ::= SEC {QID} {SecTarget} {EntryList} END_SEC
{SecTarget}    ::= OP(":") {QID} | µ
{Modifiers}    ::= OP("[") {ModifierList} OP("]") | µ
{ModifierList} ::= {QID} OP(",") {ModifierList} | {QID}
{EntryList}    ::= {Modifiers} {Entry} {EntryList}
{Entry}        ::= {Sec} | {Def}
{Def}          ::= {QID} OP(":=") {ValList} SEMICOLON |
                   {QID} SEMICOLON
{ValList}      ::= {Val} {ValList} | {Val}
{Val}          ::= ID | LIT | OP
{QID}          ::= ID | ID OP(".") {QID}

L'elenco dei valori di definizione ({ValList}) deve essere completato con un punto e virgola. Ciò semplifica la grammatica ed evita ambiguità, perché il punto e virgola non può far parte di un valore ({VAL}), tranne che all'interno di una stringa letterale.

L'operatore di assegnazione (:=) delle definizioni ({Def}) serve anche a evitare ambiguità ({QID}) dei nomi e dei valori delle definizioni.

Tipi definiti per le definizioni

  • Testo: ID.ID (nome dell'elenco di testi e identificatore dell'elenco di testi) - vedi Localizzazione delle stringhe dell'elenco di testi

  • Immagine: ID.ID (nome del pool di immagini e identificatore del pool di immagini)

  • ID (identificatore IEC)

  • QID (identificatore qualificato): {QID} ::= ID | ID.ID

  • CategoryPath ::= {StringLiteral} | {CategoryPath}

  • Cardinalità: [{MIN} .. {MAX}] | [ {MIN} .. INF [ {MIN}, E {MAX} sono valori letterali interi e non negativi. Se {MAX} != INF, Poi {MIN} <= {MAX} deve applicare.

  • StringLiteral: una stringa letterale IEC può contenere interruzioni di riga.

  • StdTaskFlags ::= {StdTaskFlag} | {StdTaskFlags} StdTaskFlag ::= NONE | CREATE_IF_MISSING | READONLY

  • Letterale: qualsiasi letterale IEC o QID (per costanti Enum)

  • DTBoolFlag: µ (sequenza vuota) | TRUE | FALSE

  • Tipo di slot: SUBMODULE | REFERENCE

  • Pragma: [ {PragmaList} ] {PragmaList} ::= {Pragma} | {Pragma} , {PragmaList} {Pragma} ::= { ( ID | {StringLiteral} | {OP2} )+ } {OP2} : tutti gli operatori tranne {, }, [, ] E ,.

  • Percorso istanza:

    InstancePath ::= {IComp} | {IComp} . {IComp} mit {IComp} ::= ID {ArrayAccess}* e {ArrayAccess} ::= [ {IntList} ] e {IntList} ::= Int | Int , {IntList}

  • Rif.Attività: Attività_Standard. ( Low | Medium | High) | Custom_Task.ID

Percorsi delle istanze

In alcune posizioni nella dichiarazione del modulo è possibile definire percorsi di istanza per indirizzare una variabile di un blocco funzione: per parametri, slot, I/O, array con dimensioni variabili e riferimenti di istanza.

Un percorso di istanza è definito come una sequenza non vuota di componenti, separati da punti: C1.C2…CN. Un componente deve essere un identificatore IEC o un componente seguito da un'espressione di indice [i1, …, iN], Dove i1 A iN sono valori interi.

I percorsi delle istanze sono sempre relativi al blocco funzione che implementa la logica del modulo. Il primo componente del percorso dell'istanza è un membro (VAR_INPUT O VAR_OUTPUT, a seconda del caso d'uso) del blocco funzione. In caso di componenti aggiuntivi nel percorso dell'istanza, questi componenti indirizzano la variabile all'interno del membro. Altrimenti viene indirizzato il membro stesso. I percorsi delle istanze possono essere limitati alle variabili di ingresso o di uscita (esempio: per I/O). Per le strutture queste restrizioni non valgono. Questo tipo di percorsi di istanza sono chiamati percorsi di istanza di input risp. percorsi delle istanze di output.

Localizzazione delle stringhe dell'elenco di testi

I testi nei moduli (esempio: descrizione del modulo, nome, descrizione del parametro) possono essere visualizzati in diverse lingue. Questi testi vengono gestiti in elenchi di testi.

. Specifica per il nome della lingua:
  • Il nome della lingua è di formato <LanguageCode>[-<Country/Region>] (esempio: en-US, de-DE).

  • <LanguageCode> è il nome della lingua secondo ISO 639-1 (esempio: de O en).

  • <Country/Region> è un codice paese secondo ISO 3166.

  • Quando si richiama una voce dell'elenco di testi, il sistema cerca innanzitutto il nome completo della lingua. Se non viene trovato nulla, cerca il file <LanguageCode>. Se anche questa ricerca fallisce, verrà utilizzato il testo predefinito.

Tabella 8. Esempi di nomi di lingue negli elenchi di testi

Lingua

Nome della lingua

Cinese

zh-CHS

Inglese

it-USA

francese

fr-FR

Tedesco

de-DE

Italiano

esso esso

giapponese

ja-JP

portoghese

pt-PT

russo

ru-RU

spagnolo

es-ES



Derivazione delle dichiarazioni dei moduli

Analogamente all'ereditarietà orientata agli oggetti di un blocco funzione A da un blocco funzione B ("EXTENDS") esiste la possibilità di derivare dichiarazioni di moduli utilizzando l'istruzione IMPORTS parola chiave. I modificatori UPDATE E HIDE vengono trattati in modo speciale.

. Vengono utilizzate le seguenti regole:
  • Il nome del modulo importato deve essere specificato con namespace se questo modulo è definito in una libreria diversa.

  • Non sono consentite importazioni cicliche, in particolare un modulo non deve importare se stesso. (Esempio di importazione ciclica: il modulo M_1 importa il modulo M_2, M_2 importa M_3, …, M_N importa nuovamente M_1.)

  • Un modulo derivato può essere definito senza il file IMPLEMENTED_BY direttiva. In questo caso verrà utilizzato il blocco funzione del modulo base.

  • Se un modulo derivato specifica un blocco funzione (tramite l'uso di MPLEMENTED_BY), questo blocco funzione deve derivare dal blocco funzione del modulo base oppure deve essere identico ad esso.

  • Un modulo derivato eredita tutte le sezioni del modulo base. Può aggiungere nuove sezioni o modificare sezioni esistenti.

  • Una sezione può essere modificata nel modulo derivato utilizzando lo stesso nome e destinazione estesi con il modificatore UPDATE. In questo caso, le sue voci vengono modificate. Tutte le definizioni mancanti della sezione nel modulo derivato verranno riprese dal modulo base.

  • Il modificatore UPDATE E HIDE può essere utilizzato solo se la rispettiva sezione (nome e destinazione) è definita nel modulo base. Al contrario, una sezione definita nel modulo base può essere utilizzata nel modulo derivato solo se ha l'estensione HIDE O UPDATE modificatore. Se c'è solo il HIDE modificatore nella sezione e non UPDATE, allora non sono ammesse definizioni.

  • Alcune voci devono essere modificate nel modulo derivato (esempio: la descrizione).

Esempio 15. Esempio:
MODULE MBase IMPLEMENTED_BY FBBase
SEC MetaData
        DESC := TL.Desc_Base ;
END_SEC
SEC Parameters
        SEC Param : paramxIn
                Variable := xIn ;
                Name     := TL.Param1_Name ;
                Desc     := TL.Param1_Desc ;
        END_SEC
END_SEC

MODULE MDerived IMPORTS MBase
[UPDATE] SEC MetaData
        DESC := TL.Desc_Derived ;
END_SEC
[UPDATE] SEC Parameters
        [UPDATE,HIDE] SEC Param : paramIn
                Variable := xIn ;
                DEFAULT := TRUE ;
        END_SEC
END_SEC


Nell'esempio sopra il parametro paramIn del modulo MBase è nascosto nel modulo derivato MDerived (utilizzando il HIDE modificatore) e allo stesso tempo un nuovo valore predefinito (TRUE) è impostato.

Note sull'ordine delle sezioni e definizioni

L'ordine delle sezioni direttamente dopo l'intestazione del modulo è irrilevante. All'interno delle sezioni l'ordine può essere molto importante. Ad esempio, l'ordine delle dichiarazioni degli slot definisce l'ordine dei moduli nell'albero dei moduli.

L'ordine delle definizioni è sempre irrilevante.

. Regole per i moduli derivati relativi all'ordine:
  • Le sezioni dei moduli base sono sempre definite prima delle sezioni del modulo stesso.

  • Se una sezione del modulo base viene modificata mediante l'uso di UPDATE O HIDE, il suo ordine non viene influenzato.

  • Non è possibile per un modulo derivato modificare l'ordine definito nel modulo base.

Completamento automatico e "componenti elenco"

Quando si inizia a digitare nell'editor del modulo, tutte le definizioni di sezione disponibili/possibili vengono visualizzate in un menu "elenco componenti". Vengono mostrate solo le sezioni e le definizioni significative per la posizione corrente. Anche se alcune voci di sottosezione hanno lo stesso nome delle voci di sottosezione di altre sezioni, proverà a visualizzare solo le definizioni di sezione corrispondenti.

Se Ritorno viene premuto dopo aver completato la prima riga di una sezione, la sezione verrà completata con tutte le definizioni/sezioni necessarie e il file END_SEC .

Dopo le definizioni delle variabili, le variabili di input/output vengono presentate dalle definizioni dei "componenti dell'elenco". I flag o i valori predefiniti vengono presentati anche in una selezione "elenco componenti", che mostra i possibili flag/valori.

Dopo le definizioni, che utilizzano voci di elenchi di testi o voci di pool di immagini (esempio: la maggior parte delle volte Desc :=), viene presentato un menu "Elenco componenti" che comprende tutti gli elenchi di testi o i pool di immagini disponibili e visibili e le relative voci.

Premendo F2, è possibile aprire il supporto di input corrispondente.

Sezioni della dichiarazione del modulo

Sezione: Metadati

Sezione: Livello superiore

Sezione: IO

Sezione: Parametri

Sezione: Slot

Sezione: Visi

Sezione: Procure

Sezione: VarArray

Sezione: Vincoli

Sezione: Rif.Ist

Sezione: mse.Sequenza

Generatore di dispositivi

alg.Allarme