我正在使用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:+https://stackoverflow.com/questions/73603121
复制相似问题