当前位置: 首页 > news >正文

【Janet】语法与解析器

一个 Janet 程序的生命周期开始于一个文本文件,像系统上的其他文件一样,就是一个字节序列。Janet 源文件必须是 UTF-8 或 ASCII 编码。程序编译或运行之前,需要将源码转换到一个数据结构。像 Lisp 一样,Janet 源代码是同构的,即代码由 Janet 的核心数据结构表示,因此,语言中用于操作元组、字符串和表(table)的所有功能都可以轻松地用于操作源代码。

Janet 代码转换成数据结构之前,必须先由 Janet 解析器读取解析。解析器在 Lisp 中通常被称为读取器,它将纯文本翻译成可用于编译器和宏的数据结构。在 Janet 中它叫做解析器而不是读取器,是因为读取阶段并不会执行代码。这种方式更安全直接,也让语法高亮,格式化以及语法分析变得更简单。因为解析器不可扩展,Janet 的哲学是通过宏来扩展语言,而不是读取器宏。

nil,true和false

niltruefalse 都是可以在解析器中以其本身形式输入的字面量。

nil
true
false

符号

Janet 符号是一串不以数字或冒号开头的字母数字组成的字符序列。可以包含字符 !@$%^&*-_+=:<>.? 以及 Unicode 字符。

为方便起见,绝大多数符号应该采用全小写以破折号连接的形式(称为 kebab case[烤串格式])。

来自其他模块的符号通常会包含一个正斜杠,它用来将模块名和模块中定义的符号名区分开(就是 Go 语言中的 . 运算符)。

symbol
kebab-case-symbol
snake_case_symbol
my-module/my-function
*****
!%$^*__--__._+++===-crazy-symbol
*global-var*
你好

Keywords

Janet 关键字类似于符号但是以 : 开头。它于符号的用法不同,关键字会被编译器当作常量,而不是名称。关键字常用于表(table)和结构体的键,或者宏的部分语法。

:keyword
:range
:0x0x0x0
:a-keyword
::
:

数字

Janet 数字表示为 IEEE 754 浮点数。语法于大多数语言类似。数字可以以十进制书写,并添加下划线分隔。小数点可以用来表示浮点数。使用进制加 r 前缀可以将数字表示为其他进制。例如16可以写成 161_616r104r1000x100x 前缀因为广泛使用也被支持。进制基数必须以十进制书写,范围是 2 到 36 之间。超过十进制的数用字母表示数字,大小写不敏感。

0
12
-65912
4.98
1.3e18
1.3E18
18r123C
11raaa&a
1_000_000
0xbeef

字符串

Janet 字符串使用双引号包裹。字符串是 8-bit clean 的,可以包含任意字节序列,包括内嵌的0字节。在字符串中插入双引号需要使用反斜杠转义。对于不可打印字符,你可以选择使用几种常见的转义字符,或者使用 \xHH 转义序列来以十六进制形式转义一个字节。支持的转义字符如下:

  • \xHH 以十六进制转义一个字节。
  • \n 换行(ASCII 10)
  • \t 制表符(ASCII 9)
  • \r 回车(ASCII 13)
  • \0 空(ASCII 0)
  • \z 空(ASCII 0)
  • \f 换页符(ASCII 12)
  • \e 退出键(ASCII 27)
  • \" 双引号(ASCII 34)
  • \uxxxx 转义4个十六进制字符表示的 UTF-8 码点
  • \Uxxxxxx 转义6个十六进制字符表示的 UTF-8 码点
  • \\ 反斜杠(ASCII 92)

字符串中的换行符会被忽略,这样可以定义一个不包含换行的多行字符串。

# same as "Thisisastring"
"This
is
a
string"

长字符串

Janet 中另一种表示字符串的方式是长字符串,用反引号表示。长字符串以任意数量的反引号开始,并以相同数量的反引号结束。长字符串不会进行转义,它可以用来定义包含换行,不可打印字符或需要多重转义字符的字符串。

# same as "This\nis\na\nstring."
``
This
is
a
string
``# same as "This is\na string."
`
This is
a string.
`

长字符串常用于文档,详见文档章节。

Buffers

缓冲区和字符串非常相似,但是它是可修改的。Janet 中的字符串创建后是不可修改的,但是缓冲区创建之后可以修改。缓冲区的语法和字符串和长字符串一样,但是缓冲区必须以 @ 开头。

@""
@"Buffer."
@``Another buffer``
@`
Yet another buffer
`

元组

元组是由圆括号或方括号包裹的以空格分隔的一些列值。解析器将字符 ASCII 32, \0\f\n\r\t\v 当作空白符。

(do 1 2 3)
[do 1 2 3]

方括号表示这个元组会被用作元组字面量而不是函数调用,宏调用或特殊形式。如果一个元组有方括号,解析器会在该元组上设置一个标志,以便让编译器知道要将这个元组编译成一个构造器。程序员可以通过 tuple/type 函数来检查一个元组是否有括号。

数组

数组与元组类似,但是以 @ 开头表示可以修改。

@(:one :two :three)
@[:one :two :three]

结构体

结构体是由大括号包裹的以空格分隔的一系列键值对。键值对序列定义为 key1,value1,key2,value2,等等。元素数量必须是偶数,否则解析器会发出解析错误。任何值都可以做为键和值。使用 nilmath/nan 做为键时,该键值对在解析后会被丢弃。

