在通过 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 将 grammarName
和 startRule
作为参数,并期望您的输入来自标准输入。
我克隆了您的存储库以仔细查看您的问题。
为什么 g运行 给你这个问题的直接问题是你在语法文件中指定了你的目标语言(看来我需要收回关于它在你的语法中没有任何内容的评论) .通过在语法中指定 python 作为目标语言,您不会生成 TestRig
class(由grun
别名) 需要执行。
我从语法中删除了目标语言选项,并且能够 运行 g运行 命令针对您的示例输入。为了让它正确解析,我冒昧地修改了您语法中的几处内容:
- 删除了目标语言(通常最好在 antlr 命令行上指定目标语言,这样语法仍然与语言无关(如果您想使用 TestRig/grun 实用程序进行测试,这也是必不可少的, 因为你需要 Java 目标)).
- 将
SectionName
词法分析器规则更改为 section
解析器规则(带有标记的替代方案。拥有像 'Body ' Integer
这样的词法分析器规则将为您提供一个包含 body 关键字和整数的标记,然后你必须稍后分开(它也迫使 'Body' 和整数之间只有一个 space)。
- 将
NewLine
标记设置为 -> skip
(这对我来说有点假设,但不跳过 NewLine
将需要修改更多解析规则以指定所有 NewLine
是一个有效的标记。)
- 删除了
StatementEnd
词法分析器规则,因为我 skip
编辑了 NewLine
标记
- 将
Integer
和 Float
东西改成了两个不同的标记,这样我就可以在 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>)
在
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 将 grammarName
和 startRule
作为参数,并期望您的输入来自标准输入。
我克隆了您的存储库以仔细查看您的问题。
为什么 g运行 给你这个问题的直接问题是你在语法文件中指定了你的目标语言(看来我需要收回关于它在你的语法中没有任何内容的评论) .通过在语法中指定 python 作为目标语言,您不会生成 TestRig
class(由grun
别名) 需要执行。
我从语法中删除了目标语言选项,并且能够 运行 g运行 命令针对您的示例输入。为了让它正确解析,我冒昧地修改了您语法中的几处内容:
- 删除了目标语言(通常最好在 antlr 命令行上指定目标语言,这样语法仍然与语言无关(如果您想使用 TestRig/grun 实用程序进行测试,这也是必不可少的, 因为你需要 Java 目标)).
- 将
SectionName
词法分析器规则更改为section
解析器规则(带有标记的替代方案。拥有像'Body ' Integer
这样的词法分析器规则将为您提供一个包含 body 关键字和整数的标记,然后你必须稍后分开(它也迫使 'Body' 和整数之间只有一个 space)。 - 将
NewLine
标记设置为-> skip
(这对我来说有点假设,但不跳过NewLine
将需要修改更多解析规则以指定所有NewLine
是一个有效的标记。) - 删除了
StatementEnd
词法分析器规则,因为我skip
编辑了NewLine
标记 - 将
Integer
和Float
东西改成了两个不同的标记,这样我就可以在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>)