在通过 HomeBrew 安装的 macOS 上设置 ANTLR 的 CLASSPATH

setting up ANTLR's CLASSPATH on macOS installed via HomeBrew

之后,我通过 HomeBrew 安装了 ANTLR:

brew install antlr

它安装在:

/usr/local/Cellar/antlr/<version>/

并通过

安装了Python运行时间
pip3 install antlr4-python3-runtime

来自,我运行

export CLASSPATH=".:/usr/local/Cellar/antlr/<version>/antlr-<version>-complete.jar:$CLASSPATH"

但是当我运行命令

grun <grammarName> <inputFile>

我收到臭名昭著的错误消息:

Can't load <grammarName> as lexer or parser

如果您能帮助我了解问题以及解决方法,我将不胜感激。

P.S. 应该没关系,但你可能会看到我正在处理的代码 here.

此错误消息表明 TestRig(grun 别名使用)无法在您的 class 路径中找到解析器(或词法分析器)class。如果您已将生成的解析器放在包中,您可能需要考虑包名称,但最主要的是生成的(和编译的)class 在您的 class 路径中。

此外.. TestRig 将 grammarNamestartRule 作为参数,并期望您的输入来自标准输入。

我克隆了您的存储库以仔细查看您的问题。

为什么 g运行 给你这个问题的直接问题是你在语法文件中指定了你的目标语言(看来我需要收回关于它在你的语法中没有任何内容的评论) .通过在语法中指定 python 作为目标语言,您不会生成 TestRig class(由grun 别名) 需要执行。

我从语法中删除了目标语言选项,并且能够 运行 g运行 命令针对您的示例输入。为了让它正确解析,我冒昧地修改了您语法中的几处内容:

  • 删除了目标语言(通常最好在 antlr 命令行上指定目标语言,这样语法仍然与语言无关(如果您想使用 TestRig/grun 实用程序进行测试,这也是必不可少的, 因为你需要 Java 目标)).
  • SectionName 词法分析器规则更改为 section 解析器规则(带有标记的替代方案。拥有像 'Body ' Integer 这样的词法分析器规则将为您提供一个包含 body 关键字和整数的标记,然后你必须稍后分开(它也迫使 'Body' 和整数之间只有一个 space)。
  • NewLine 标记设置为 -> skip(这对我来说有点假设,但不跳过 NewLine 将需要修改更多解析规则以指定所有 NewLine 是一个有效的标记。)
  • 删除了 StatementEnd 词法分析器规则,因为我 skip 编辑了 NewLine 标记
  • IntegerFloat 东西改成了两个不同的标记,这样我就可以在 section 解析器规则中使用 Integer 标记。
  • 为了让这个框架能够处理您的示例输入,还进行了一些小的调整。

我使用的结果语法是:

grammar ElmerSolver;

// Parser Rules

// eostmt: ';' | CR;

statement: ';';

statement_list: statement*;

sections: section+ EOF;
// section: SectionName /* statement_list */ End;

// Lexer Rules

fragment DIGIT: [0-9];
Integer: DIGIT+;

Float:
    [+-]? (DIGIT+ ([.]DIGIT*)? | [.]DIGIT+) ([Ee][+-]? DIGIT+)?;

section:
    'Header' statement_list End                         # headerSection
    | 'Simulation' statement_list End                   # simulatorSection
    | 'Constants' statement_list End                    # constantsSection
    | 'Body ' Integer statement_list End                # bodySection
    | 'Material ' Integer statement_list End            # materialSection
    | 'Body Force ' Integer statement_list End          # bodyForceSection
    | 'Equation ' Integer statement_list End            # equationSection
    | 'Solver ' Integer statement_list End              # solverSection
    | 'Boundary Condition ' Integer statement_list End  # boundaryConditionSection
    | 'Initial Condition ' Integer statement_list End   # initialConditionSection
    | 'Component' Integer statement_list End            # componentSection;

End: 'End';

// statementEnd: ';' NewLine*;

NewLine: ('\r'? '\n' | '\n' | '\r') -> skip;

LineJoining:
    '\' WhiteSpace? ('\r'? '\n' | '\r' | '\f') -> skip;

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

LineComment: '#' ~( '\r' | '\n')* -> skip;

有了这些变化,我 运行

➜ antlr4 ElmerSolver.g4
javac *.java                                         
grun ElmerSolver sections -tree  < examples/ex001.sif

得到输出:

(sections (section Simulation statement_list End) (section Equation  1 statement_list End) <EOF>)