{}
{:key1 "value1" :key2 :value2 :key3 3}
{[1 2 3] [4 5 6]}
{@[] @[]}
{1 2 3 4 5 6}

Tables

表和结构体有相同的语法,但是以 @ 开头表示可以修改。

@{}
@{:key1 "value1" :key2 :value2 :key3 3}
@{[1 2 3] [4 5 6]}
@{@[] @[]}
@{1 2 3 4 5 6}

注释

单行注释以 # 开始,没有多行注释。

语法糖

在其他编程语言中,通常被称为读取宏(reader macros)的东西,Janet 为其中几种形式提供了简写符号。在 Janet 中这些语法以前缀形式出现且不可扩展。

'x

(quote x) 的语法糖。

;x

(splice x) 的语法糖。

~x

(quasiquote x) 的语法糖。

,x

(unquote x) 的语法糖。

|(body $)

(short-fn (body $)) 的语法糖。

这些简写符号可以以任意顺序组合,例如 ''x ((quote (quote x))) 或 ,;x ((unquote (splice x)))。

语法高亮

对于语法高亮,janet.vim 中有一些初步的Vim语法高亮支持。然而,通用的Lisp语法高亮应该也能提供很好的效果。此外,还可以通过从 Janet 源代码中运行 make grammar 命令来生成一个 janet.tmLanguage 文件,供其他程序使用。

语法

对于那些正在寻找更简洁语法描述的人来说,下面给出了一个用于识别 Janet 源代码的 PEG 语法。PEG 语法本身与 EBNF 类似。更多关于 PEG 语法的信息可以在 PEG 部分找到。

PEG(Parsing Expression Grammar,解析表达式语法)和EBNF(Extended Backus-Naur Form,扩展巴科斯范式)都是用于描述语法的工具,它们在编程语言的解析和编译器设计中非常重要。

(def grammar~{:ws (set " \t\r\f\n\0\v"):readermac (set "';~,|"):symchars (+ (range "09" "AZ" "az" "\x80\xFF") (set "!$%&*+-./:<?=>@^_")):token (some :symchars):hex (range "09" "af" "AF"):escape (* "\\" (+ (set `"'0?\abefnrtvz`)(* "x" :hex :hex)(* "u" [4 :hex])(* "U" [6 :hex])(error (constant "bad escape")))):comment (* "#" (any (if-not (+ "\n" -1) 1))):symbol :token:keyword (* ":" (any :symchars)):constant (* (+ "true" "false" "nil") (not :symchars)):bytes (* "\"" (any (+ :escape (if-not "\"" 1))) "\""):string :bytes:buffer (* "@" :bytes):long-bytes {:delim (some "`"):open (capture :delim :n):close (cmt (* (not (> -1 "`")) (-> :n) '(backmatch :n)) ,=):main (drop (* :open (any (if-not :close 1)) :close))}:long-string :long-bytes:long-buffer (* "@" :long-bytes):number (cmt (<- :token) ,scan-number):raw-value (+ :comment :constant :number :keyword:string :buffer :long-string :long-buffer:parray :barray :ptuple :btuple :struct :dict :symbol):value (* (any (+ :ws :readermac)) :raw-value (any :ws)):root (any :value):root2 (any (* :value :value)):ptuple (* "(" :root (+ ")" (error ""))):btuple (* "[" :root (+ "]" (error ""))):struct (* "{" :root2 (+ "}" (error ""))):parray (* "@" :ptuple):barray (* "@" :btuple):dict (* "@" :struct):main :root})
http://www.dtcms.com/a/575319.html

相关文章:

  • 异构比较查找
  • 网站价位无法访问服务器上网站
  • 服装购物网站排名icp备案证书
  • 网站对公司的作用是什么意思免费外贸网站制作
  • 一级a做爰片免费网站体验nginx进wordpress不能进目录
  • 湛江市建设局网站成功的软文营销案例
  • 对于网站开发有什么要求冉冉科技网站建设
  • 汝州网站建设网站建设方案数
  • 跨境电商平台网站建设制作h5用什么软件比较好
  • 网站构建设计思路设计参考网站推荐
  • 两台电脑一台做服务器 网站电商付费推广方式
  • 编写网站 支付宝做爰的最好看的视频的网站
  • 金华企业网站建设富阳seo关键词优化
  • 青岛网上房地产官网查网签苏州seo关键词优化
  • 网站建设行业发展方向企业百度网站怎么做
  • 做西装的网站金融保险网站模板
  • 网站做长连接用手机怎么制作软件
  • 购物网站建设教程全面的客户管理系统
  • 菏泽 兼职做网站阿里云网站建设教程
  • evince魔改记
  • 做内贸的网站小说网站怎么做用户画像
  • Spring AI Advisors API与 Ollama 的结合及实战示例
  • 互联网装修seo网站结构
  • php做自己的网站vue适合什么样的网站开发
  • 界面设计的算法解析
  • 用tornado做网站电商网站前端制作分工
  • 建一家网站多少钱wordpress emlog
  • 1系统分析与设计及 IT 项目管理
  • 企业建设网站目的商标注册45大类明细
  • RHCE : NFS实验1