The Open Protocol Notation Programming Guide 1 Document Version 1 (4/23/2018)



Download 1.37 Mb.
Page12/24
Date23.04.2018
Size1.37 Mb.
#46651
1   ...   8   9   10   11   12   13   14   15   ...   24

Application Layer


Next a simple application layer protocol is described that travels on top of MiniTCP. The protocol, called Echo, simply echoes data it receives in arbitrary order, but without any lost. Incoming messages carry the string that contains the message to be echoed, plus the user name that initiated the message.

protocol Echo;

using MiniTcp;

// The MiniTCP port is used by the Echo protocol.

const Port EchoPort = 99;

// Post received by the server with the message to be echoed and the user

// that generated the message.

message Post {

string Content;

string UserName;

}

// The echoed message.



message Echo {

string Content;

}

The EchoServer accepts Post messages (sent by the clients) and issues Echo messages, representing the echoed data. The endpoint also keeps a list of users that are allowed to send Post messages. If a message from a user that is not in the list is received, the message is ignored.


// The EchoServer is stacked on top of a Socket with the proper ports.

endpoint EchoServer 

over Socket where value.SourcePort == EchoPort 

&&  value.DestinPort in EphemeralPorts; 

accepts Post issues Echo

{

// Messages that arrived and were not echoed yet.



array unechoed = [];

// List of users that are allowed to request an echo. How this list

// is retrieved is abstracted, and can be thought of as being a static

// list.


array allowedUsers = getAllowedUsers();

// The message is accepted only if the user is allowed. In case it is

// not, the message will not match the rule and will be just ignored.

observe this accepts m:Post{UserName in allowedUsers}

{

unechoed += [m.Content];



// When an Echo is issued, to be sure its content is unechoed

// add an assertion to validate this logic.

observe this issues m:Echo{}

{

assert m.Content in unechoed;



unechoed = unechoed.Remove(m.Content);

}

}



The contract on the endpoint assures that only data that has been posted can be echoed. Observe that since this is our top-level protocol, we do not need process rules to consume messages and dispatch them up the stack.

Next, the parsing actor is defined that maps from a TCP socket to the echo endpoint. This parser will be automatically started on a socket that uses the port for the Echo protocol.

// This is the actor that listens on the server socket indexed by

// the EchoPort.

actor autostart EchoServerParser(

Socket serverSocket where value.SourcePort == EchoPort)

{

// A MiniTCP Segment is matched, the Payload is decoded to a Post



// message and dispatched to EchoServer.

process serverSocket accepts Segment{Payload is m:Post

from BinaryDecoder}

{

dispatch (endpoint EchoServer over socket) accepts m;



}

// A similar rule for the other direction.



//...

}

  1. Language Reference

    1. Lexis

      1. Lexical Unit


LexicalUnit ::= LexicalElement*

LexicalElement ::= Whitespace | Comment | Token

Token ::= Identifier | Keyword | Literal | OperatorOrPunctuator
      1. Whitespace


Whitespace ::= any charater with Unicode class Zs
| tab characters (U+0009, U+000B)
| formfeed character (U+000C)


| Newline

NewLine ::= carriage return (U+000D)

| line feed (U+000A),

| next line (U+0085)
      1. Comments


Comment ::= SingleLineComment | MultiLineComment

SingleLineComment ::= // (! NewLine)*

MultiLineComment ::= /* ( ! */ )* */
      1. Literals


Literal ::= BooleanLiteral | IntegerLiteral | FractionalLiteral | CharacterLiteral | StringLiteral

| NullLiteral | NothingLiteral | BinaryLiteral | GuidLiteral | DecimalLiteral

BooleanLiteral ::= true | false

IntegerLiteral ::= Sign? DecimalDigit+ | ( 0x | 0X ) HexDigit+ | ( 0b | 0B ) BinaryDigit+

| (0o | 0O) OctetDigit+

FractionalLiteral ::= Sign? DecimalDigit* . DecimalDigit+ Exponent?

