antlr / antlr4

ANTLR (ANother Tool for Language Recognition) is a powerful parser generator for reading, processing, executing, or translating structured text or binary files.
http://antlr.org
BSD 3-Clause "New" or "Revised" License
17.11k stars 3.28k forks source link

JavaScript target: code defined by @parser::members should not be put inside constructor #2308

Open YuhangGe opened 6 years ago

YuhangGe commented 6 years ago

g4 file content:

grammar Expr;

@lexer::members {
ExprLexer.prototype.test = function() {
  console.log('test in lexer');
};
}

@parser::members {
ExprParser.prototype.test = function() {
  console.log('test in parser');
};
}

prog locals[k = 0]: (line{console.log($k++)})+;

line: ID NL;

ID: [a-zA-Z]+;
NL: '\r'? '\n';
WS: [ \t]+ -> skip;

The code defined by members in generated ExprParser.js and ExprLexer.js has different position.

In ExprLexer.js:

// more code ...

ExprLexer.prototype.grammarFileName = "Expr.g4";

ExprLexer.prototype.test = function() {
  console.log('test in lexer');
};

exports.ExprLexer = ExprLexer;

In ExprParser.js:

function ExprParser (input) {
    antlr4.Parser.call(this, input);
    this._interp = new antlr4.atn.ParserATNSimulator(this, atn, decisionsToDFA, sharedContextCache);
    this.ruleNames = ruleNames;
    this.literalNames = literalNames;
    this.symbolicNames = symbolicNames;

    ExprParser.prototype.test = function() {
      console.log('test in parser');
    };

    return this;
}
ExprParser.prototype = Object.create(antlr4.Parser.prototype);
ExprParser.prototype.constructor = ExprParser;
// more code ...

I think ExprLexer.js is right but ExprParser.js is wrong, because member functions or member properties of class in javascript language should be defined on prototype.

The right code in ExprParser.js should be:

function ExprParser (input) {
    antlr4.Parser.call(this, input);
    this._interp = new antlr4.atn.ParserATNSimulator(this, atn, decisionsToDFA, sharedContextCache);
    this.ruleNames = ruleNames;
    this.literalNames = literalNames;
    this.symbolicNames = symbolicNames;
    return this;
}
ExprParser.prototype = Object.create(antlr4.Parser.prototype);
ExprParser.prototype.constructor = ExprParser;

ExprParser.prototype.test = function() {
    console.log('test in parser');
};

// more code ...
ericvergnaud commented 6 years ago

You might be right. Can you propose a fix?

Envoyé de mon iPhone

Le 13 juin 2018 à 15:54, 白羊座小葛 notifications@github.com a écrit :

g4 file content:

grammar Expr;

@lexer::members { ExprLexer.prototype.test = function() { console.log('test in lexer'); }; }

@parser::members { ExprParser.prototype.test = function() { console.log('test in parser'); }; }

prog locals[k = 0]: (line{console.log($k++)})+;

line: ID NL;

ID: [a-zA-Z]+; NL: '\r'? '\n'; WS: [ \t]+ -> skip; The code defined by members in generated ExprParser.js and ExprLexer.js has different position.

In ExprLexer.js:

// more code ...

ExprLexer.prototype.grammarFileName = "Expr.g4";

ExprLexer.prototype.test = function() { console.log('test in lexer'); };

exports.ExprLexer = ExprLexer; In ExprParser.js:

function ExprParser (input) { antlr4.Parser.call(this, input); this._interp = new antlr4.atn.ParserATNSimulator(this, atn, decisionsToDFA, sharedContextCache); this.ruleNames = ruleNames; this.literalNames = literalNames; this.symbolicNames = symbolicNames;

ExprParser.prototype.test = function() { console.log('test in parser'); };

return this;

} ExprParser.prototype = Object.create(antlr4.Parser.prototype); ExprParser.prototype.constructor = ExprParser; // more code ... I think ExprLexer.js is right, because member functions or member properties of class in javascript language should be defined on prototype.

The right code in ExprParser.js should be:

function ExprParser (input) { antlr4.Parser.call(this, input); this._interp = new antlr4.atn.ParserATNSimulator(this, atn, decisionsToDFA, sharedContextCache); this.ruleNames = ruleNames; this.literalNames = literalNames; this.symbolicNames = symbolicNames; return this; } ExprParser.prototype = Object.create(antlr4.Parser.prototype); ExprParser.prototype.constructor = ExprParser;

ExprParser.prototype.test = function() { console.log('test in parser'); };

// more code ... — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.