Leksikalsk struktur
Dokumenter
Et M-dokument er en sorteret sekvens af Unicode-tegn. M tillader forskellige klasser af Unicode-tegn i forskellige dele af et M-dokument. Du kan få oplysninger om Unicode-tegnklasser i Unicode Standard, version 3.0, afsnit 4.5.
Et dokument består enten af præcis ét udtryk eller af grupper af definitioner , der er organiseret i sektioner. Afsnit beskrives detaljeret i kapitel 10. Grundlæggende bruges følgende trin til at læse et udtryk fra et dokument:
Dokumentet afkodes i henhold til tegnkodningsskemaet i en sekvens af Unicode-tegn.
Der udføres leksikalsk analyse, hvilket oversætter streamen af Unicode-tegn til en strøm af tokens. De resterende underafsnit i dette afsnit dækker leksikalsk analyse.
Syntaktisk analyse udføres og oversætter dermed strømmen af tokens til en formular, der kan evalueres. Denne proces beskrives i efterfølgende afsnit.
Grammatikregler
De leksikalske og syntaktiske grammatikker præsenteres ved hjælp af grammatiske produktioner. Hver grammatikproduktion definerer et ikke-afsluttende symbol og de mulige udvidelser af dette ikke-terminalsymbol til sekvenser af ikke-terminalsymboler eller terminalsymboler. I grammatiske produktioner vises symboler, der ikke er terminalsymboler , med kursiv, og afsluttende symboler vises med en skrifttype med fast bredde.
Den første linje i en grammatisk produktion er navnet på det ikke-afsluttende symbol, der defineres efterfulgt af et kolon. Hver efterfølgende indrykkede linje indeholder en mulig udvidelse af den ikke-terminal, der er angivet som en sekvens af ikke-afsluttende eller afsluttende symboler. Eksempelvis definerer produktionen:
if-expression:
if
if-condition then
true-expressionelse
false-expression
definerer et if-udtryk , der skal bestå af tokenet if
efterfulgt af en if-betingelse efterfulgt af tokenet then
efterfulgt af et true-expression efterfulgt af tokenet else
efterfulgt af et false-expression.
Hvis der er mere end én mulig udvidelse af et ikke-afsluttende symbol, vises alternativerne på separate linjer. Eksempelvis definerer produktionen:
variable-list:
variabel
variabellistevariabel ,
definerer en variabelliste , der enten består af en variabel eller består af en variabelliste efterfulgt af en variabel. Definitionen er med andre ord rekursiv og angiver, at en variabelliste består af en eller flere variabler adskilt af kommaer.
Et sænket suffiks "opt" bruges til at angive et valgfrit symbol. Produktionen:
field-specification:
optional
opt field-name =
field-type
er en forkortelse for:
field-specification:
field-name =
field-type
optional
field-name =
felttype
og definerer en feltspecifikation, der eventuelt skal begynde med terminalsymbolet optional
efterfulgt af et feltnavn, terminalsymbolet =
og en felttype.
Alternativer vises normalt på separate linjer, men i tilfælde, hvor der er mange alternativer, kan udtrykket "en af" være foran en liste over udvidelser, der er angivet på en enkelt linje. Dette er simpelthen en oversigt over hver af alternativerne på en separat linje. Eksempelvis definerer produktionen:
decimal-digit: en af
0 1 2 3 4 5 6 7 8 9
er en forkortelse for:
decimal-digit:
0
1
2
3
4
5
6
7
8
9
Leksikalsk analyse
Produktionen af leksikalske enheder definerer den leksikalske grammatik for et M-dokument. Alle gyldige M-dokumenter er i overensstemmelse med denne grammatik.
lexical-unit:
lexical-elementsopt
lexical-elements:
leksikalsk-element
leksikalsk-element
leksikalske elementer
lexical-element:
blanktegn
tokenkommentar
På leksikalsk niveau består et M-dokument af en strøm af mellemrum, kommentarer og tokenelementer . Hver af disse produktioner beskrives i de følgende afsnit. Kun tokenelementer er vigtige i den syntaktiske grammatik.
Blanktegn
Mellemrum bruges til at adskille kommentarer og tokens i et M-dokument. Mellemrum indeholder mellemrumstegnet (som er en del af Unicode-klasse Z'er) samt vandret og lodret fane, formularfeed og sekvenser af nye tegn. Newline-tegnsekvenser omfatter vognretur, linjeskift, vognretur efterfulgt af linjeskift, næste linje og afsnitsseparatortegn.
blanktegn:
Ethvert tegn med Unicode-klasse Zs
Vandret tabulatortegn (U+0009
)
Lodret tabulatortegn (U+000B
)
Formularfeedtegn (U+000C
)
Vognreturtegn (U+000D
) efterfulgt af linjeskifttegn (U+000A
)
new-line-character
new-line-character:
Vognreturtegn (U+000D
)
Linjeskifttegn (U+000A
)
Næste linjetegn (U+0085
)
Linjeseparatortegn (U+2028
)
Afsnitsseparatortegn (U+2029
)
Af hensyn til kompatibiliteten med værktøjer til redigering af kildekode, der tilføjer mærker for filafslutninger og for at gøre det muligt at se et dokument som en sekvens af korrekt afbrudte linjer, anvendes følgende transformationer i rækkefølge på et M-dokument:
Hvis det sidste tegn i dokumentet er et Control-Z-tegn (
U+001A
), slettes dette tegn.Et vognreturtegn (
U+000D
) tilføjes i slutningen af dokumentet, hvis dokumentet ikke er tomt, og hvis det sidste tegn i dokumentet ikke er en vognretur (U+000D
), et linjeskift (U+000A
), en linjeseparator (U+2028
) eller en afsnitsseparator (U+2029
).
Kommentarer
To former for kommentarer understøttes: kommentarer på én linje og afgrænsede kommentarer. Kommentarer med en enkelt linje starter med tegnene //
og udvides til slutningen af kildelinjen. Afgrænsede kommentarer starter med tegnene /*
og slutter med tegnene */
.
Afgrænsede kommentarer kan strække sig over flere linjer.
kommentar:
enkeltlinjekommentar
afgrænset kommentar
enkeltlinjekommentar:
//
enkelt-line-comment-charactersopt
enkeltlinjekommentartegn:
single-line-comment-character single-line-comment-charactersopt
enkeltlinjekommentartegn:
Alle Unicode-tegn undtagen et nyt linjetegn
afgrænset kommentar:
/*
delimited-comment-textopt asterisks /
delimited-comment-text:
delimited-comment-section delimited-comment-textopt
delimited-comment-section:
/
stjernervælger not-slash-or-asterisk
Stjerner:
*
stjernervælger
not-slash-or-asterisk:
Alle Unicode-tegn undtagen *
eller /
Kommentarer indlejres ikke. Tegnsekvenserne /*
og */
har ingen særlig betydning i en kommentar på en enkelt linje, og tegnsekvenserne //
og /*
har ingen særlig betydning i en separeret kommentar.
Kommentarer behandles ikke i tekstkonstanter. Eksemplet
/* Hello, world
*/
"Hello, world"
indeholder en afgrænset kommentar.
Eksemplet
// Hello, world
//
"Hello, world" // This is an example of a text literal
viser flere kommentarer med en enkelt linje.
Tokens
Et token er et id, et nøgleord, en konstant, en operator eller en tegnsætningstegn. Mellemrum og kommentarer bruges til at adskille tokens, men betragtes ikke som tokens.
tegn:
Identifikator
nøgleord
bogstavelig
operator-or-punctuator
Escape-sekvenser for tegn
M-tekstværdier kan indeholde vilkårlige Unicode-tegn. Tekstkonstanter er dog begrænset til grafiske tegn og kræver brug af escape-sekvenser for ikke-grafiske tegn. Hvis du f.eks. vil medtage et vognretur-, linjeskift- eller tabulatortegn i en tekstkonstant, #(cr)
kan sekvenserne , #(lf)
og #(tab)
escape bruges. Hvis du vil integrere starttegnene #(
for escapesequence i en tekstkonstant, skal selve escape-filen #
være escape-tegn:
#(#)(
Escape-sekvenser kan også indeholde korte (fire hex-cifre) eller lange (otte hex-cifre) Unicode-kodepunktværdier. Følgende tre escape-sekvenser svarer derfor til hinanden:
#(000D) // short Unicode hexadecimal value
#(0000000D) // long Unicode hexadecimal value
#(cr) // compact escape shorthand for carriage return
Flere escape-koder kan inkluderes i en enkelt escape-sekvens adskilt af kommaer. følgende to sekvenser svarer således til hinanden:
#(cr,lf)
#(cr)#(lf)
I det følgende beskrives standardmekanismen for tegns escaping i et 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:
control-character
control-character:
cr
lf
tab
escape-escape:
#
Konstanter
En konstant (literal) er en repræsentation af en værdi i kildekoden.
bogstavelig:
logical-literal
number-literal
tekstkonstant
null-literal
verbatim-literal
Null-konstanter
Null-konstanten bruges til at skrive værdien null
. Værdien null
repræsenterer en fraværende værdi.
null-literal:
null
Logiske konstanter
En logisk konstant bruges til at skrive værdierne true
og false
producerer en logisk værdi.
logical-literal:
true
false
Talkonstanter
En talkonstant bruges til at skrive en numerisk værdi og producerer en talværdi.
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
decimal-digits:
decimal-digit decimal-digitsopt
decimal-digit: en af
0 1 2 3 4 5 6 7 8 9
eksponentdel:
e
signopt decimal-digits
E
signopt decimal-digits
tegn: en af
+ -
hexadecimal-number-literal:
0x
hex-cifre
0X
hex-cifre
hex-cifre:
hex-digit hex-digitsopt
hex-digit: en af
0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f
Et tal kan angives i hexadecimalt format ved at foranstille hexcifrene med tegnene 0x
. Eksempler:
0xff // 255
Bemærk, at hvis et decimaltegn er inkluderet i en talkonstant, skal der være mindst ét ciffer efter det. Er f.eks. en talkonstant, 1.3
men 1.
og 1.e3
er ikke.
Tekstkonstanter
En tekstkonstant bruges til at skrive en sekvens af Unicode-tegn og opretter en tekstværdi.
text-literal:
"
text-literal-charactersopt "
text-literal-characters:
text-literal-character text-literal-charactersopt
text-literal-character:
enkelt-tekst-tegn
character-escape-sequence
double-quote-escape-sequence
enkelt-tekst-tegn:
Alle tegn undtagen "
(U+0022
) eller #
(U+0023
) efterfulgt af (
(U+0028
)
double-quote-escape-sequence:
""
(U+0022
, U+0022
)
Hvis anførselstegn skal medtages i en tekstværdi, gentages anførselstegnet på følgende måde:
"The ""quoted"" text" // The "quoted" text
Produktionen af character-escape-sequence kan bruges til at skrive tegn i tekstværdier uden at skulle kode dem direkte som Unicode-tegn i dokumentet. En vognretur og et linjeskift kan f.eks. skrives i en tekstværdi som:
"Hello world#(cr,lf)"
Verbatim-konstanter
En verbatim-konstant bruges til at gemme en sekvens af Unicode-tegn, der er angivet af en bruger som kode, men som ikke kan fortolkes korrekt som kode. På kørselstidspunktet giver den en fejlværdi.
verbatim-literal:
#!"
text-literal-charactersopt "
Identifiers
En identifikator (identifier) er et navn, der bruges til at referere til en værdi. Id'er kan enten være almindelige identifikatorer eller citerede identifikatorer.
identifikator:
regular-identifier
quoted-identifier
regular-identifier:
available-identifier
available-identifier dot-character regular-identifier
available-identifier:
Et nøgleord eller en identifikator , der ikke er et nøgleord
keyword-or-identifier:
identifier-start-character identifier-part-charactersopt
identifier-start-character:
bogstav-tegn
understregningstegn
identifier-part-characters:
identifier-part-character identifier-part-charactersopt
identifier-part-character:
bogstav-tegn
decimal-digit-character
understregningstegn
connecting-character
kombinationstegn
formateringstegn
priktegn:
.
(U+002E
)
understregningstegn:
_
(U+005F
)
bogstav-tegn:
Et Unicode-tegn i klasserne Lu, Ll, Lt, Lm, Lo eller Nl
kombinationstegn:
Et Unicode-tegn i klasse Mn eller Mc
decimal-digit-character:
Et Unicode-tegn i klasse Nd
connecting-character:
Et Unicode-tegn på klasse-pc'en
formateringstegn:
Et Unicode-tegn i klassen Cf
Et quoted-id kan bruges til at tillade, at en sekvens på nul eller flere Unicode-tegn bruges som en identifikator, herunder nøgleord, mellemrum, kommentarer, operatorer og tegnsætningstegn.
quoted-identifier:
#"
text-literal-charactersopt "
Bemærk, at escape-sekvenser og dobbelte anførselstegn til escape-anførselstegn kan bruges i et citeret id på samme måde som i en tekstkonstant.
I følgende eksempel bruges identifikator anførselstegn for navne, der indeholder et mellemrumstegn:
[
#"1998 Sales" = 1000,
#"1999 Sales" = 1100,
#"Total Sales" = #"1998 Sales" + #"1999 Sales"
]
I følgende eksempel bruges identifikator, der citeres, til at inkludere operatoren +
i en identifikator:
[
#"A + B" = A + B,
A = 1,
B = 2
]
Generaliserede id'er
Der er to steder i M, hvor der ikke introduceres flertydigheder af identifikatorer, der indeholder tomme værdier, eller som ellers er nøgleord eller talkonstanter. Disse steder er navnene på postfelter i en postkonstant, og i en feltadgangsoperator ([ ]
) Der tillader M sådanne identifikatorer uden at skulle bruge identifikatorer i anførselstegn.
[
Data = [ Base Line = 100, Rate = 1.8 ],
Progression = Data[Base Line] * Data[Rate]
]
De identifikatorer, der bruges til at navngive og få adgang til felter, kaldes generelle identifikatorer og defineres på følgende måde:
generalized-identifier:
generalized-identifier-part
generalized-identifier adskilt kun af tomme værdier (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
Nøgleord
Et nøgleord er en identifikatorlignende sekvens af tegn, der er reserveret, og som ikke kan bruges som identifikator, undtagen når der bruges mekanismen til identifikator-quoting, eller hvor en generel identifikator er tilladt.
nøgleord: et af
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 og tegnsætningstegn
Der er flere typer operatorer og tegnsætningstegn. Operatorer bruges i udtryk til at beskrive handlinger, der involverer en eller flere operander. Eksempelvis bruger udtrykket a + b
operatoren +
til at lægge de to operander a
og b
sammen. Tegnsætningstegn er til gruppering og adskillelse.
operator-or-punctuator: en af
, ; = < <= > >= <> + - * / & ( ) [ ] { } @ ! ? ?? => .. ...