【问题标题】:TypeScript antlr4ts listener type throwing an errorTypeScript antlr4ts 监听器类型抛出错误
【发布时间】:2018-08-24 06:02:37
【问题描述】:

我正在尝试在 Angular 项目中使用 antlr4 解析器。

有一个数据服务类,其中调用的函数如下所示

parseRule() {
  const ruleString = ' STRING TO PARSE';

  const inputStream = new ANTLRInputStream(ruleString);
  const lexObject = new lexer.scopeLexer(inputStream);
  const tokenStream = new CommonTokenStream(lexObject);
  const parseObject = new parser.scopeParser(tokenStream);
  const result = parseObject.file();
  const evaluator = new ScopeEvaluator();
  const walker = new ParseTreeWalker();

  walker.walk(evaluator, result);
  console.log(' result :', result.text);
}

客户侦听器正在实现仅使用一种方法导出的接口,即 enterNonGraphScope。

import { scopeListener } from './antlrscope/scopeListener';
import { NonGraphScopeContext, NamesetSimpleContext } from './antlrscope/scopeParser';

export class ScopeEvaluator implements scopeListener {

  constructor() {
    console.log('constructed the asdfasf');
  }

  enterNonGraphScope = function (ctx: NonGraphScopeContext) {
    console.log('Tis ', ctx.text);
  };

}

从 scopeListener.ts 中粘贴一些 sn-p 用于说明界面

export interface scopeListener extends ParseTreeListener {

/**
 * Enter a parse tree produced by the `NonGraphScope`
 * labeled alternative in `scopeParser.scope`.
 * @param ctx the parse tree
*/
enterNonGraphScope?: (ctx: NonGraphScopeContext) => void;

当我运行 angular ng serve 时,它​​正在编译打字稿代码。 我收到一个错误

src/app/rule-parser.service.ts(31,17) 中的错误:错误 TS2559:“ScopeEvaluator”类型与“ParseTreeListener”类型没有共同的属性。

下面是打字稿中生成的监听器。 (删除内容和antlr生成的cmets)

export interface scopeListener extends ParseTreeListener {
    enterNonGraphScope?: (ctx: NonGraphScopeContext) => void;
    exitNonGraphScope?: (ctx: NonGraphScopeContext) => void;
    enterBlockScope?: (ctx: BlockScopeContext) => void;
    exitBlockScope?: (ctx: BlockScopeContext) => void;
    enterNamesetSimple?: (ctx: NamesetSimpleContext) => void;
    exitNamesetSimple?: (ctx: NamesetSimpleContext) => void;
    enterGrainExpression?: (ctx: GrainExpressionContext) => void;
    exitGrainExpression?: (ctx: GrainExpressionContext) => void;
    enterGrainSimple?: (ctx: GrainSimpleContext) => void;
    exitGrainSimple?: (ctx: GrainSimpleContext) => void;
    enterNamesetExpression?: (ctx: NamesetExpressionContext) => void;
}

这似乎与打字稿解释或打字有关。 我是 javascript/typescript 的新手。你能帮帮我吗?

webpack / 生成的 javascript 代码运行良好,但此错误阻止生成构建。

非常感谢!

-维纳亚克

【问题讨论】:

    标签: angularjs typescript antlr4


    【解决方案1】:

    我对此进行了一些谷歌搜索,发现这可以通过弱类型处理更改来做一些事情。更多详情请点击以下链接。

    https://blogs.msdn.microsoft.com/typescript/2017/06/12/announcing-typescript-2-4-rc/

    基于此,另一个 * 讨论位于 After upgrading TypeScript, Angular controller registration now fails to compile

    对实现接口的类的以下修改有效。 选项 1 更好,因为它只是一个类型断言。

    选项 1

        parseRule() {
          const ruleString = ' Scope: (Dim1.Attr1 * &Namset1);' +
            ' Measure.[asdfa] = ddd ;' +
            'end scOPe;';
    
          const inputStream = new ANTLRInputStream(ruleString);
          const lexObject = new lexer.scopeLexer(inputStream);
          const tokenStream = new CommonTokenStream(lexObject);
          const parseObject = new parser.scopeParser(tokenStream);
          const result = parseObject.file();
          const evaluator = new ScopeEvaluator();
          const walker = new ParseTreeWalker();
          console.log(' type of ' , evaluator);
          walker.walk(evaluator as ParseTreeListener, result);
            // Parse and execute the code.
            console.log(' p :', parseObject);
          console.log(' result :', result.text);
        }
    

    选项 2 - 涉及重新声明内容?

                import { scopeListener } from './antlrscope/scopeListener';
                import { NonGraphScopeContext, NamesetSimpleContext } from './antlrscope/scopeParser';
                import { ParseTreeListener } from 'antlr4ts/tree/ParseTreeListener';
    
    
                export class ScopeEvaluator implements scopeListener {
    
                    visitTerminal = () => { };
                    visitErrorNode = () => { };
                    enterEveryRule = () => { };
                    exitEveryRule = () => { };
                    enterNonGraphScope = function (ctx: NonGraphScopeContext) {
                        console.log('Tis ', ctx.text);
                    };
                }
    

    如果您觉得这不是正确的做法,请发表评论。我对 typescript 的理解还不完整。

    【讨论】:

    • 您目前使用的是哪个TS版本? My listener 在没有这些技巧的情况下进行编译(我在 2.7.2 atm 上)。你的scopeListener 怎么样?方法签名是否正确?这里的完整错误信息是什么?可能你和NonGraphScopeContext类型有冲突?
    • @MikeLischke 在 Angular 项目中,打字稿版本为 2.5.3 。我不确定是否升级打字稿版本,角度项目中的任何内容都会受到影响。我会将听众添加到主要问题中。在 Angular 中,当我运行 ng serve 时,我得到了那个错误,虽然编译通过了,但是当我进行生产构建时,错误阻止我构建 Angular 应用程序。
    • 我只会接受我自己的答案。它可能有助于新人尝试在当前的角度构建上使用 antlr。