Lexicale structuur

Documenten

Een M-document is een geordende reeks Unicode-tekens. M staat verschillende klassen Unicode-tekens toe in verschillende delen van een M-document. Zie de Unicode-standaard, versie 3.0, sectie 4.5 voor meer informatie over Unicode-tekenklassen.

Een document bestaat uit precies één expressie of groepen definities die zijn ingedeeld in secties. In hoofdstuk 10 worden de secties gedetailleerd beschreven. Conceptueel gezien worden de volgende stappen gebruikt om een expressie uit een document te lezen:

  1. Het document wordt gedecodeerd volgens het tekencoderingsschema in een reeks Unicode-tekens.

  2. Lexicale analyse wordt uitgevoerd, waardoor de stroom Unicode-tekens wordt omgezet in een stroom tokens. De resterende subsecties van deze sectie hebben betrekking op lexicale analyse.

  3. Syntactische analyse wordt uitgevoerd, waardoor de stroom tokens wordt omgezet in een formulier dat kan worden geëvalueerd. Dit proces wordt behandeld in de volgende secties.

Conventies met betrekking tot de grammatica

De lexicale en syntactische grammatica worden gepresenteerd met behulp van grammaticaproducties. Elke grammaticaproductie definieert een niet-terminalsymbool en de mogelijke uitbreidingen van dat niet-terminale symbool in reeksen van niet-terminale of terminalsymbolen. In grammaticaproducties worden niet-terminal+ symbolen weergegeven in cursief type en terminalsymbolen worden weergegeven in een lettertype met vaste breedte.

De eerste regel van een grammaticaproductie is de naam van het niet-terminale symbool dat wordt gedefinieerd, gevolgd door een dubbele punt. Elke opeenvolgende ingesprongen lijn bevat een mogelijke uitbreiding van de niet-terminale opgegeven als een reeks niet-terminale of terminalsymbolen. Neem bijvoorbeeld de volgende productieregel:

if-expression:
      ifif-conditionthentrue-expressionelsefalse-expression

definieert een if-expressie die uit het token ifbestaat, gevolgd door een if-voorwaarde, gevolgd door het token then, gevolgd door een true-expression, gevolgd door het token else, gevolgd door een false-expression.

Wanneer er meer dan één mogelijke uitbreiding van een niet-terminaal symbool is, worden de alternatieven weergegeven op afzonderlijke regels. Neem bijvoorbeeld de volgende productieregel:

variable-list:
      Variabele
      variabele met variabelenlijst
,

definieert een lijst met variabelen die bestaat uit een variabele of bestaat uit een lijst met variabelen , gevolgd door een variabele. Met andere woorden, de definitie is recursief en geeft aan dat een lijst met variabelen bestaat uit een of meer variabelen, gescheiden door komma's.

Een subscripted achtervoegsel 'opt' wordt gebruikt om een optioneel symbool aan te geven. De productie:

veldspecificatie:
      optionalveldtype opt-name=

is een korte aanduiding voor:

veldspecificatie:
      veldnaamveldtype
=
      optionalveldnaamveldtype=

en definieert een veldspecificatie om optioneel te beginnen met het terminalsymbool optional gevolgd door een veldnaam, het terminalsymbool =en een veldtype.

Alternatieven worden normaal gesproken vermeld op afzonderlijke regels, maar in gevallen waarin er veel alternatieven zijn, kan de woordgroep 'een van' voorafgaan aan een lijst met uitbreidingen die op één regel worden gegeven. Dit is gewoon een afkorting voor het weergeven van elk van de alternatieven op een afzonderlijke regel. Neem bijvoorbeeld de volgende productieregel:

decimal-digit: een van
      0 1 2 3 4 5 6 7 8 9

is een korte aanduiding voor:

decimal-digit:
      0
      1
      2
      3
      4
      5
      6
      7
      8
      9

Lexicale analyse

De productie van lexicale eenheden definieert de lexicale grammatica voor een M-document. Elk geldig M-document voldoet aan deze grammatica.

lexicale eenheid:
      kies voor lexicale elementen
lexicale elementen:
      lexical-element
      lexical-element
      lexicale elementen
lexical-element:
      spatie
      tokencommentaar

Op lexical niveau bestaat een M-document uit een stroom witruimte-, opmerking- en tokenelementen . Deze productieregels worden besproken in de volgende secties. Alleen tokenelementen zijn significant in de syntactische grammatica.

Spatie

