Lexikal struktur

Dokument

Ett M-dokument är en ordnad sekvens med Unicode-tecken. M tillåter olika klasser av Unicode-tecken i olika delar av ett M-dokument. Information om Unicode-teckenklasser finns i Unicode-standarden version 3.0, avsnitt 4.5.

Ett dokument består antingen av exakt ett uttryck eller av grupper av definitioner indelade i avsnitt. Avsnitt beskrivs i detalj i kapitel 10. Följande steg används för att läsa ett uttryck från ett dokument:

  1. Dokumentet avkodas enligt dess teckenkodningsschema till en sekvens med Unicode-tecken.

  2. En lexikalisk analys utförs, då dataströmmen med Unicode-tecken översätts till en dataström med token. De återstående underavsnitten i det här avsnittet beskriver lexikal analys.

  3. Syntaktisk analys utförs, då dataströmmen med token översätts till ett formulär som kan utvärderas. Den här processen beskrivs i följande avsnitt.

Grammatiska konventioner

Lexikal och syntaktisk grammatik presenteras med hjälp av grammatisk produktion. Varje grammatisk produktion definierar en icke-terminalsymbol och de möjliga expansionerna av denna icke-terminalsymbol i sekvenser av icke-terminal- eller terminalsymboler. I grammatisk produktion visas _icke-terminal+-symbolerna som kursiv typ, och terminalsymboler visas i ett teckensnitt med fast bredd.

Den första raden i en grammatisk produktion är namnet på den icke-terminalsymbol som definieras, följt av ett kolon. Varje efterföljande indragen rad innehåller en möjlig expansion av den icke-terminalsymbol som anges som en sekvens av icke-terminal- eller terminalsymboler. Till exempel produktionen:

if-expression:
      ifif-conditionthentrue-expressionelsefalse-expression

definierar ett if-expression som ska bestå av token if, följt av ett if-condition följt av token then, följt av ett true-expression följt av token else, följt av ett false-expression.

Om det finns mer än en möjlig expansion av en icke-terminalsymbol visas alternativen på separata rader. Till exempel produktionen:

variable-list:
      variabel
      variabel-listvariabel
,

definierar en variable-list som antingen består av en variable eller av en variable-list följt av en variable. Med andra ord är definitionen rekursiv och anger att en variabellista består av en eller flera variabler, avgränsade med kommatecken.

Ett nedsänkt suffix ”opt” används för att ange en valfri symbol. Produktionen:

field-specification:
      optionalopt field-name=fälttyp

är en förkortning för:

fältspecifikation:
      field-name
=field-type
      optionalfältnamn=fälttyp

och definierar en field-specification för att (valfritt) börja med terminalsymbolen optional följt av ett field-name, terminalsymbolen = och en field-type.

Alternativ visas vanligtvis på separata rader, men i de fall där det finns många alternativ kan frasen ”en av” komma före en lista över expansioner som visas på en enda rad. Detta är bara ett kortare sätt istället för att visa varje alternativ på en separat rad. Till exempel produktionen:

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

är en förkortning för:

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

Lexikal analys

lexical-unit-produktionen definierar den lexikala grammatiken för ett M-dokument. Varje giltigt M-dokument följer denna grammatik.

lexikal enhet:
      lexical-elementsopt
lexikala element:
      lexical-element
      lexical-element
      lexikala element
lexical-element:
      Blanksteg
      tokenkommentar

På den lexikala nivån består ett M-dokument av en dataström av elementen blanksteg, kommentar och token. Var och en av dessa produktioner beskrivs i följande avsnitt. Endast token-elementen är viktiga i syntaktisk grammatik.

Blanksteg

Blanksteg används för att avgränsa kommentarer och tokens i ett M-dokument. Blanksteg innehåller blankstegstecknet (som är en del av Unicode-klassen Zs), samt vågräta och lodräta tabbar, formulärflöde och sekvenser av tecken för ny rad. Sekvenser av tecken för ny rad innehåller vagnretur, radmatning, vagnretur följt av radmatning, nästa rad och styckeavgränsningstecken.

whitespace:
      Valfritt tecken med Unicode-klassen Zs
      Vågrätt tabbtecken (U+0009)
      Lodrätt tabbtecken (U+000B)
      Tecken för formulärflöde (U+000C)
      Vagnreturtecken (U+000D) följt av radmatningstecken (U+000A)
      new-line-character
new-line-character:
      Vagnreturtecken (U+000D)
      Radmatningstecken (U+000A)
      Tecken för nästa rad (U+0085)
      Tecken för radavgränsare (U+2028)
      Tecken för styckeavgränsare (U+2029)

