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:
Dokumentet avkodas enligt dess teckenkodningsschema till en sekvens med Unicode-tecken.
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.
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:
if
if-condition then
true-expressionelse
false-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:
optional
opt field-name =
field-type
är en förkortning av:
fältspecifikation:
field-name =
field-type
optional
fä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:
e
signopt decimal-digits
E
signopt decimal-digits
sign: en av
+ -
hexadecimal-number-literal:
0x
hex-siffror
0X
hex-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
, ; = < <= > >= <> + - * / & ( ) [ ] { } @ ! ? ?? => .. ...