Witruimte wordt gebruikt om opmerkingen en tokens in een M-document te scheiden. Witruimte bevat het spatieteken (dat deel uitmaakt van Unicode-klasse Zs), evenals horizontale en verticale tabs, formulierfeeds en nieuwelijntekenreeksen. Nieuwe regeltekenreeksen omvatten regelterugloop, regelinvoer, regelterugloop gevolgd door regelinvoer, volgende regel en alineascheidingstekens.

witruimte:
      Elk teken met Unicode-klasse Zs
      Horizontaal tabteken (U+0009)
      Verticaal tabteken (U+000B)
      Formulierfeedteken (U+000C)
      Regelterugloopteken (U+000D) gevolgd door regelinvoerteken (U+000A)
      new-line-character
new-line-character:
      Regelterugloopteken (U+000D)
      Teken voor regelinvoer (U+000A)
      Volgend regelteken (U+0085)
      Teken voor regelscheidingsteken (U+2028)
      Alineascheidingsteken (U+2029)

Voor compatibiliteit met hulpprogramma's voor het bewerken van broncode die einde-of-bestandmarkeringen toevoegen en om in te schakelen dat een document kan worden weergegeven als een reeks correct beëindigde regels, worden de volgende transformaties toegepast op een M-document:

  • Als het laatste teken van het document een Control-Z-teken (U+001A) is, wordt dit teken verwijderd.

  • Een regelterugloopteken () wordt toegevoegd aan het einde van het document als dat document niet leeg is en als het laatste teken van het document geen regelterugloop (U+000D), een regelinvoer (U+000AU+000D), een regelscheidingsteken (U+2028) of een alineascheidingsteken (U+2029) is.

Opmerkingen

Er worden twee vormen van opmerkingen ondersteund: opmerkingen met één regel en gescheiden opmerkingen. Opmerkingen met één regel beginnen met de tekens // en worden uitgebreid tot het einde van de bronregel. Opmerkingen met scheidingstekens beginnen met de tekens /* en eindigen op de tekens */.

Door scheidingstekens gescheiden opmerkingen kunnen meerdere regels omvatten.

Commentaar:
      opmerking met één regel
      met scheidingstekens gescheiden opmerking
opmerking met één regel:

      //Opt voor één regel-opmerking-tekens
tekens met één regel opmerking:
      opt-tekens voor één regel-opmerking-tekenmet één regel
teken met één regel opmerking:

      Unicode-tekens behalve een nieuw regelteken
met scheidingstekens gescheiden opmerking:

      /*sterretjes met scheidingstekens voor tekst met scheidingstekens/
tekst met scheidingstekens:
      sectie met scheidingstekens voor scheidingstekens voor tekst
met scheidingstekens voor opmerkingen:

      /
      sterretjes kiezen voor not-slash-or-asterisk
Sterretjes:

      *sterretjeskiezen
not-slash-or-asterisk:

      Unicode-tekens behalve * of /

Opmerkingen worden niet genest. De tekenreeksen /* en */ hebben geen speciale betekenis binnen een eenregelig commentaar. De tekenreeksen // en /* hebben geen speciale betekenis binnen een commentaar met scheidingstekens.

Opmerkingen worden niet verwerkt binnen letterlijke tekst. Het voorbeeld

/* Hello, world 
*/ 
    "Hello, world"

bevat een opmerking met scheidingstekens.

Het voorbeeld

// Hello, world 
// 
"Hello, world" // This is an example of a text literal

toont verschillende opmerkingen met één regel.

Tokens

Een token is een id, trefwoord, letterlijke operator of interpunctie. Witruimte en opmerkingen worden gebruikt om tokens te scheiden, maar worden niet beschouwd als tokens.

Token:
      id
      Trefwoord
      Letterlijke
      operator-or-punctuator

Escapereeksen voor tekens

M-tekstwaarden kunnen willekeurige Unicode-tekens bevatten. Letterlijke tekst is echter beperkt tot grafische tekens en vereist het gebruik van escapereeksen voor niet-grafische tekens. Als u bijvoorbeeld een teken voor regelterugloop, regelfeed of tab wilt opnemen in een letterlijke tekst, kunnen de #(cr), #(lf)en #(tab) escape-reeksen worden gebruikt. Als u de escapesequence-begintekens #( wilt insluiten in een letterlijke tekst, moet het # zelf worden escaped:

#(#)(

Escapereeksen kunnen ook korte (vier hexcijferige cijfers) of lange (acht hexcijferige) Unicode-codepuntwaarden bevatten. De volgende drie escapereeksen zijn daarom gelijkwaardig:

#(000D)     // short Unicode hexadecimal value 
#(0000000D) // long Unicode hexadecimal value 
#(cr)       // compact escape shorthand for carriage return

Meerdere escapecodes kunnen worden opgenomen in één escape-reeks, gescheiden door komma's; de volgende twee reeksen zijn dus gelijkwaardig:

#(cr,lf) 
#(cr)#(lf)

Hieronder wordt het standaardmechanisme beschreven voor escape-tekens in een M-document.

character-escape-sequence:
      #(escape-sequence-list)
escape-sequence-list:
      een escape-reeks
      escape-sequence escape-list met één escape-sequence
,
een escape-reeks:
      lange unicode-escape-reeks
      short-unicode-escape-sequence
      control-character-escape-sequence
      escape-escape
long-unicode-escape-sequence:
      hex-digit hex-digit hex-digit hex-digit hex-digit hex-digit hex-digit hex-digit
short-unicode-escape-sequence:
      hex-digit hex-digit hex-digit hex-digit
control-character-escape-sequence:
      control-character
control-character:

      cr
      lf
      tab
escape-escape:
      #

Letterlijke waarden

Een literal oftewel letterlijke waarde is een representatie van de broncode van een waarde.

Letterlijke:
      logische letterlijke waarde
      getal-letterlijke waarde
      letterlijke tekst
      null-letterlijke waarde
      letterlijke letterlijke verbatim

Null-letterlijke waarden

De letterlijke waarde null wordt gebruikt om de null waarde te schrijven. De null waarde vertegenwoordigt een afwezige waarde.

null-literal:
      null

Logische literals

Een logische letterlijke waarde wordt gebruikt om de waarden true te schrijven en false een logische waarde te produceren.

logische letterlijke waarde:
      true
      false

Numerieke letterlijke waarden

Een letterlijk getal wordt gebruikt om een numerieke waarde te schrijven en een getalwaarde te produceren.

aantal-letterlijke waarden:
      decimaal-getal-letterlijk
      hexadecimale-getal-letterlijke
decimaal-getal-letterlijk:
      decimal-digits
.decimal-digits exponent-partopt
      .exponent-part-optvoor decimale cijfers
      exponent-part-optvoor decimale cijfers
decimale cijfers:
      kies voordecimale cijfers
decimal-digit:
een van
      0 1 2 3 4 5 6 7 8 9
exponent-part:
      etekenkiezen voor decimale cijfers
      Etekenkiezen voor decimale cijfers
teken:
een van
      + -
hexadecimale-getal-letterlijke waarde:
      0xhex-digits
      0Xhex-digits
hex-digits:
      hex-digit hex-digitsopt
hex-digit:
een van
      0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f

Een getal kan worden opgegeven in hexadecimale notatie door de hex-digits met de tekens 0xte voorafgaan. Bijvoorbeeld:

0xff // 255

Houd er rekening mee dat als een decimaalteken is opgenomen in een letterlijke waarde van een getal, er ten minste één cijfer achter moet staan. Is bijvoorbeeld 1.3 een letterlijke waarde van een getal, 1.e3 maar 1. niet.

Letterlijke tekstwaarde

Een letterlijke tekst wordt gebruikt om een reeks Unicode-tekens te schrijven en een tekstwaarde te produceren.

letterlijke tekst:
      "opt voor tekst-letterlijke tekens"
letterlijke tekst:
      tekst-letterlijk-teken-letterlijk-tekenskiezen
tekst-letterlijk-teken:
      één tekstteken
      teken-escape-reeks
      double-quote-escape-sequence
enkel tekstteken:

      Elk teken behalve " (U+0022) of # (U+0023) gevolgd door ( (U+0028)
double-quote-escape-sequence:
      "" (U+0022, U+0022)

Als u aanhalingstekens wilt opnemen in een tekstwaarde, wordt het aanhalingsteken als volgt herhaald:

"The ""quoted"" text" // The "quoted" text

De tekenreeksproductie kan worden gebruikt om tekens in tekstwaarden te schrijven zonder ze rechtstreeks te hoeven coderen als Unicode-tekens in het document. Een regelterugloop en regelfeed kunnen bijvoorbeeld worden geschreven in een tekstwaarde als:

"Hello world#(cr,lf)"

Letterlijke letterlijke bewoordingen van de exacte bewoordingen