För kompatibilitet med redigeringsverktyg för källkod som lägger till markörer för filslut, och för att göra det möjligt att visa ett dokument som en sekvens av korrekt avslutade rader, används följande omvandlingar, i ordning, på ett M-dokument:

  • Om det sista tecknet i dokumentet är ett Ctrl-Z-tecken (U+001A) tas det tecknet bort.

  • Ett vagnreturtecken (U+000D) läggs till i slutet av dokumentet om dokumentet inte är tomt och om det sista tecknet i dokumentet inte är en vagnretur (U+000D), en radmatning (U+000A), en radavgränsare (U+2028) eller en styckeavgränsare (U+2029).

Kommentarer

Två former av kommentarer stöds: enkelradskommentarer och avgränsade kommentarer. Enkelradskommentarer börjar med tecknen // och sträcker sig till slutet av källraden. Avgränsade kommentarer börjar med tecknen /* och slutar med tecknen */.

Avgränsade kommentarer kan sträcka sig över flera rader.

Kommentar:
      enkelradskommentar
      avgränsad kommentar
single-line-comment:

      //single-line-comment-charactersopt
single-line-comment-characters:
      single-line-comment-character single-line-comment-charactersopt
single-line-comment-character:

      Alla Unicode-tecken utom ett nytt radtecken
avgränsad kommentar:

      /*avgränsad-kommentar-textopt asterisker/
avgränsad-kommentar-text:
      avgränsat-kommentarsavsnitt avgränsat-kommentar-textopt
avgränsat-kommentar-avsnitt:

      /
      asterisksopt not-slash-or-asterisk
Asterisker:

      *asterisksopt
not-slash-or-asterisk:

      Valfritt Unicode-tecken utom * eller /

Kommentarerna kapslas inte. Teckensekvenserna /* och */ har ingen särskild betydelse inom en enkelradskommentar, och teckensekvenserna // och /* har ingen särskild betydelse inom en avgränsad kommentar.

Kommentarer bearbetas inte inom textliteraler. Exemplet

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

innehåller en avgränsad kommentar.

Exemplet

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

visar flera enkelradskommentarer.

Token

En token är en identifierare, ett nyckelord, en literal, operator eller skiljetecken. Blanksteg och kommentarer används för att avgränsa token, men betraktas inte som token.

Token:
      identifierare
      Sökord
      Bokstavlig
      operator-or-punctuator

Tecken-escape-sekvenser

M-textvärden kan innehålla godtyckliga Unicode-tecken. Textliteraler är dock begränsade till grafiska tecken och kräver användning av escape-sekvenser för icke-grafiska tecken. Om du till exempel vill inkludera ett vagnretur-, radmatnings- eller tabbtecken i en textliteral kan escape-sekvenserna #(cr), #(lf) och #(tab) användas. Om du vill bädda in starttecknet för escape-sekvensen #( i en textliteral måste # i sig själv vara undantagen:

#(#)(

Escape-sekvenser kan också innehålla korta (fyra hexadecimala siffror) eller långa (åtta hexadecimala siffror) Unicode-code-point-värden. Följande tre escape-sekvenser är därför likvärdiga:

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

Flera escape-koder kan inkluderas i en enda escape-sekvens, avgränsade med kommatecken. Följande två sekvenser är alltså likvärdiga:

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

I följande avsnitt beskrivs standardmekanismen för teckenundantag i ett M-dokument.

character-escape-sequence:
      #(escape-sequence-list)
escape-sequence-list:
      single-escape-sequence
      escape-sequence escape-list med enkel escape-sequence
,
single-escape-sequence:
      long-unicode-escape-sequence
      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 hex-digit
short-unicode-escape-sequence:
      hex-digit hex-digit hex-digit hex-digit
control-character-escape-sequence:
      kontrolltecken
control-character:

      cr
      lf
      tab
escape-escape:
      #

Literaler

En literal är en källkodsrepresentation av ett värde.

Bokstavlig:
      logisk-literal
      talliteral
      textliteral
      null-literal
      verbatim-literal

Null-literaler

Null-literalen används för att skriva null-värdet. null-värdet representerar ett värde som saknas.

null-literal:
      null

Logiska literaler

En logisk literal används för att skriva värdena true och false och genererar ett logiskt värde.

logical-literal:
      true
      false

Numeriska literaler

En numerisk literal används för att skriva ett numeriskt värde och ger ett talvärde.

number-literal:
      decimal-number-literal
      hexadecimal-number-literal
decimal-number-literal:
      decimal-digits
.decimal-digits exponent-partopt
      .decimal-digits exponent-partopt
      decimal-digits exponent-partopt
decimalsiffror:
      decimal-digit decimal-digitsopt
decimaltal:
en av
      0 1 2 3 4 5 6 7 8 9
exponent-part:
      esignopt decimal-digits
      Esignopt decimal-digits
sign:
one of
      + -
hexadecimal-number-literal:
      0xhex-digits
      0Xhex-digits
