在通过 HomeBrew 安装的 macOS 上设置 ANTLR 的 CLASSPATH [英] setting up ANTLR's CLASSPATH on macOS installed via HomeBrew

查看:46
本文介绍了在通过 HomeBrew 安装的 macOS 上设置 ANTLR 的 CLASSPATH的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据这个问题,我通过 HomeBrew 安装了 ANTLR:

Following this question, I have ANTLR installed via HomeBrew:

brew install antlr

它安装在:

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

并通过

pip3 install antlr4-python3-runtime

这里,我运行了

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

但是当我运行命令时

grun <grammarName> <inputFile>

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

I get the infamous error message:

无法加载作为词法分析器或解析器

Can't load <grammarName> as lexer or parser

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

I would appreciate it if you could help me know the problem and how to solve it.

PS 没关系,但您可能会看到我正在处理的代码 这里.

P.S. It shouldn't matter, but you may see the code I am working on here.

推荐答案

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

This error message is an indication that TestRig (that the grun alias uses), can’t find the Parser (or Lexer) class in your classpath. If you’ve placed your generated Parser in a package, you may need to take the package name into account, but the main thing is that the generated (and compiled) class is in your classpath.

此外.. TestRig 将 grammarName 和一个 startRule 作为参数,并期望您的输入来自 stdin.

Also.. TestRig takes the grammarName AND a startRule as parameters, and expects your input to come from stdin.

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

I cloned your repo to take a closer look at your issue.

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

The immediate issue for why grun is giving you this issue is that you specified your target language in the grammar file (looks like I need to retract that comment about it not being anything in your grammar). By specifying python as the target language in the grammar, you didn't generate the *.java classes that the TestRig class (used by the grun alias) needed to execute.

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

I removed the target language option from the grammar and was able to run the grun command against your sample input. To get it to parse correctly, I took the liberty of modifying several things in your grammar:

  • 删除了目标语言(通常最好在 antlr 命令行上指定目标语言,以便语法保持与语言无关(如果您想使用 TestRig/grun 实用程序进行测试,这也是必不可少的,因为您将需要 Java 目标)).
  • SectionName 词法规则更改为 section 解析器规则(带有标记的替代品.拥有像 'Body ' Integer 这样的词法规则会给你一个带有 body 关键字和整数的标记,然后您必须稍后将其分开(它还强制正文"和整数之间只有一个空格).
  • NewLine 标记设置为 ->跳过(这对我来说有点假设性,但不跳过 NewLine 将需要修改更多解析规则以指定所有 NewLine 是有效标记的位置.)
  • 删除了 StatementEnd 词法分析器规则,因为我 skip ed NewLine 标记
  • IntegerFloat 重新设计为两个不同的标记,以便我可以在部分使用Integer 标记 解析器规则.
  • 为了让这个骨架能够处理您的样本输入,还进行了一些细微的调整.
  • Removed the target language (It's generally better to specify the target language on the antlr command line so that the grammar remains language agnostic (it's also essential if you want to use the TestRig/grun utility to test things out, since you'll need the Java target)).
  • changed SectionName lexer rule to section parser rule (with labeled alternatives. Having lexer rules like 'Body ' Integer will give you a single token with both the body keyword and the integer, that you'd then have to pull apart later (it also forces there to be only a single space between 'Body' and the integer).
  • set the NewLine token to -> skip (This is a bit more presumptive on my part, but not skipping NewLine will require modifying more parse rule to specify where all NewLine is a valid token.)
  • removed the StatementEnd lexer rule since I skiped the NewLine tokens
  • reworked theInteger and Float stuff to be two different tokens so that I could use the Integer token in the section parser rule.
  • a couple more minor tweaks just to get this skeleton to handle your sample input.

我使用的结果语法是:

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>)

这篇关于在通过 HomeBrew 安装的 macOS 上设置 ANTLR 的 CLASSPATH的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