文件
M文档是 Unicode 字符的有序序列。M 允许在 M 文档的不同部分使用不同类别的 Unicode 字符。有关 Unicode 字符类的信息,请参阅The Unicode Standard, Version 3.0 , section 4.5。
一个文档要么由一个表达式组成,要么由组织成部分的定义组组成。第 10 章详细介绍了各个部分。 从概念上讲,以下步骤用于从文档中读取表达式:
- 文档根据其字符编码方案被解码为一系列 Unicode 字符。
- 执行词法分析,从而将 Unicode 字符流转换为标记流。本节的其余小节涵盖词法分析。
- 执行句法分析,从而将标记流转换为可评估的形式。此过程将在后续部分中介绍。
语法约定
词汇和句法文法使用文法产生式表示。每个文法产生式都定义了一个非终结符以及该非终结符可能的扩展为非终结符或终结符序列。在语法产生式中,_non-terminal 符号以斜体显示,终结符以等宽字体显示。
语法产生式的第一行是被定义的非终结符的名称,后跟一个冒号。每个连续的缩进行都包含作为非终结符或终结符序列给出的非终结符的可能扩展。以生产为例:
if-expression:
if
if-condition then
true-expression else
false-expression
定义一个if 表达式,由 token if
、if 条件、token then
、true-expression、tokenelse
和false-expression 组成。
当非终结符有多个可能的扩展时,替代项将在单独的行中列出。以生产为例:
变量列表:
变量
变量列表 ,
变量
定义了一个变量列表要么由一个的变量或者由的变量列表,接着通过一个变量。换句话说,定义是递归的,并指定一个变量列表由一个或多个变量组成,以逗号分隔。
下标后缀“ opt ”用于指示可选符号。生产:
字段规范:
optional
选择字段名称 =
字段类型
是简写:
字段说明:
字段名称 =
字段类型
optional
字段名称 =
字段类型
并定义了一个字段规范,可选择以终结符开头,optional
后跟字段名、终结符=
和字段类型。
替代方案通常在单独的行中列出,但在有许多替代方案的情况下,短语“之一”可能位于单行给出的扩展列表之前。这只是在单独的行中列出每个替代方案的简写。以生产为例:
十进制数字: 其中之一
0 1 2 3 4 5 6 7 8 9
是简写:
十进制数字:
0
1
2
3
4
5
6
7
8
9
词法分析
的词法单元生产定义的M文档词法文法。每个有效的 M 文档都符合这个语法。
词法单元: 词法元素可选 词法元素: 词法元素 词法元素 词法元素 词法元素: 空白 标记注释
在词法层面,一个 M 文档由whitespace、comment和token元素组成。以下各节将介绍这些作品中的每一个。在句法语法中只有标记元素是重要的。
空白
空格用于分隔 M 文档中的注释和标记。空白包括空格字符(它是 Unicode 类 Zs 的一部分),以及水平和垂直制表符、换页符和换行符序列。换行符序列包括回车、换行、回车后跟换行、下一行和段落分隔符。
空白:
使用Unicode类Zs的任何字符
水平制表符(U 0009
)
垂直制表符(U 000B
)
进纸字符(U 000C
)
回车符(U 000D
后跟换行符() U 000A
)
新行字符
新行字符:
回车符(U 000D
)
换行符 ( U 000A
)
下一行字符 ( U 0085
)
行分隔符 ( U 2028
)
段落分隔符 ( U 2029
)
为了与添加文件结束标记的源代码编辑工具兼容,并使文档能够被视为一系列正确终止的行,以下转换按顺序应用于 M 文档:
- 如果文档的最后一个字符是 Control-Z 字符 (
U 001A
),则删除该字符。 - 甲回车符(
U 000D
)被添加到文档的如果该文档是非空的端,并且如果该文件的最后一个字符不是回车(U 000D
),换行(U 000A
),线路分离器(U 2028
),或段落分隔符 (U 2029
)。
评论
支持两种形式的注释:单行注释和分隔注释。单行注释从字符开始,一直//
延伸到源代码行的末尾。定界注释以字符开头,以字符/*
结尾*/
。
分隔的注释可能跨越多行。
注释:
单行注释
分隔注释
单行注释:
//
单行注释字符选择
单行注释字符:
单行注释字符单行注释字符选择
单行-comment-character:
除换行符
以外的任何 Unicode 字符 delimited-comment:
/*
delimited-comment-text opt asterisks /
delimited-comment-text:
delimited-comment-section delimited-comment-text opt
delimited-comment-section:
/
asterisks选择 非斜线或星
号星号:
*
星号选择
非斜线或星号:
任何 Unicode 字符,除了*
或/
评论不嵌套。字符序列/*
,并*/
有一个单行注释中没有任何特殊含义,字符序列//
,并/*
有一个分隔符的注释中没有任何特殊含义。
文本文字中不处理注释。这个例子
复制
代码语言:javascript复制/* Hello, world
*/
"Hello, world"
包括一个带分隔符的注释。
这个例子
复制
代码语言:javascript复制// Hello, world
//
"Hello, world" // This is an example of a text literal
显示几个单行注释。
代币
甲令牌是一个标识符,关键字,文字,操作员或标点。空格和注释用于分隔标记,但不被视为标记。
标记: 标识符 关键字 文字 操作符或标点符号
字符转义序列
M 文本值可以包含任意 Unicode 字符。但是,文本文字仅限于图形字符,并且需要对非图形字符使用转义序列。例如,为了包括回车,换行,或制表符在文本文字,则#(cr)
,#(lf)
和#(tab)
转义序列可分别使用。要将转义序列开始字符嵌入#(
文本文字中,#
需要对其本身进行转义:
复制
代码语言:javascript复制#(#)(
转义序列还可以包含短(四个十六进制数字)或长(八个十六进制数字)Unicode 代码点值。因此,以下三个转义序列是等效的:
复制
代码语言:javascript复制#(000D) // short Unicode hexadecimal value
#(0000000D) // long Unicode hexadecimal value
#(cr) // compact escape shorthand for carriage return
一个转义序列中可以包含多个转义码,以逗号分隔;因此,以下两个序列是等效的:
复制
代码语言:javascript复制#(cr,lf)
#(cr)#(lf)
下面介绍M文档中字符转义的标准机制。
字符转义序列:
#(
转义序列列表 )
转义序列列表:
单转义序列
单转义序列 ,
转义序列列表
单转义序列:
长Unicode转义序列
短Unicode转义-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
short-unicode-escape-序列:
十六进制数字十六进制数字十六进制数字十六进制数字
控制字符转义序列:
控制字符
控制字符:
cr
lf
tab
转义转义:
#
文字
甲文字是一个值的一个源代码表示。
文字: 逻辑文字 数字文字 文字文字 空文字 逐字文字
空字面量
空文字用于写入null
值。该null
值表示缺失值。
空字面量:
null
逻辑文字
逻辑字面用于写入的值true
和false
,并产生一个逻辑值。
逻辑文字:
true
false
数字文字
数字文字用于写入数字值并生成数字值。
数字面:
十进制数,文字
的十六进制数,文字
的十进制数字面:
小数位数 .
小数位数指数部分选择
.
小数位数指数部分选择
小数位数指数部分选择
小数位数:
10进制位十进制位数选择
小数位数: 一个
0 1 2 3 4 5 6 7 8 9
指数部分:
e
标志选择 小数位数
E
签选择 小数位数
的标志:一
-
:十六进制数,文字
0x
的十六进制数字
0X
十六进制数字
十六进制数字:
十六进制数字的六角形数字选择
十六进制数字: 其中之一
0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f
可以通过在十六进制数字前面加上字符以十六进制格式指定数字0x
。例如:
复制
代码语言:javascript复制0xff // 255
请注意,如果数字文字中包含小数点,则其后必须至少有一位数字。例如,1.3
为数字文字,但1.
并1.e3
没有。
文字文字
文本文字用于编写 Unicode 字符序列并生成文本值。
text-literal:
"
text-literal-characters opt "
text-literal-characters:
text-literal-character text-literal-characters opt
text-literal-character:
单文本字符
字符转义序列
双引号转义序列
单文本字符:
除"
( U 0022
) 或#
( U 0023
) 后跟(
( U 0028
)
双引号转义序列:
""
( U 0022
, U 0022
)之外的任何字符
要在文本值中包含引号,请重复引号,如下所示:
复制
代码语言:javascript复制"The ""quoted"" text" // The "quoted" text
的字符转义序列生产可用于在文本值写入字符,而不必直接编码它们作为文档中的Unicode字符。例如,一个回车和换行可以写成一个文本值:
复制
代码语言:javascript复制"Hello world#(cr,lf)"
逐字文字
逐字文字用于存储用户作为代码输入但无法正确解析为代码的 Unicode 字符序列。在运行时,它会产生一个错误值。
逐字文字:
#!"
文本文字字符选择 "
身份标识
一个标识符是用于指一个值的名称。标识符可以是常规标识符或带引号的标识符。
标识符:
常规标识符
引号的标识符
常规标识符:
可供标识
可供识别点阵字符正标识符
可用标识符:
一个关键字或标识符这不是一个关键字
关键字或标识符:
标识符开始字符标识符部分字符选择
标识符开始字符:
字母字符
下划线字符
标识符部分字符:
标识符部分字符标识符部分字符选择
标识符部分字符:
字母字符
十进制数字符
下划线字符
连接字符
组合字符
格式字符
点阵字符:
.
(U 002E
)
下划线字符:
_
(U 005F
)
函字符:
类路中,L1,LT,LM,罗,或NL Unicode字符
组合字符:
Mn 或 Mc 类的 Unicode 字符
十进制数字字符:
Nd 类的 Unicode 字符
连接字符:
Pc 类的 Unicode 字符
格式字符:
Cf 类的 Unicode 字符
带引号的标识符可用于允许将任何零个或多个 Unicode 字符序列用作标识符,包括关键字、空格、注释、运算符和标点符号。
引用标识符:
#"
文本文字字符选择 "
请注意,转义序列和用于转义引号的双引号可以用在带引号的 identifier 中,就像在text-literal 中一样。
以下示例对包含空格字符的名称使用标识符引用:
复制
代码语言:javascript复制[
#"1998 Sales" = 1000,
#"1999 Sales" = 1100,
#"Total Sales" = #"1998 Sales" #"1999 Sales"
]
以下示例使用标识符引用将
运算符包含在标识符中:
复制
代码语言:javascript复制[
#"A B" = A B,
A = 1,
B = 2
]
通用标识符
M 中有两个地方没有由包含空格或其他关键字或数字文字的标识符引入歧义。这些地方是记录文字和字段访问运算符 ( [ ]
) 中的记录字段的名称,M 允许使用此类标识符,而不必使用带引号的标识符。
复制
代码语言:javascript复制[
Data = [ Base Line = 100, Rate = 1.8 ],
Progression = Data[Base Line] * Data[Rate]
]
用于命名和访问字段的标识符称为通用标识符,定义如下:
通用标识符:
通用标识符部分
通用标识符仅由空格分隔 ( U 0020
)
通用标识符部分
通用标识符部分:
通用标识符段
十进制数字字符通用标识符段
通用标识符段:
关键字或标识符
关键字或标识符 点字符 关键字或标识符
关键词
甲关键字是一个标识符样的保留的字符的序列,并且不能被用作标识符使用时除外标识符引用机制或其中广义标识符被允许。
关键词:其中之一
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
运算符和标点符号
有几种运算符和标点符号。运算符在表达式中用于描述涉及一个或多个操作数的操作。例如,表达式a b
使用
运算符将两个操作数a
和相加b
。标点符号用于分组和分隔。
运算符或标点符号: 其中之一
, ; = < <= > >= <> - * / & ( ) [ ] { } @ ! ? ?? => .. ...