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:
Dokumentet avkodas enligt dess teckenkodningsschema till en sekvens med Unicode-tecken.
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.
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
, ; = < <= > >= <> + - * / & ( ) [ ] { } @ ! ? ?? => .. ...