Udostępnij za pośrednictwem


Struktura leksykalna

Dokumenty

Dokument W języku M to uporządkowana sekwencja znaków Unicode. Język M umożliwia różne klasy znaków Unicode w różnych częściach dokumentu W języku M. Aby uzyskać informacje na temat klas znaków Unicode, zobacz Unicode Standard, Wersja 3.0, sekcja 4.5.

Dokument składa się z dokładnie jednego wyrażenia lub grup definicji zorganizowanych w sekcje. Sekcje zostały szczegółowo opisane w rozdziale 10. Mówiąc koncepcyjnie, następujące kroki służą do odczytywania wyrażenia z dokumentu:

  1. Dokument jest dekodowany zgodnie ze schematem kodowania znaków w sekwencji znaków Unicode.

  2. Wykonywana jest analiza leksykalna, co przekłada strumień znaków Unicode na strumień tokenów. Pozostałe podsekcje tej sekcji obejmują analizę leksykaną.

  3. Przeprowadzana jest analiza składniowa, a tym samym tłumaczenie strumienia tokenów na formularz, który można ocenić. Ten proces został omówiony w kolejnych sekcjach.

Konwencje dotyczące gramatyki

Gramatyki leksykalne i składniowe są prezentowane przy użyciu produkcji gramatycznych. Każda produkcja gramatyki definiuje symbol nie terminalowy i możliwe rozszerzenia tego nieterminalnego symbolu w sekwencje symboli nie terminalowych lub terminalowych. W produkcjach gramatycznych symbole inne niż terminal+ są wyświetlane w typie kursywy, a symbole terminalu są wyświetlane w czcionki o stałej szerokości.

Pierwszy wiersz produkcji gramatyki jest nazwą zdefiniowanego symbolu niekońcowego, po którym następuje dwukropek. Każdy kolejny wcięcie zawiera możliwe rozszerzenie nieterminalne podane jako sekwencja symboli nie terminalowych lub terminalowych. Na przykład produkcja:

wyrażenie-if:
      ifif-condition then wyrażenie-trueelsewyrażenie-fałsz

Definiuje wyrażenie-if, które ma składać się z tokenu if, a następnie warunek-if, a następnie token then, a następnie wyrażenie-true, a następnie token else, a następnie wyrażenie-false.

Jeśli istnieje więcej niż jedno możliwe rozszerzenie symbolu niekońcowego, alternatywy są wyświetlane w oddzielnych wierszach. Na przykład produkcja:

lista zmiennych:
      zmienna
      zmienna-lista
, zmiennych

definiuje listę zmiennych, która składa się ze zmiennej lub składa się z listy zmiennych, po której następuje zmienna. Innymi słowy, definicja jest rekursywna i określa, że lista zmiennych składa się z co najmniej jednej zmiennej rozdzielone przecinkami.

Sufiks w indeksie dolnym "opt" służy do wskazywania opcjonalnego symbolu. Produkcja:

specyfikacja pola:
      optionalopt field-name = field-type(typ pola)

to skrócona forma produkcji:

specyfikacja pola:
      nazwa-pola typ-pola
=
      optionalnazwa-pola = typ-pola

i definiuje specyfikację pola, aby opcjonalnie rozpocząć od symbolu optional terminalu, po którym następuje nazwa-pola, symbol =terminalu i typ pola.

Alternatywy są zwykle wyświetlane w oddzielnych wierszach, choć w przypadkach, gdy istnieje wiele alternatyw, wyrażenie "jeden z" może poprzedzać listę rozszerzeń podanych w jednym wierszu. Jest to po prostu skrót do wyświetlania każdej alternatywy w osobnym wierszu. Na przykład produkcja:

cyfra-dziesiętna: jedna z
      0 1 2 3 4 5 6 7 8 9

to skrócona forma produkcji:

cyfra-dziesiętna:
      0
      1
      2
      3
      4
      5
      6
      7
      8
      9

Analiza leksykalna

Produkcja leksykalno-jednostkowa definiuje gramatykę leksykatyczną dokumentu M. Każdy prawidłowy dokument języka M jest zgodny z tą gramatyką.

leksykalna jednostka:
      optykały-elementyleksykalne
elementy leksykalne:
      element-leksykalny
      element-leksykalny
      elementy leksykalne
element-leksykalny:
      znak odstępu
      komentarz tokenu

Na poziomie leksykalnym dokument języka M składa się ze strumienia białych znaków, komentarzy i elementów tokenu . Każda z tych produkcji została omówiona w poniższych sekcjach. Tylko elementy tokenu są istotne w gramatyce składniowej.

