Java parser works fine but JavaScript parser built from the same grammar does not (antlr4)

1,624 views
Skip to first unread message

Marshall Levin

unread,
Jun 17, 2015, 8:00:57 PM6/17/15
to antlr-di...@googlegroups.com, Marshall Levin
Hey folks,

I'm kinda stumped here. I have a really simple grammar. It works fine in Java.

Here's the grammar.

bash-3.2$ cat Simple.g4

grammar Simple;

date : month year ;
month : MONTH ;
year : YEAR ;

MONTH : 'January' | 'February' | 'March' | 'April' | 'May' | 'June' | 'July' | 'August' | 'September' | 'October' | 'November' | 'December' ;
YEAR : [1-9][0-9][0-9][0-9] ;

WS : [ \t\r\n]+ -> skip ;

I can build the Java parser and successfully parse some input.

bash-3.2$ antlr4 -o . -listener -visitor Simple.g4
bash-3.2$ javac *.java
bash-3.2$ grun Simple date -tree
February 1923
(date (month February) (year 1923))

Next I build the JavaScript parser.

bash-3.2$ antlr4 -o . -listener -visitor -Dlanguage=JavaScript Simple.g4

My node.js project uses the antlr4 JavaScript runtime.

bash-3.2$ cat package.json
{
  "name": "parser-js",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node test-parser.js"
  },
  "dependencies": {
    "antlr4": "^4.5.2"
  }
}
bash-3.2$ npm install

Here's the JavaScript I'm using, which is pretty much copied from https://theantlrguy.atlassian.net/wiki/display/ANTLR4/JavaScript+Target.

bash-3.2$ cat test-parser.js
var antlr4 = require('antlr4/index');
var SimpleLexer = require('./SimpleLexer');
var SimpleParser = require('./SimpleParser');

MyGrammarListener = function(ParseTreeListener) {};
MyGrammarListener.prototype.enterDate = function(ctx) {};
MyGrammarListener.prototype.exitDate = function(ctx) {};
MyGrammarListener.prototype.enterMonth = function(ctx) {};
MyGrammarListener.prototype.exitMonth = function(ctx) {};
MyGrammarListener.prototype.enterYear = function(ctx) {};
MyGrammarListener.prototype.exitYear = function(ctx) {};
DatePrinter = function() {
MyGrammarListener.call(this);
return this;
};
DatePrinter.prototype = Object.create(MyGrammarListener.prototype);
DatePrinter.prototype.constructor = DatePrinter;

DatePrinter.prototype.exitYear = function(ctx) {
console.log("Thank you for entering a year!");
};

var input = "February 1923";

var chars = new antlr4.InputStream(input);
var lexer = new SimpleLexer.SimpleLexer(chars);
var tokens = new antlr4.CommonTokenStream(lexer);
var parser = new SimpleParser.SimpleParser(tokens);
parser.buildParseTrees = true;
var tree = parser.date();
var printer = new DatePrinter();
antlr4.tree.ParseTreeWalker.DEFAULT.walk(printer, tree);

When I attempt to execute this code, I get the following error:

bash-3.2$ npm start

> pars...@0.0.0 start /tmp/antlr4-test
> node test-parser.js

/tmp/antlr4-test/node_modules/antlr4/tree/Tree.js:207
listener.enterEveryRule(ctx);
        ^
TypeError: undefined is not a function
    at ParseTreeWalker.enterRule (/tmp/antlr4-test/node_modules/antlr4/tree/Tree.js:207:11)
    at ParseTreeWalker.walk (/tmp/antlr4-test/node_modules/antlr4/tree/Tree.js:191:8)
    at Object.<anonymous> (/tmp/antlr4-test/test-parser.js:32:37)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Function.Module.runMain (module.js:501:10)
    at startup (node.js:129:16)
    at node.js:814:3

