Dela via


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 Standard, version 3.0, avsnitt 4.5.

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

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

  2. Lexikal analys utförs, vilket omvandlar dataströmmen med Unicode-tecken till en ström av token. De återstående underavsnitten i det här avsnittet omfattar lexikal analys.

  3. Syntaktisk analys utförs och omvandlar därmed strömmen av token till ett formulär som kan utvärderas. Den här processen beskrivs i efterföljande avsnitt.

Grammatiska konventioner

De lexikala och syntaktiska grammatikerna presenteras med hjälp av grammatikproduktioner. Varje grammatikproduktion definierar en icke-terminalsymbol och möjliga expansioner av den icke-terminala symbolen till sekvenser av icke-terminal- eller terminalsymboler. I grammatikproduktioner visas icke-terminal+ symboler i 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 indragad linje innehåller en möjlig utökning av den icke-terminala som ges som en sekvens av icke-terminal- eller terminalsymboler. Till exempel produktionen:

if-expression:
      ifif-condition then true-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 falskt uttryck.

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 variabellista som antingen består av en variabel eller består av en variabellista följt av en variabel. 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:

fältspecifikation:
      optionalopt field-name = field-type

är en förkortning av:

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

och definierar en fältspecifikation för att eventuellt börja med terminalsymbolen optional följt av ett fältnamn, terminalsymbolen =och en fälttyp.

Alternativ anges normalt på separata rader, men i fall där det finns många alternativ kan frasen "en av" föregå en lista över expansioner som ges på en enda rad. Det här är bara en förkortning för att visa var och en av alternativen på en separat rad. Till exempel produktionen:

decimaltal: en av
      0 1 2 3 4 5 6 7 8 9

är en förkortning av:

decimaltal:
      0
      1
      2
      3
      4
      5
      6
      7
      8
      9

Lexikal analys

Produktionen av lexikala enheter definierar lexikal grammatik för ett M-dokument. Varje giltigt M-dokument överensstämmer med den här grammatiken.

lexical-unit:
      lexical-elementsopt
lexikala element:
      lexical-element
      lexical-element
      lexikala element
lexical-element:
      tomt utrymme
      tokenkomment

På lexikal nivå består ett M-dokument av en ström av blankstegs-, kommentars- och tokenelement . Var och en av dessa produktioner beskrivs i följande avsnitt. Endast tokenelement är betydande i den syntaktiska grammatiken.

Tomt utrymme

Blanksteg används för att avgränsa kommentarer och token i ett M-dokument. Blanksteg innehåller blankstegstecknet (som är en del av Unicode-klass Zs), samt vågrät och lodrät flik, formulärfeed och nya teckensekvenser. Nya teckensekvenser inkluderar vagnretur, radmatning, vagnretur följt av radmatning, nästa rad och styckeavgränsningstecken.

tomt utrymme:
      Alla tecken med Unicode-klass Zs
      Vågrätt fliktecken (U+0009)
      Lodrätt fliktecken (U+000B)
      Formulärflödestecken (U+000C)
      Vagnreturtecken (U+000D) följt av radmatningstecken (U+000A)
      new-line-character
new-line-character:
      Vagnreturtecken (U+000D)
      Radmatningstecken (U+000A)
      Nästa radtecken (U+0085)
      Radavgränsartecken (U+2028)
      Styckeavgränsartecken (U+2029)

För kompatibilitet med källkodsredigeringsverktyg som lägger till markörer i slutet av filen och för att göra det möjligt att visa ett dokument som en sekvens med korrekt avslutade rader, tillämpas följande transformeringar i ordning på ett M-dokument:

  • Om dokumentets sista tecken är ett Control-Z-tecken (U+001A) tas det här tecknet bort.

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

Kommentarer

Två typer av kommentarer stöds: kommentarer med en rad och avgränsade kommentarer. Enradskommentarer 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:
      single-line-comment
      avgränsad kommentar
single-line-comment:

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

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

      /*avgränsad-kommentar-textopt asterisks /
avgränsad kommentarstext:
      avgränsad-kommentar-avsnitt avgränsad-kommentar-textopt
avgränsad-kommentar-avsnitt:

      /
      asteriskerväljer not-slash-or-asterisk
Asterisker:

      *asterisksopt
not-slash-or-asterisk:

      Unicode-tecken utom * eller /

Kommentarer 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 i 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 enradskommentarer.

Token

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

bevis:
      identifierare
      nyckelord
      ordagrann
      operator-or-punctuator

Escape-sekvenser för tecken

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 vagnreturtecken, radmatningstecken eller tabbtecken i en textliteral #(cr)kan sekvenserna , #(lf)och #(tab) escape användas. Om du vill bädda in escapesequence-starttecken #( i en textliteral måste själva vara undantagen # :

#(#)(

Escape-sekvenser kan också innehålla korta (fyra hexsiffror) eller långa (åtta hexsiffror) Unicode-kodpunktsvä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 ingå i en enda escape-sekvens, avgränsade med kommatecken. följande två sekvenser är alltså likvärdiga:

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

Följande beskriver standardmekanismen för teckenundansteg i ett M-dokument.

character-escape-sequence:
      #( escape-sequence-list )
escape-sequence-list:
      single-escape-sequence
      single-escape-sequence
, escape-sequence-list
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.

ordagrann:
      logisk-literal
      number-literal
      textliteral
      null-literal
      verbatim-literal

Null-literaler

Null-literalen används för att skriva null värdet. Värdet null representerar ett frånvarande värde.

null-literal:
      null

Logiska literaler

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

logisk-literal:
      true
      false

Numeriska literaler

En talliteral används för att skriva ett numeriskt värde och genererar ett talvärde.

number-literal:
      decimal-tal-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:
en av
      + -
hexadecimal-number-literal:
      0xhex-siffror
      0Xhex-siffror
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 föregå hex-siffrorna med tecknen 0x. Till exempel:

0xff // 255

Observera att om en decimalpunkt ingår i en talliteral måste den ha minst en siffra som följer den. Till exempel 1.3 är en talliteral men 1. och 1.e3 är inte det.

Textliteraler

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

textliteral:
      " text-literal-charactersopt "
text-literal-characters:
      text-literal-character text-literal-charactersopt
text-literal-character:
      single-text-character
      character-escape-sequence
      double-quote-escape-sequence
single-text-character:

      Alla 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 på följande sätt:

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

Produktionen av tecken-escape-sekvens 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 det 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 vanliga 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
      understreckstecken
identifier-part-characters:
      opt identifier-part-character identifier-part-characters
identifier-part-character:
      bokstavstecken
      decimal-digit-character
      understreckstecken
      ansluta-tecken
      kombinera tecken
      formateringstecken
dot-character:

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

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

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

Observera att escape-sekvenser och dubbla citattecken för att undkomma citattecken kan användas i en citerad identifierare, precis som i en textliteral.

I följande exempel används identifierare som citerar 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 som citerar 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 tomma värden eller som på annat sätt är nyckelord eller talliteraler. Dessa platser är namnen på postfält i en postliteral och i en fältåtkomstoperator ([ ]) Där tillåter M sådana identifierare utan att behöva använda citerade identifierare.

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

Identifierarna som används för namn- och åtkomstfält kallas generaliserade identifierare och definieras på följande sätt:

generalized-identifier:
      generalized-identifier-part
      generalized-identifier
avgränsad endast med tomma (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 ID-liknande sekvens med tecken som är reserverad och kan inte användas som identifierare förutom när du använder mekanismen identifier-quoting eller där en generaliserad identifierare tillåts.

nyckelord: en 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 är till för att gruppera och separera.

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