Een letterlijke letterlijke bewoording wordt gebruikt om een reeks Unicode-tekens op te slaan die door een gebruiker als code zijn ingevoerd, maar die niet correct als code kunnen worden geparseerd. Tijdens runtime wordt er een foutwaarde gegenereerd.

letterlijke verbatim:
      #!"opt voor tekst-letterlijke tekens"

Identifiers

Een id (identifier) is een naam die wordt gebruikt om naar een waarde te verwijzen. Id's kunnen reguliere id's of aan geciteerde id's zijn.

Id:
      regular-identifier
      id tussen aan/ uit
regular-identifier:
      beschikbare id
      available-identifier dot-character regular-identifier
beschikbare id:

      Een trefwoord of id die geen trefwoord is
trefwoord of id:
      id-start-character identifier-part-charactersopt
id-beginteken:
      letterteken
      onderstrepingsteken
identifier-part-characters:
      id-part-character identifier-part-charactersopt
id-part-character:
      letterteken
      decimal-digit-character
      onderstrepingsteken
      verbindingsteken
      combineren-teken
      opmaakteken
puntteken:

      . (U+002E)
onderstrepingsteken:
      _ (U+005F)
letterteken:
      Een Unicode-teken van klassen Lu, Ll, Lt, Lm, Lo of Nl
combineren-teken:
      Een Unicode-teken van klassen Mn of Mc
decimal-digit-character:
      Een Unicode-teken van de klasse Nd
verbindingsteken:
      Een Unicode-teken van de klasse-pc
opmaakteken:
      Een Unicode-teken van de klasse Cf

Een aanhalingsteken-id kan worden gebruikt om elke reeks nul of meer Unicode-tekens toe te staan als id, waaronder trefwoorden, witruimte, opmerkingen, operators en interpuncties.

aan/uit-id:
      #"opt voor tekst-letterlijke tekens"

Houd er rekening mee dat escapereeksen en dubbele aanhalingstekens voor escape-aanhalingstekens kunnen worden gebruikt in een aanhalingstekens, net zoals in een letterlijke tekst.

In het volgende voorbeeld wordt id-aanhalingsteken gebruikt voor namen die een spatieteken bevatten:

[ 
    #"1998 Sales" = 1000, 
    #"1999 Sales" = 1100, 
    #"Total Sales" = #"1998 Sales" + #"1999 Sales"
]

In het volgende voorbeeld wordt de id-aanhaling gebruikt om de + operator in een id op te nemen:

[ 
    #"A + B" = A + B, 
    A = 1, 
    B = 2 
]

Gegeneraliseerde id's

Er zijn twee plaatsen in M waar geen dubbelzinnigheden worden geïntroduceerd door id's die lege waarden bevatten of die anderszins trefwoorden of letterlijke getallen zijn. Deze plaatsen zijn de namen van recordvelden in een letterlijke record en in een operator voor veldtoegang ([ ]) Daar staat M dergelijke id's toe zonder aanhalingstoken-id's te hoeven gebruiken.

[ 
    Data = [ Base Line = 100, Rate = 1.8 ], 
    Progression = Data[Base Line] * Data[Rate]
]

De id's die worden gebruikt voor naam- en toegangsvelden worden gegeneraliseerde id's genoemd en als volgt gedefinieerd:

gegeneraliseerde id:
      generalized-identifier-part
      gegeneraliseerde id
, gescheiden door lege waarden (U+0020)
generalized-identifier-part
generalized-identifier-part:
      gegeneraliseerde id-segment
      decimal-digit-character generalized-identifier-segment
gegeneraliseerde id-segment:
      trefwoord of id
      trefwoord-of-id-punt-teken-trefwoord-of-id

Trefwoorden

Een trefwoord is een id-achtige reeks tekens die is gereserveerd en kan niet worden gebruikt als een id, behalve wanneer u het mechanisme voor het aanhalen van id's gebruikt of waar een gegeneraliseerde id is toegestaan.

trefwoord: een van
       and as each else error false if in is let meta not null or otherwise
       section shared then true try type #binary #date #datetime
       #datetimezone #duration #infinity #nan #sections #shared #table #time

Operatoren en leestekens

Er zijn verschillende soorten operatoren en leestekens. Operators worden gebruikt in expressies om bewerkingen met een of meer operanden te beschrijven. De expressie a + b gebruikt bijvoorbeeld de operator + om de twee operanden a en b toe te voegen. Interpunctietekens zijn bedoeld voor groepering en scheiding.

operator-or-punctuator: een van
      , ; = < <= > >= <> + - * / & ( ) [ ] { } @ ! ? ?? => .. ...