Первое, что следует отметить, это то, что вы вызываете start
с объектом ProgContext
, а затем вызываете visitExpressionSequence
для него. Это на самом деле не имеет значения в этом случае, потому что вы не переопределяете ни vistExpressionSequence
, ни visitProg
, так что на самом деле оба по умолчанию просто вызывают visitChildren
, поэтому не имеет значения, какой из них вы вызываете. Тем не менее, вы действительно должны вызывать visit
только явно, а не какой-либо из методов visitFoo
. visit
всегда будет следить за тем, чтобы был вызван правильный метод visitFoo
.
Переходя к актуальной проблеме, у вас есть две проблемы: во-первых, ключ в вашем выводе не имеет кавычек, даже если ваш метод visitPropertyExpressionAssignment
должен выполнить именно это. А во-вторых, в конце вывода есть <EOF>
, который, я полагаю, вам не нужен.
Первая проблема заключается в том, что ваш ввод при синтаксическом анализе выдает синтаксическую ошибку. Это связано с тем, что {x: 1}
на самом деле не является допустимой программой на JavaScript, поскольку {
в начале оператора рассматривается как начало блока, а не как литерал объекта. Вам нужно было бы заключить скобки вокруг литерала, чтобы сделать его действительным в начале оператора.
Вторая проблема заключается в том, что правило prog
завершается в конце файла, создавая маркер EOF
. Чтобы не печатать это, вы можете просто переопределить visitProg
, чтобы вызывать только visit
в своем списке выписок, а не в EOF
токене.
Вы устранили первую проблему, вызвав правило expressionSequence
в своем парсере вместо prog
. Если анализировать выражение вместо программы, это нормально (хотя в контексте, подобном REPL, вы можете вместо этого попытаться проанализировать входные данные как выражение и, если это не получится, проанализировать его как оператор). Может показаться, что это также решит вашу вторую проблему, но это не совсем так:
Вы больше не получаете <EOF>
в выводе, потому что вы больше не соответствует концу файла. Это означает, что если входные данные состоят из действительного выражения, за которым следует полная фигня (скажем, const input = '{x: 1} krgsfkjhwruei';
), это не вызовет синтаксической ошибки, а вместо этого удачно проанализирует часть {x: 1}
, а затем полностью проигнорирует часть мусора без Любое указание на проблему. Это почти никогда не то, что вы хотите. Вместо этого вы можете определить новое правило в вашей грамматике, которое соответствует выражению, за которым следует конец файла, например:
expressionInput: expressionSequence EOF;
Теперь, если вход содержит мусор после правильного выражения, вы получите синтаксическую ошибку. Однако это вновь введет проблему <EOF>
в выводе. Но опять же, вы можете просто исправить это, переопределив visitExpressionInput
, а затем вызывая только visit(ctx.expressionSequence);
.