lua-lexer
动手写个词法解析器,词法解析非常简单其关键处理问题在于
- 字符串
- 数字
- 关键字与符号
定义关键字及符号映射
src=lua-lexer.js
<style>
.token {
display: inline-block;
padding: 4px;
border: 1px solid var(--base00, transparent);
margin: 2px;
border-radius: 4px;
}
</style>
<div>
<textarea rows="20" style="width:100%" id="input" autofocus>
'\u{1f481}'
'\x61'
'\97'
'a'
[[a]]
1
1.1
1.1e-1
1.1e+1
.1
local abc = 123;
if(abc="123"){
print(abc)
}
string='123'
-- abc
-- [[
comment
]]--
longString = [[too long]]
</textarea
>
<button id="generate">generate</button>
</div>
<div id="tag" style="width:100%;min-height:200px;font-size:14px;"></div>
<script>
const input = document.getElementById("input");
const g = document.getElementById("generate");
const t = document.getElementById("tag");
const lexerCom = () => {
console.log("start..");
t.innerHTML = "";
let err = "";
try {
const lexer = new Lexer(input.value, "main.lua");
let d = "";
let token = lexer.nextToken();
while (token[0] !== TOKEN_EOF) {
d += gt(token);
token = lexer.nextToken();
}
d += gt(token);
t.innerHTML = d;
} catch (e) {
console.error(e);
t.innerHTML = `<div style="color:red;font-size:14px;">${e.message}</div>`;
}
};
g.onclick = lexerCom;
lexerCom();
function colorRandom() {
const color = [
"yellow",
"orange",
"red",
"magenta",
"violet",
"blue",
"cyan",
"green",
];
return color[Math.floor(Math.random() * color.length)];
}
function gt(token) {
let [kind, tok, location] = token;
let printStr = `[${kindToCategory(kind)}] ${tok}`;
return `<div class="token" style="color:var(--${colorRandom()})" data-start=${
location?.start.offset
} data-end=${location?.end.offset}>${printStr}</div>`;
}
// This handler will be executed every time the cursor
// is moved over a different list item
t.addEventListener(
"mouseover",
function (event) {
event.target.style.borderColor = "orange";
let start = event.target.dataset["start"];
let end = event.target.dataset["end"];
setTimeout(() => {
input.setAttribute("readonly", true);
input.focus();
input.setSelectionRange(start, end);
}, 10);
event.preventDefault();
},
false
);
t.addEventListener(
"mouseout",
function (event) {
event.target.style.borderColor = "";
input.removeAttribute("readonly");
},
false
);
</script>