这是一个非常长期而又伟大的目标
至少, 在计算机的领域, 自己动手实现一个工具是一个很好的学习的过程
所以在简单了解了一下基础之后, 就决定要开工了!
先实现 目标语言 -> js 这样一个简单的小目标再说
PS: 主要是为了记录一些遇到的问题和思考的问题
先使用最简单的方式实现 print
至少很多方面, 很可能就先基于 js 进行实现了
./main.sx
可以先使用 js 来实现一些很麻烦的功能, 反正不行就调用 js 的一个函数嘛, 就像这样
./io.js
嘛...看起来好像是一个很简单的的过程, 也就这么两行代码不是吗? 但实际上, 可能大概, 稍微有一丢丢的复杂
虽然只需要解析两行代码, 但还是需要对这两行代码进行一些分组分类操作的
比如有一些文本是关键字: [import, as] (反正个人感觉 js 的 import 有点奇怪, 所以稍稍修改了一下下
然后有一些是字面量: ['./io.js', 123] (其实有考虑这里要不要把引号作为标示符去解析, 为了简单还是先作为整体吧
最后还有一些变量名字?: [io, print] (姑且先这么称呼吧
一些操作符: [.] 和 括号 [(, )] (感觉并不是很懂, 但直觉上最好把括号单独作为一个分类拎出来 orz, PS: 可能是由于括号都是成对出现的大概
好啦, 这样基本上就把最基本的元素准备齐全了, 大概这样
之后需要做的就是把它从字符串解析一下下~
好~ 现在有了一个很烂的匹配算法, 不要在意一些细节~
至少现在已经可以将代码从文本转换成结构化的数据了~
之后想办法处理一下这个结构
虽然这次很短, 但是未完待续~
PS: 补一下相关的工具函数 orz
以及这个文件现在的源代码, 稍微改动了一丢丢 (number -> integer
const tokenTypes = [
'keyword',
'name',
'operator',
'paren',
// 字面量类型
// PS: 想了一下, 字面量还是归类为 tokens 可能会好一些?
'string',
'integer',
]
const keywords = [
'import',
'as',
]
const parens = ['(', ')']
const operator = ['.']
function getTokens(input) {
const tokens = []
let cur = 0
function whileForChar(char) {
const ending = char
let str = char
while(str === ending ||
char !== ending && cur < input.length
) {
cur++
char = input[cur]
str += char
}
cur++
return str
}
function whileForRegexp(regexp) {
let str = ''
char = input[cur]
while (char.match(regexp) && cur < input.length) {
str += char
cur++
char = input[cur]
}
return str
}
while(cur < input.length) {
let char = input[cur]
// 空格或者换行, 就暂且先认为是一个 str
if (char.match(/\s/)) {
if (char === '\n') {
tokens.push({ type: 'operator', value: '\n' })
}
cur++
continue
}
// 匹配括号~
if (parens.includes(char)) {
tokens.push({ type: 'paren', value: char })
cur++
continue
}
// 匹配操作符~
// PS: 考虑到操作符不止会有一个, 突然想起来还有上面的括号!
if (operator.includes(char)) {
// 先这样实现吧~
tokens.push({ type: 'operator', value: char })
cur++
continue
}
// 匹配字符串, 写的有点烂
if (char.match(/\'|\"/)) {
const str = whileForChar(char)
tokens.push({ type: 'string', value: str })
continue
}
// 匹配数字
if (char.match(/\d/)) {
const str = whileForRegexp(/\d/)
tokens.push({ type: 'integer', value: str })
continue
}
// 匹配一部分变量名
if (char.match(/[A-Z]|_/)) {
const str = whileForRegexp(/[a-zA-Z]|_|[0-9]/)
tokens.push({ type: 'name', value: str })
continue
}
// 匹配关键字
if (char.match(/[a-z]/)) {
const str = whileForRegexp(/[a-zA-Z]|_|[0-9]/)
if (!keywords.includes(str)) {
tokens.push({ type: 'name', value: str })
continue
}
tokens.push({ type: 'keyword', value: str })
continue
}
console.error('not match')
cur++
}
return tokens
}
module.exports = { getTokens }