hex-siffror:
      hex-digit hex-digitsopt
hex-digit:
en av
      0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f

Ett tal kan anges i hexadecimalt format genom att du före hex-digits skriver tecknen 0x. Till exempel:

0xff // 255

Observera att om ett decimaltecken ingår i en nummerliteral måste det finnas minst en siffra efter det. 1.3 är till exempel en nummerlitteral men inte 1. och 1.e3.

Textliteraler

En textliteral används för att skriva en sekvens med Unicode-tecken och genererar ett textvärde.

text-literal:
      "text-literal-charactersopt"
textliterala tecken:
      text-literal-character text-literal-charactersopt
text-literal-character:
      single-text-character
      character-escape-sequence
      double-quote-escape-sequence
single-text-character:

      Valfritt tecken utom " (U+0022) eller # (U+0023) följt av ( (U+0028)
double-quote-escape-sequence:
      "" (U+0022, U+0022)

Om du vill inkludera citattecken i ett textvärde upprepas citattecknet enligt följande:

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

Produktionen character-escape-sequence kan användas för att skriva tecken i textvärden utan att behöva koda dem direkt som Unicode-tecken i dokumentet. Till exempel kan en vagnretur och radmatning skrivas i ett textvärde som:

"Hello world#(cr,lf)"

Ordagranna literaler

En ordagrann literal används för att lagra en sekvens med Unicode-tecken som har angetts av en användare som kod, men som inte kan parsas korrekt som kod. Vid körning genererar den ett felvärde.

verbatim-literal:
      #!"text-literal-charactersopt"

Identifierare

En identifierare är ett namn som används för att referera till ett värde. Identifierare kan antingen vara reguljära identifierare eller citerade identifierare.

identifierare:
      regular-identifier
      quoted-identifier
regular-identifier:
      available-identifier
      available-identifier dot-character regular-identifier
available-identifier:

      Ett nyckelord eller en identifierare som inte är ett nyckelord
keyword-or-identifier:
      identifier-start-character identifier-part-charactersopt
identifier-start-character:
      bokstavstecken
      understreck
identifier-part-characters:
      identifier-part-character identifier-part-charactersopt
identifier-part-character:
      bokstavstecken
      decimal-digit-character
      understreck
      ansluta-tecken
      kombinera tecken
      formateringstecken
punkttecken:

      . (U+002E)
underscore-character:
      _ (U+005F)
letter-character:
      Ett Unicode-tecken i klasserna Lu, Ll, Lt, Lm, Lo eller Nl
combining-character:
      Ett Unicode-tecken i klasserna Mn eller Mc
decimal-digit-character:
      Ett Unicode-tecken i klassen Nd
connecting-character:
      Ett Unicode-tecken i klassen Pc
formatting-character:
      Ett Unicode-tecken i klassen Cf

En quoted-identifier kan användas för att tillåta att en sekvens med noll eller flera Unicode-tecken används som en identifierare, inklusive nyckelord, blanksteg, kommentarer, operatorer och skiljetecken.

quoted-identifier:
      #"text-literal-charactersopt"

Observera att escape-sekvenser och dubbla citattecken för escape-citat kan användas i en identifierare med citat tecken, precis som i entext-literal.

I följande exempel används identifierare med citat för namn som innehåller ett blankstegstecken:

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

I följande exempel används identifierare med citat för att inkludera operatorn + i en identifierare:

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

Generaliserade identifierare

Det finns två platser i M där inga tvetydigheter introduceras av identifierare som innehåller blanksteg eller som annars är nyckelord eller nummerliteraler. De här platserna är namnen på postfälten i en postliteral och i en fältåtkomstoperator ([ ]). Där tillåter M sådana identifierare utan att behöva använda identifierare med citattecken.

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

De identifierare som används för namn- och åtkomstfält kallas generaliserade identifierare och definieras enligt följande:

generalized-identifier:
      generalized-identifier-part
      generaliserad identifierare
avgränsad endast med blanksteg (U+0020)
generalized-identifier-part
generalized-identifier-part:
      generalized-identifier-segment
      decimal-digit-character generalized-identifier-segment
generalized-identifier-segment:
      keyword-or-identifier
      keyword-or-identifier dot-character keyword-or-identifier

Nyckelord

Ett nyckelord är en identifierarliknande teckensekvens som är reserverad, och kan inte användas som en identifierare förutom när du använder mekanismen för citerade identifierare eller där en generaliserad identifierare tillåts.

keyword: något av
       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

Operatorer och skiljetecken

Det finns flera typer av operatorer och skiljetecken. Operatorer används i uttryck för att beskriva åtgärder som involverar en eller flera operander. Uttrycket a + b använder till exempel operatorn + för att lägga till de två operanderna a och b. Skiljetecken används för gruppering och avgränsning.

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