Znak odstępu

Białe znaki służą do oddzielania komentarzy i tokenów w dokumencie języka M. Odstęp zawiera znak spacji (który jest częścią klasy Unicode Zs), a także poziomą i pionową kartę, kanał informacyjny formularza i sekwencje znaków nowego wiersza. Sekwencje znaków nowego wiersza obejmują znak powrotu karetki, kanału informacyjnego, powrotu karetki, a następnie znaki separatora wiersza, następnego wiersza i separatora akapitu.

biały znak:
      Dowolny znak z klasą Unicode Zs
      Znak karty poziomej (U+0009)
      Znak karty pionowej (U+000B)
      Znak kanału informacyjnego formularza (U+000C)
      Znak powrotu karetki (U+000D), po którym następuje znak przesuwu wiersza (U+000A)
      nowy znak wiersza
znak nowego wiersza:
      Znak powrotu karetki (U+000D)
      Znak kanału informacyjnego wiersza (U+000A)
      Znak następnego wiersza (U+0085)
      Znak separatora linii (U+2028)
      Znak separatora akapitu (U+2029)

Aby zapewnić zgodność z narzędziami do edycji kodu źródłowego, które dodają znaczniki końca pliku i umożliwiają wyświetlanie dokumentu jako sekwencji poprawnie zakończonych wierszy, następujące przekształcenia są stosowane w celu wyświetlenia dokumentu W języku M:

  • Jeśli ostatnim znakiem dokumentu jest znak Control-Z (U+001A), ten znak zostanie usunięty.

  • Znak powrotu karetki (U+000D) jest dodawany na końcu dokumentu, jeśli dokument jest niepusty, a ostatni znak dokumentu nie jest znakiem powrotu karetki (), przesuwu wiersza (U+000AU+000D), separatorem wiersza (U+2028) lub separatorem akapitu (U+2029).

Komentarze

Obsługiwane są dwie formy komentarzy: komentarze jednowierszowe i komentarze rozdzielane. Komentarze jednowierszowe zaczynają się od znaków // i rozszerzają się na koniec wiersza źródłowego. Komentarze rozdzielone zaczynają się od znaków /* i kończą się znakami */.

Komentarze rozdzielone mogą obejmować wiele wierszy.

komentarz:
      komentarz jednowierszowy
      komentarz rozdzielany
komentarz jednowierszowy:

      //jednowierszowy znak komentarza
znaki komentarza jednowierszowego:
      jednowierszowy znak komentarza jednowierszowego z jednym wierszem i znakamikomentarza
jednowierszowy znak komentarza:

      Dowolny znak Unicode z wyjątkiem nowego znaku wiersza
komentarz rozdzielany:

      /*ogranicznik-komentarz-tekstopt a gwiazdki /
rozdzielany tekst komentarza:
      rozdzielany-komentarz-sekcja rozdzielana-komentarz-tekstoptimited-comment-section
:

      /
      gwiazdkiopt not-slash-or-asterisk
Gwiazdki:

      *gwiazdkiopt
not-slash-or-asterisk:

      Dowolny znak Unicode z wyjątkiem * lub /

Komentarze nie są zagnieżdżone. Sekwencje znaków /* i */ nie mają specjalnego znaczenia w komentarzu jednowierszowym, a sekwencje znaków // i /* nie mają specjalnego znaczenia w komentarzu z ogranicznikami.

Komentarze nie są przetwarzane w literałach tekstowych. Przykład

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

zawiera rozdzielany komentarz.

Przykład

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

pokazuje kilka komentarzy jednowierszowych.

Tokeny

Token to identyfikator, słowo kluczowe, literał, operator lub znak interpunkcyjny. Białe znaki i komentarze są używane do oddzielania tokenów, ale nie są traktowane jako tokeny.

żeton:
      identifier
      słowo kluczowe
      literal
      operator-or-interpunkcyjny

Sekwencje ucieczki znaków

Wartości tekstowe języka M mogą zawierać dowolne znaki Unicode. Literały tekstowe są jednak ograniczone do znaków graficznych i wymagają użycia sekwencji ucieczki dla znaków niegraficznych. Na przykład, aby uwzględnić znak powrotu karetki, kanału wiersza lub tabulatora w literałie tekstowym, #(cr)można użyć odpowiednio sekwencji ucieczki , #(lf)i #(tab) , . Aby osadzić znaki #( początkowe escapesequence w literału tekstowym, # należy samodzielnie osadzić znaki ucieczki:

#(#)(

Sekwencje ucieczki mogą również zawierać krótkie (cztery cyfry szesnastkowy) lub długie (osiem cyfr szesnastkowy) wartości punktów kodu Unicode. W związku z tym następujące trzy sekwencje ucieczki są równoważne:

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

Wiele kodów ucieczki może być uwzględnionych w jednej sekwencji ucieczki rozdzielone przecinkami; Następujące dwie sekwencje są zatem równoważne:

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

Poniżej opisano standardowy mechanizm ucieczki znaków w dokumencie języka M.

znak-ucieczka-sekwencja:
      #( escape-sequence-list )
escape-sequence-list:
      pojedyncza sekwencja ucieczki
      lista ucieczki z sekwencji ucieczki z jedną sekwencją
,
pojedyncza sekwencja ucieczki:
      long-unicode-escape-sequence
      short-unicode-escape-sequence
      control-character-escape-sequence
      ucieczka ucieczki
long-unicode-escape-sequence:
      szesnastkowy cyfra-szesnastkowy-
short-unicode-escape-sequence:
      cyfra-szesnastkowy-cyfra-szesnastkowy-cyfra-szesnastkowy
control-character-escape-sequence:
      znak kontrolny
znak kontrolny:

      cr
      lf
      tab
ucieczka ucieczki:
      #

Literały

Element literał jest reprezentacją wartości w kodzie źródłowym.

dosłowny:
      literał logiczny
      literał liczbowy
      literał tekstowy
      literał null
      literał dosłowny

Literały o wartości null

Literał o wartości null jest używany do zapisywania null wartości. Wartość null reprezentuje nieobecną wartość.

literał null:
      null

Literały logiczne

Literał logiczny służy do zapisywania wartości true i false tworzenia wartości logicznej.

literał logiczny:
      true
      false

Literały liczbowe

Literał liczbowy służy do pisania wartości liczbowej i generuje wartość liczbową.

literał liczbowy:
      literał-liczba-dziesiętna
      literał-liczby szesnastkowej
Literał-liczby dziesiętnej:
      Cyfry-dziesiętne cyfry-dziesiętne
.wykładniczo-częściowej
      . wyrażenie-cyfr-dziesiętne wykładniczo-częściowe
      wyrażenie-cyfr-dziesiętne wykładniczo-częściowe
cyfry dziesiętne:
      cyfra-dziesiętna-cyfra-dziesiętna— wyrażenie zgody
cyfra-dziesiętna:
jedna z
      0 1 2 3 4 5 6 7 8 9
część wykładnicza:
      eznakopt-digits decimal-digits
      Eznakopt-digits decimal-digits
znak:
jeden z
      + -
literał-liczbowy szesnastkowy:
      0xcyfry szesnastowe
      0Xcyfry szesnastowe
cyfry szesnastkowej:
      szesnastkowy cyfra-cyfra-szesnastkowy
cyfra-szesnastkowy:
jeden z
      0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f

Liczbę można określić w formacie szesnastkowym, poprzedzając cyfry szesnastkowe znakami 0x. Na przykład:

0xff // 255

Należy pamiętać, że jeśli punkt dziesiętny jest uwzględniony w literału liczbowym, musi zawierać co najmniej jedną cyfrę po niej. Na przykład jest literałem liczbowym, 1.3 1.e3 ale 1. nie.

Literały tekstowe

Literał tekstowy służy do pisania sekwencji znaków Unicode i tworzy wartość tekstową.

literał tekstowy:
      " wybór znakówliterałów tekstowych "
znaki tekstowe literału:
      Wyrażenie zgody na zamianę znakówtekstowych literałów tekstowych
znak-literał-tekstu:
      jednotekstowy znak
      znak-ucieczka-sekwencja
      podwójna sekwencja ucieczki cudzysłowu
jednotekstowy znak:

      Dowolny znak z wyjątkiem " () lub # (), po którym ( następuje (U+0023U+0028)U+0022
double-quote-escape-sequence:
      "" (U+0022, U+0022)

Aby uwzględnić cudzysłowy w wartości tekstowej, cudzysłow jest powtarzany w następujący sposób:

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

Środowisko produkcyjne sekwencji ucieczki znaków może służyć do zapisywania znaków w wartościach tekstowych bez konieczności bezpośredniego kodowania ich jako znaków Unicode w dokumencie. Na przykład znak powrotu karetki i kanału informacyjnego można zapisać w wartości tekstowej jako:

"Hello world#(cr,lf)"

Literały dosłowne

Literał dosłowny służy do przechowywania sekwencji znaków Unicode, które zostały wprowadzone przez użytkownika jako kod, ale które nie mogą być poprawnie analizowane jako kod. W czasie wykonywania generuje wartość błędu.

literał dosłowny:
      #!"wybór znakówliterałów tekstowych "

Identyfikatory

Element identyfikator to nazwa używana do odwoływania się do wartości. Identyfikatory mogą być zwykłymi identyfikatorami lub identyfikatorami cytowanych.

identyfikator:
      zwykły identyfikator
      identyfikator cytowany
zwykły identyfikator:
      dostępny identyfikator
      identyfikator-dostępny-kropka-znak zwykły-identyfikator
dostępny identyfikator:

      Słowo kluczowe lub identyfikator , który nie jest słowem kluczowym
słowo kluczowe lub identyfikator:
      identyfikator-start-znak identyfikator-part-znakiopt-opt
identyfikator-start-znak:
      znak litery
      znak podkreślenia
identifier-part-characters:
      identifier-part-character identifier-part-charactersopt
identyfikator— część znaku:
      znak litery
      znak-cyfra-dziesiętna
      znak podkreślenia
      znak połączenia
      łączenie znaku
      znak formatowania
znak kropki:

      . (U+002E)
znak podkreślenia:
      _ (U+005F)
znak litery:
      Znak Unicode klas Lu, Ll, Lt, Lm, Lo lub Nl
znak łączący:
      Znak Unicode klas Mn lub Mc
znak-cyfra-dziesiętna:
      Znak Unicode klasy Nd
znak połączenia:
      Znak Unicode klasy Pc
znak formatowania:
      Znak Unicode klasy Cf

Identyfikator cudzysłów może służyć do zezwalania na używanie dowolnej sekwencji znaków Unicode zero lub więcej jako identyfikatora, w tym słów kluczowych, białych znaków, komentarzy, operatorów i znaków interpunkcyjnych.

identyfikator cytowany:
      #" wybór znakówliterałów tekstowych "

Należy pamiętać, że sekwencje ucieczki i cudzysłowy do cudzysłowów ucieczki mogą być używane w cudzysłowie cytowanym, podobnie jak w literału tekstowego.

W poniższym przykładzie użyto identyfikatora cudzysłów dla nazw zawierających znak spacji:

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

W poniższym przykładzie użyto identyfikatora cudzysłów, aby uwzględnić + operator w identyfikatorze:

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

Identyfikatory uogólnione

Istnieją dwa miejsca w języku M, w których nie są wprowadzane niejednoznaczności przez identyfikatory zawierające puste lub które są inaczej słowami kluczowymi lub literałami liczbowymi. Te miejsca to nazwy pól rekordów w literału rekordu i w operatorze dostępu do pól ([ ]) W tym miejscu język M umożliwia takie identyfikatory bez konieczności używania identyfikatorów cytowanych.

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

Identyfikatory używane do nazywania i uzyskiwania dostępu do pól są określane jako identyfikatory uogólnione i zdefiniowane w następujący sposób:

uogólniony-identyfikator:
      uogólniona część identyfikatora
      identyfikator uogólniony
oddzielony tylko wartościami pustymi (U+0020)
uogólniona część identyfikatora
generalized-identifier-part:
      uogólniony segment identyfikatora
      Segment uogólniony-identyfikator-identyfikator-cyfra-dziesiętna
uogólniony segment identyfikatora:
      słowo kluczowe lub identyfikator
      słowo kluczowe lub identyfikator dot-znak słowa kluczowego lub identyfikatora

Słowa kluczowe

Słowo kluczowe to sekwencja znaków, która jest zarezerwowana, i nie może być używana jako identyfikator, z wyjątkiem sytuacji, gdy jest używany mechanizm cudzysłów identyfikatorów lub gdzie dozwolony jest uogólniony identyfikator.

słowo kluczowe: jeden z
       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

Operatory i znaki interpunkcyjne

Istnieje kilka rodzajów operatorów i znaków interpunkcyjnych. Operatory są używane w wyrażeniach do opisywania operacji obejmujących co najmniej jeden operand. Na przykład wyrażenie a + b używa operatora +, aby dodać dwa operandy a i b. Znaki interpunkcyjne służą do grupowania i oddzielania.

operator-or-interpunkcyjny: jeden z
      , ; = < <= > >= <> + - * / & ( ) [ ] { } @ ! ? ?? => .. ...