我正在使用 nearley.js 和 moo.js 來制作編程語言。用moo.js,有一個NL,意思是換行正則匹配,我的是`/[\r\n] /,但是好像有問題。在我正在關注的教程中,它說
Unexpected WS token: " ". Instead, I was expecting to see one of the following:
A identifier token based on:
var_assign → ● %identifier _ "=" _ expr
A identifier token based on:
fun_call → ● %identifier _ "(" _ fun_call$ebnf$1 ")"
at Parser.feed (C:\Users\mcqui\OneDrive\Desktop\Programming language for capstones\node_modules\nearley\lib\nearley.js:343:27)
at main (C:\Users\mcqui\OneDrive\Desktop\Programming language for capstones\parse.js:15:12)
我不知道該怎么做,因為我檢查了所有內容,但它似乎不起作用。這是我的 lexer.js 檔案:
const moo = require('moo')
const fs = require("mz/fs")
let lexer = moo.compile({
WS: /[ \t] /,
comment: /\/\/.*?$/,
number: /0|[1-9][0-9]*/,
string: /"(?:\\["\\]|[^\n"\\])*"/,
lparen: '(',
rparen: ')',
lbrace: '{',
rbrace: '}',
identifier: /[a-zA-Z][a-zA-Z_0-9]*/,
fatarrow: '=>',
assign: '=',
NL: { match: /[\r\n] /, lineBreaks: true }
});
module.exports = lexer;
async function main(){
const code = (await fs.readFile("main.kpp")).toString()
lexer.reset(code)
while (true){
const token = lexer.next();
if(!token){
break;
}
console.log(token);
}
}
這是我的 parse.js 檔案:
const nearley = require("nearley");
const grammar = require("./kpp.js");
const fs = require('mz/fs');
async function main() {
const filename = process.argv[2];
if(!filename){
console.log("Provide a .kpp file");
return;
}
const code = (await fs.readFile(filename)).toString();
const parser = new nearley.Parser(nearley.Grammar.fromCompiled(grammar));
parser.feed(code);
if(parser.results.length > 1){
console.log('Error');
} else if (parser.results.length == 1){
const ast = parser.results[0];
const outputFilename = filename.replace('.kpp', '.ast');
await fs.writeFile(outputFilename, JSON.stringify(ast, null, " "))
console.log(`WROTE ${outputFilename}.`)
} else{
console.log("Parse error")
}
}
main().catch(err => console.log(err.stack));
這是我正在運行的檔案(在我自己的編程語言中:
f = () => 1
g = (a b) => add(multiply(2 a) b)
h = (x y) => {
show("x=" x)
show("y=" y)
g(x y)
}
result = h(3 4)
show("result =" result)
show("f =" f())
show("f(gf f) =" g(f() f()))
這是 nearley.js 組態檔:
@{%
const myLexer = require("./lexer")
%}
@lexer myLexer
statements
->statement
{%
(data) => {
return [data[0]]
}
%}
| statements %NL statement
{%
(data) => {
return [...data[0], data[2]]
}
%}
statement
-> var_assign {% id %}
| fun_call {% id %}
var_assign
-> %identifier _ "=" _ expr
{%
(data) => {
return {
type: "var_assign",
var_name: data[0],
value: data[4]
}
}
%}
fun_call
-> %identifier _ "(" _ (arg_list _):? ")"
{%
(data) => {
return {
type: 'fun_call',
fun_name: data[0],
arguments: data[4] ? data[4][0] : []
}
}
%}
arg_list
-> expr
{%
(data) => {
return [data[0]]
}
%}
| arg_list __ expr
{%
(data) => {
return [...data[0], data[2]]
}
%}
expr
-> %string {% id %}
| %number {% id %}
| %identifier {% id %}
| fun_call {% id %}
| lamba {% id %}
lamba -> "(" _ (param_list _):? ")" _ "=>" _ lamba_body
{%
(data) => {
return {
type: "lamba",
parameters: data[2] ? data[2][0] : [],
body: data[7]
}
}
%}
param_list
-> %identifier (__ %identifier):*
{%
(data) => {
const repeatedPieces = data[1];
const restParams = repeatedPieces.map(piece => piece[1])
return [data[0], ...restParams]
}
%}
lamba_body
-> expr
{%
(data) => {
return [data[0]];
}
%}
| "{" _ %NL statements %NL _ "}"
{%
(data) => {
return data[3];
}
%}
_ -> %WS:*
__ -> %WS:
uj5u.com熱心網友回復:
這里的問題來自這樣一個事實,即您沒有指定任何關于制表期望的內容。
statements %NL statement清楚地告訴決議器,除了一個或多個換行符之外,您別無所求。我建議您不要將新行本身指定為字串的結尾,而是期望空格(換行符空格):* 代替。您還可以使用此詞法分析器和此空白規則使用的類似技術。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/503661.html
標籤:javascript 节点.js 正则表达式 近利
上一篇:洗牌一副牌js的功能
