kach / nearley

📜🔜🌲 Simple, fast, powerful parser toolkit for JavaScript.
https://nearley.js.org
MIT License
3.57k stars 231 forks source link

Parsing the text failed, and the error message said that an opening bracket is required, but I already have an opening bracket. #639

Open qinjunhang opened 11 months ago

qinjunhang commented 11 months ago

image

The content of wql.ne is:

# http://www.json.org/
# http://www.asciitable.com/
@{%

const moo = require('moo')

let lexer = moo.compile({
    space: {match: /\s+/, lineBreaks: true},
    number: /-?(?:[0-9]|[1-9][0-9]+)(?:\.[0-9]+)?(?:[eE][-+]?[0-9]+)?\b/,
    string: /"(?:\\["bfnrt\/\\]|\\u[a-fA-F0-9]{4}|[^"\\])*"/,
    key: /[a-zA-Z-_]+/,
    comparator: /=|<|<=|>=|>|!=/,
})

%}

@lexer lexer

start -> condition {% d => { return d[0]}  %}

operator -> "AND"  {% d => {   return d[0].value}  %}
    | "OR" {% d => {   return d[0].value}  %}

comparator -> %comparator {% d => { return d[0].value}  %} 

condition ->  _ expression  (_  operator _ expression ):* _  {% extractCondition %}

expression -> IDENTIFIER _ comparator _ LITERAL  {% function(d) { return [d[0], d[2], d[4]]; } %}  
    | "(" _ condition _ ")" {% function(d) { return [d[0], d[2], d[4]]; } %}

key -> %key {% function(d) { return d[0].value } %}
IDENTIFIER -> key   {% id %}

number -> %number {% function(d) { return parseFloat(d[0].value) } %}
string -> %string {% function(d) { return d[0].value } %}
LITERAL -> number  {% id %}
    | string   {% id %}
    | [a-zA-Z-_] {% function(d) { return d[0].value } %}

_ -> null | %space {% function(d) { return null; } %}

@{%
function extractCondition(d){
    console.log("@@@@@@@@@@@@",d)
    let output = [d[1]];

    for (let i in d[2]) {
        output.push(d[2][i][1]);
        output.push(d[2][i][3]);
    }

    return output;
}
%}
esdmr commented 11 months ago

The lexer seems to not have a token for open/close parenthesis. Adding that would solve it.

let lexer = moo.compile({
    space: {match: /\s+/, lineBreaks: true},
    number: /-?(?:[0-9]|[1-9][0-9]+)(?:\.[0-9]+)?(?:[eE][-+]?[0-9]+)?\b/,
    string: /"(?:\\["bfnrt\/\\]|\\u[a-fA-F0-9]{4}|[^"\\])*"/,
    key: /[a-zA-Z-_]+/,
    comparator: /=|<|<=|>=|>|!=/,
    lparen: '(',
    rparen: ')',
})

(Also, wql.ne seems to have some ambiguities. Notably: in expression, there is a _ both inside and outside condition. Also, since there is a lexer, character classes like [a-zA-Z-_] behave incorrectly. In this case, both [a-zA-Z-_] and %string can match at the same time.)