npm ERR! Darwin 14.3.0
npm ERR! argv "node" "/usr/local/bin/npm" "start"
npm ERR! node v0.12.2
npm ERR! npm  v2.7.6
npm ERR! code ELIFECYCLE
npm ERR! pars...@0.0.0 start: `node test-parser.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the pars...@0.0.0 start script 'node test-parser.js'.
npm ERR! This is most likely a problem with the parser-js package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node test-parser.js
npm ERR! You can get their info via:
npm ERR!     npm owner ls parser-js
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /tmp/antlr4-test/npm-debug.log

Can anyone see what I might be doing wrong?

Thanks.

Marshall Levin

unread,
Jun 18, 2015, 12:13:12 PM6/18/15
to antlr-di...@googlegroups.com
Ah, I think I made some progress. The correct JS code (at least the one I got to work) is:

var antlr4 = require('antlr4/index');
var SimpleLexer = require('./SimpleLexer');
var SimpleParser = require('./SimpleParser');
var SimpleListener = require('./SimpleListener');

YearPrinter = function () {
    SimpleListener.SimpleListener.call(this);
    return this;
};
YearPrinter.prototype = Object.create(SimpleListener.SimpleListener.prototype);
YearPrinter.prototype.constructor = YearPrinter;
YearPrinter.prototype.exitYear = function (ctx) {
    console.log(ctx);
};

var input = "January 1900";
var chars = new antlr4.InputStream(input);
var lexer = new SimpleLexer.SimpleLexer(chars);
var tokens = new antlr4.CommonTokenStream(lexer);
var parser = new SimpleParser.SimpleParser(tokens);
parser.buildParseTrees = true;
var tree = parser.date();
var printer = new YearPrinter();
antlr4.tree.ParseTreeWalker.DEFAULT.walk(printer, tree);

Enise KILAVUZ

unread,
Aug 31, 2015, 3:17:07 AM8/31/15
to antlr-discussion
Hi Marshall,

Actually, I am new on Antlr4 and javascript. I did your example and worked it fine. But I want to get leaf node values. And I do not know how to get values, so I need your help this topic. I searched it and googled but I cant find any helpfully knowledge. 

Thanks

18 Haziran 2015 Perşembe 19:13:12 UTC+3 tarihinde Marshall Levin yazdı:

Eric Vergnaud

unread,
Aug 31, 2015, 11:42:22 AM8/31/15
to antlr-discussion
That is a task for your Listener, which must override the corresponding methods.
In Marshall's example, the 'exitYear' method overrides the default one (which does nothing)

KN

unread,
Oct 28, 2015, 12:40:58 PM10/28/15
to antlr-discussion
I tried your code almost exactly as is, and I am getting errors related to the requirejs module loading.  "Uncaught ReferenceError: exports is not defined".  My code is below.  There are 'exports' commands in the index.js files in the antlr4 javascript runtime files.  Are those only intended to be run on the server (like in Node)?

<html>
<head>
 
<script src='https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.20/require.js'></script>
 
<script>

 
var antlr4 = require(['antlr4/index']);

 
var SimpleLexer = require(['Grammar/SimpleLexer']);

 
var SimpleParser = require(['Grammar/SimpleParser']);
 var SimpleListener = require(['Grammar/SimpleListener']);
 </script>
</head>
<body>
 
<script>

 
YearPrinter = function () {

 
SimpleListener.SimpleListener.call(this);
 
return this;
 
};
 
YearPrinter.prototype = Object.create(SimpleListener.SimpleListener.prototype);
 
YearPrinter.prototype.constructor = YearPrinter;
 
YearPrinter.prototype.exitYear = function (ctx) {
 console
.log(ctx);
 
};
 
 
var input = "January 1900";
 
var chars = new antlr4.InputStream(input);
 
var lexer = new SimpleLexer.SimpleLexer(chars);
 
var tokens = new antlr4.CommonTokenStream(lexer);
 
var parser = new SimpleParser.SimpleParser(tokens);
 parser
.buildParseTrees = true;
 
var tree = parser.date();
 
var printer = new YearPrinter();
 antlr4
.tree.ParseTreeWalker.DEFAULT.walk(printer, tree);

 
</script>

</body>
</html>




Eric Vergnaud

unread,
Oct 28, 2015, 8:00:15 PM10/28/15
to antlr-discussion
Hi, you need a 'require' function compatible with NodeJS syntax. 
I dont know if the one from cloud flare is compatible, but it doesn't seem to be from the look of it.
There is one here:
Reply all
Reply to author
Forward
0 new messages