在通过 HomeBrew 安装的 macOS 上设置 ANTLR 的 CLASSPATH [英] setting up ANTLR's CLASSPATH on macOS installed via HomeBrew
问题描述
根据这个问题,我通过 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
edNewLine
标记 - 将
Integer
和Float
重新设计为两个不同的标记,以便我可以在部分使用
解析器规则.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 tosection
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 skippingNewLine
will require modifying more parse rule to specify where allNewLine
is a valid token.) - removed the
StatementEnd
lexer rule since Iskip
ed theNewLine
tokens - reworked the
Integer
andFloat
stuff to be two different tokens so that I could use theInteger
token in thesection
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屋!