DecimalLiteral ::= FractionalLiteral (m | M) | Sign? DecimalDigit+ (m | M)

Exponent ::= ( e | E ) Sign? DecimalDigit+

Sign ::= + | -

BinaryDigit ::= 0 | 1

OctetDigit ::= BinaryDigit | 2 |3 |4 |5 |6 |7

DecimalDigit ::= OctetDigit |8 |9

HexDigit ::= DecimalDigit | a | A |b | B |c | C |d |D |e |E|f |F

CharacterLiteral ::= ' ( ! ' & VisibleCharacter | \' | CharacterEscape ) '

CharacterEscape ::= \xHexDigit#4 | \xHexDigit#8 | \CharacterEscapeControl

CharacterEscapeControl ::= 0 | a |b | f | n | r |t |v

StringLiteral ::= SingleLineStringLiteral | MultilineStringLiteral

SingleLineStringLiteral ::= " ( ! " & VisibleCharacter | \" | CharacterEscape )* " MultiLineStringLiteral ::=

@ " ( ! " & VisibleCharacter | \" | Newline | CharacterEscape )* "

BlockLiteral ::= { ( \} | \{ | \\ | VisibleCharater | NewLine | BlockLiteral )* }

NullLiteral ::= null

NothingLiteral ::= nothing

BinaryLiteral ::= $[ ( HexDigit HexDigit )* ] | Base64Literal

Base64Literal ::= TO BE DONE

GuidLiteral ::= { HexDigit#8 - HexDigit#4 - HexDigit#4 - HexDigit#4 - HexDigit#12 }

VisibleCharacter ::= TO BE DONE (specify unicodes)

Newline ::= TO BE DONE (specify unicodes for CR or CR LF)

The intention of the BlockLiteral is to allow embedding of an alien grammar within OPN. It allows nesting braces without escaping as long as the braces are balanced. If this is not the case, writers have to escape unbalanced braces. The same rule holds for the backslash ( \ ), and can be escaped, that is (\\), if needed.


      1. Identifiers and Keywords


QualifiedIdentifier ::= Identifier ( . Identifier )*

Identifier ::= KeywordOrIdentifier without Keyword | @ KeywordOrIdentifier | $ StringLiteral

KeywordOrIdentifier ::= IdentifierBegin IdentifierContinue* IdentifierEnd | IdentifierSingle

IdentifierBegin ::= one of _ Letter

IdentifierContinue ::= one of Letter DecimalDigit

IdentifierEnd = one of _ Letter DecimalDigit

IdentifierSingle = Letter

Letter ::= unicode character of class Lu, Ll, Lt, Lm, Lo, Nl, Mn, Mc, Pc, Cf

Keyword ::= any of:

abstract accepts actor annotation any array as aspect assert autostart
binary binding bool break byte


case catch change char connection const consumes continue contract

decimal default delete dispatch do double

enum else endpoint error exception extends extern

false finally flags float from for foreach follows

get guid

if in int interface internal invariant is issues

json

long

map metadata message module

new nothing null

observe operation operator over override

pattern precedes process protocol provides public

regex ref return role rule

sbyte select set short static string success switch syntax

throw treedata true try type typedef

uint ulong using ushort

value var virtual void

where while with

xml xpath

WeakKeyword::= any of:

all bind create exists freeze optional out result some start stop this ignore separator
      1. Operators and Punctuators


Note that multi-character operators (for example &&, >=, #.., and so on) should be considered as single tokens, and therefore they do not allow spaces or tabs interleaved.

OperatorOrPunctuator ::= any of:

{ } [ ] ( ) . , + - * / % ! = < > & ^ ; # ` ?

&& || == != <= >= => | & ^ ==> <=> ~ .. ... << >> += -= ++ -- ?? #? #..




    1. Download 1.37 Mb.

      Share with your friends:
1   ...   8   9   10   11   12   13   14   15   ...   24




The database is protected by copyright ©ininet.org 2024
send message

    Main page