文章目录
- ANTLR4基本使用
- **1. 安装 Java 运行时(必需)**
- **2. 安装 ANTLR4 命令行工具**
- **方法一:通过包管理器(推荐)**
- **macOS/Linux (Homebrew)**
- **Windows (Chocolatey)**
- **方法二:手动安装(通用)**
- **3. 验证安装**
- **4. 配置环境变量(可选)**
- **macOS/Linux**
- **Windows**
- **5. 使用示例**
- **(1) 生成解析器**
- **(2) 测试语法树**
- **6. 开发工具集成**
- **Visual Studio Code**
- **IntelliJ IDEA**
- **常见问题解决**
- YAML
- 1. YAML 语法文件 (`YAML.g4`)
- 2. 语法说明
- 3. 生成解析器
- 4. 解析树可视化
- 5. 支持的 YAML 特性
- 6. 扩展建议
- 7. 完整解析流程
- JSON
- 1. JSON 语法文件 (`JSON.g4`)
- 2. 语法说明
- 3. 生成解析器
- 4. 解析树可视化
- 5. 支持的 JSON 特性
- 6. 扩展建议
- 7. 性能优化
- Latex
- 1. LaTeX 语法文件 (`LaTeX.g4`)
- 2. 语法树结构说明
- 3. 解析示例
- 输入 LaTeX 文件 (`example.tex`):
- Java 解析代码:
- 生成的解析树结构:
- 4. 关键特性支持
- 5. 扩展建议
- 6. 典型应用场景
最近接触到数学公式的解析,然后和ANTLR4进行了一场遭遇战。
以下是使用 ANTLR4 解析 YAML 文件的完整语法文件 (YAML.g4
) 和解析示例:
ANTLR4基本使用
以下是安装 ANTLR4 命令行工具的详细步骤,适用于主流操作系统:
1. 安装 Java 运行时(必需)
ANTLR4 是基于 Java 的工具,需先安装 Java 11+:
# 检查是否已安装 Java
java -version
- 如果未安装,从 Oracle JDK 或 OpenJDK 下载。
2. 安装 ANTLR4 命令行工具
方法一:通过包管理器(推荐)
macOS/Linux (Homebrew)
brew install antlr
Windows (Chocolatey)
choco install antlr4
方法二:手动安装(通用)
-
下载最新版 ANTLR4 JAR 文件:
curl -O https://www.antlr.org/download/antlr-4.12.0-complete.jar
替换
4.12.0
为官网最新版本号。 -
将 JAR 文件移动到固定目录(如
~/lib/antlr
):mkdir -p ~/lib/antlr mv antlr-4.12.0-complete.jar ~/lib/antlr/
-
添加别名到 Shell 配置文件(
.bashrc
/.zshrc
/.bash_profile
):# ANTLR4 别名 alias antlr4='java -jar ~/lib/antlr/antlr-4.12.0-complete.jar' alias grun='java org.antlr.v4.gui.TestRig'
然后执行:
source ~/.bashrc # 或对应配置文件
3. 验证安装
antlr4
如果看到以下输出,表示安装成功:
ANTLR Parser Generator Version 4.12.0
...
4. 配置环境变量(可选)
若不想用别名,可将 ANTLR4 加入 PATH
:
macOS/Linux
export CLASSPATH=".:~/lib/antlr/antlr-4.12.0-complete.jar:$CLASSPATH"
export PATH="$PATH:~/lib/antlr"
Windows
- 右键“此电脑” → 属性 → 高级系统设置 → 环境变量
- 在
PATH
中添加 ANTLR4 JAR 所在目录 - 新建
CLASSPATH
变量,值为.;C:\path\to\antlr-4.12.0-complete.jar
5. 使用示例
(1) 生成解析器
antlr4 YourGrammar.g4 # 生成词法/语法分析器
javac *.java # 编译生成的 Java 文件
(2) 测试语法树
grun YourGrammar ruleName -gui # 可视化解析树
输入文本后按 Ctrl+D
(macOS/Linux) 或 Ctrl+Z
(Windows) 结束输入。
6. 开发工具集成
Visual Studio Code
- 安装扩展:
- ANTLR4 Grammar Syntax Support
- 右键
.g4
文件 → “Generate ANTLR Code”
IntelliJ IDEA
- 安装插件:
- ANTLR v4 grammar plugin (内置)
- 右键
.g4
文件 → “Generate ANTLR Recognizer”
常见问题解决
-
antlr4: command not found
检查别名或环境变量配置是否正确。 -
Java 版本不兼容
确保使用 Java 11+:java -version
-
无法生成代码
检查语法文件是否有错误,或尝试手动指定输出目录:antlr4 -o ./output YourGrammar.g4
通过以上步骤,您可以在任何主流操作系统上安装并运行 ANTLR4 命令行工具。如需更高级的功能(如自定义 Visitor/Listener),可参考 ANTLR4 官方文档。
YAML
1. YAML 语法文件 (YAML.g4
)
grammar YAML;// 语法规则
document: blockMapping?;blockMapping: blockPair+;blockPair: key ':' value;key: SCALAR;value: SCALAR| blockMapping| blockSequence;blockSequence: '-' value ('\n' '-' value)*;// 词法规则
SCALAR: UNQUOTED_SCALAR| SINGLE_QUOTED_SCALAR| DOUBLE_QUOTED_SCALAR;UNQUOTED_SCALAR: [a-zA-Z0-9_\-\.]+;SINGLE_QUOTED_SCALAR: '\'' (~['\n] | '\'\'')* '\'';DOUBLE_QUOTED_SCALAR: '"' (~["\n] | '\\"')* '"';COMMENT: '#' ~[\n]* -> skip;WS: [ \t\r\n]+ -> skip;// 特殊字符处理
COLON : ':' ;
DASH : '-' ;
2. 语法说明
-
文档结构:
- 一个 YAML 文档由可选的
blockMapping
组成 blockMapping
包含多个键值对 (blockPair
)
- 一个 YAML 文档由可选的
-
键值对:
- 键 (
key
) 必须是标量 (SCALAR) - 值 (
value
) 可以是:- 标量
- 嵌套的映射 (
blockMapping
) - 序列 (
blockSequence
)
- 键 (
-
序列:
- 以
-
开头 - 可以包含多行
- 以
-
标量类型:
- 未加引号的 (
UNQUOTED_SCALAR
):字母数字、下划线、连字符、点 - 单引号 (
SINGLE_QUOTED_SCALAR
):支持单引号转义 (''
) - 双引号 (
DOUBLE_QUOTED_SCALAR
):支持反斜杠转义 (\"
)
- 未加引号的 (
-
忽略:
- 注释 (
#
开头) - 空白字符 (空格、制表符、换行)
- 注释 (
3. 生成解析器
- 使用 ANTLR4 工具生成代码:
antlr4 YAML.g4
javac YAML*.java
- 使用生成的解析器 (Java 示例):
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;public class YAMLParserExample {public static void main(String[] args) throws Exception {String yaml = """name: John Doeage: 30address:street: 123 Main Stcity: Anytownhobbies:- hiking- reading""";CharStream input = CharStreams.fromString(yaml);YAMLLexer lexer = new YAMLLexer(input);CommonTokenStream tokens = new CommonTokenStream(lexer);YAMLParser parser = new YAMLParser(tokens);ParseTree tree = parser.document();// 打印解析树System.out.println(tree.toStringTree(parser));}
}
4. 解析树可视化
使用 ANTLR 的 grun
工具查看解析树:
grun YAML document -gui <<EOF
name: John Doe
age: 30
EOF
5. 支持的 YAML 特性
特性 | 是否支持 | 示例 |
---|---|---|
键值对 | ✅ | key: value |
嵌套映射 | ✅ | parent: {child: value} |
列表 | ✅ | - item1\n- item2 |
多行字符串 | ❌ | `text: |
锚点与引用 | ❌ | &anchor\n key: value |
复杂数据类型 | ❌ | !!timestamp 2023-01-01 |
6. 扩展建议
-
支持多行字符串:
添加MULTILINE_SCALAR
规则:MULTILINE_SCALAR: '|' '\n' (' ' | '\t')* ~[\n]* ('\n' (' ' | '\t')* ~[\n]*)*;
-
支持类型标签:
value: SCALAR| tag SCALAR| blockMapping| blockSequence;tag : '!!' [a-zA-Z]+ ;
-
错误处理:
添加error
规则捕获非法输入:ERROR_CHAR : . ;
7. 完整解析流程
graph TDA[YAML 输入] --> B[词法分析 (Lexer)]B --> C[Token 流]C --> D[语法分析 (Parser)]D --> E[解析树]E --> F[遍历树 (Visitor/Listener)]
这个语法文件提供了 YAML 的核心功能解析,可根据实际需求进一步扩展。
JSON
以下是适用于 ANTLR4 的 JSON 语法文件 (JSON.g4
),完整支持 JSON 标准(RFC 8259):
1. JSON 语法文件 (JSON.g4
)
grammar JSON;// 语法规则
json: value;value: object| array| STRING| NUMBER| 'true'| 'false'| 'null';object: '{' pair (',' pair)* '}'| '{' '}';pair: STRING ':' value;array: '[' value (',' value)* ']'| '[' ']';// 词法规则
STRING: '"' (ESC | SAFE_CHAR)* '"';fragment ESC: '\\' (["\\/bfnrt] | UNICODE);fragment UNICODE: 'u' HEX HEX HEX HEX;fragment HEX: [0-9a-fA-F];fragment SAFE_CHAR: ~["\\\u0000-\u001F];NUMBER: '-'? INT ('.' [0-9]+)? EXP?;fragment INT: '0' | [1-9] [0-9]*;fragment EXP: [Ee] [+-]? [0-9]+;WS: [ \t\n\r]+ -> skip;
2. 语法说明
-
结构定义:
json
: 根规则,表示一个 JSON 文档value
: 可以是对象、数组、字符串、数字、布尔值或null
object
: 键值对集合(如{"key": "value"}
)array
: 值列表(如[1, "a", true]
)
-
词法规则:
STRING
: 支持转义字符(\n
,\uXXXX
等)NUMBER
: 支持整数、浮点数和科学计数法WS
: 跳过空白字符
-
严格校验:
- 字符串必须用双引号(
"
)包裹 - 不允许尾随逗号(如
[1, 2,]
会报错)
- 字符串必须用双引号(
3. 生成解析器
-
生成 Java 代码:
antlr4 JSON.g4 javac JSON*.java
-
测试解析(Java 示例):
import org.antlr.v4.runtime.*; import org.antlr.v4.runtime.tree.*;public class JSONParserExample {public static void main(String[] args) throws Exception {String json = """{"name": "Alice","age": 30,"scores": [90, 85, 95]}""";CharStream input = CharStreams.fromString(json);JSONLexer lexer = new JSONLexer(input);CommonTokenStream tokens = new CommonTokenStream(lexer);JSONParser parser = new JSONParser(tokens);ParseTree tree = parser.json(); // 从根规则开始解析System.out.println(tree.toStringTree(parser));} }
4. 解析树可视化
使用 ANTLR 的 grun
工具查看解析树:
grun JSON json -gui <<EOF
{"key": "value"}
EOF
会显示如下结构:
(json (value (object { (pair "key" : (value "value")) })))
5. 支持的 JSON 特性
特性 | 示例 | 是否支持 |
---|---|---|
对象 | {"key": "value"} | ✅ |
数组 | [1, "a", true] | ✅ |
嵌套结构 | {"a": {"b": [1, 2]}} | ✅ |
字符串转义 | "Line\nBreak" | ✅ |
Unicode 字符 | "\u03B1" (α) | ✅ |
科学计数法数字 | 1.23e-4 | ✅ |
布尔值/null | true , false , null | ✅ |
尾随逗号 | {"a": 1,} | ❌ |
单引号字符串 | {'key': 'value'} | ❌ |
6. 扩展建议
-
支持注释(非标准 JSON):
COMMENT: '/*' .*? '*/' -> skip| '//' ~[\n]* -> skip;
-
宽松模式(允许尾随逗号):
object: '{' pair (',' pair)* ','? '}'| '{' '}';
-
自定义错误处理:
parser.addErrorListener(new BaseErrorListener() {@Overridepublic void syntaxError(...) {throw new RuntimeException("Syntax error at line " + line + ":" + charPositionInLine + " - " + msg);} });
7. 性能优化
- 预编译解析器:在多次解析时复用
Lexer
/Parser
实例 - 关闭冗余功能:禁用
ANTLRErrorListener
提升速度lexer.removeErrorListeners(); parser.removeErrorListeners();
此语法文件完全兼容标准 JSON,可直接用于构建 JSON 解析器、验证器或转换工具。如需处理非标准 JSON(如带注释的配置文件),按需扩展即可。
Latex
以下是适用于 ANTLR4 的 LaTeX 语法文件 (LaTeX.g4
),定义了包含 documentclass
、section
、item
、task
等常见标记的语法树结构:
1. LaTeX 语法文件 (LaTeX.g4
)
grammar LaTeX;// 语法规则
document: preamble? (section | item | task | textContent)*;preamble: '\\documentclass' '{' ID '}' ('[' options ']')?;section: '\\section' '{' textContent '}' (subsection)?;subsection: '\\subsection' '{' textContent '}';item: '\\item' (textContent | itemize | enumerate);itemize: '\\begin{itemize}' item* '\\end{itemize}';enumerate: '\\begin{enumerate}' item* '\\end{enumerate}';task: '\\task' '{' textContent '}' ('\\solution' '{' textContent '}')?;textContent: (TEXT | COMMAND | MATH)+;// 词法规则
COMMAND: '\\' [a-zA-Z]+;MATH: '$' .*? '$';ID: [a-zA-Z]+;TEXT: ~[\\{}[\]]+;OPTION_SEP: ',';LBRACE : '{';
RBRACE : '}';
LBRACK : '[';
RBRACK : ']';WS: [ \t\r\n]+ -> skip;// 复合规则
options: ID (OPTION_SEP ID)*;
2. 语法树结构说明
-
文档结构:
-
节点类型:
preamble
:\documentclass
声明section
/subsection
: 章节标题item
: 列表项(可嵌套在itemize
或enumerate
中)task
: 自定义任务环境(带可选的\solution
)textContent
: 文本、命令或数学公式的混合内容
-
嵌套规则:
- 列表可以嵌套 (
item
包含itemize
/enumerate
) textContent
可以包含任意文本和命令
- 列表可以嵌套 (
3. 解析示例
输入 LaTeX 文件 (example.tex
):
\documentclass{article}
\section{Introduction}
This is a \textbf{test}.
\begin{itemize}\item First point\item Second point with math: $E=mc^2$
\end{itemize}
\task{Solve the equation}{ \solution{ $x=1$ } }
Java 解析代码:
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;public class LaTeXParserExample {public static void main(String[] args) throws Exception {CharStream input = CharStreams.fromFileName("example.tex");LaTeXLexer lexer = new LaTeXLexer(input);CommonTokenStream tokens = new CommonTokenStream(lexer);LaTeXParser parser = new LaTeXParser(tokens);ParseTree tree = parser.document();// 打印解析树System.out.println(tree.toStringTree(parser));// 使用Visitor遍历new LaTeXBaseVisitor<Void>() {@Overridepublic Void visitSection(LaTeXParser.SectionContext ctx) {System.out.println("Section: " + ctx.textContent().getText());return super.visitSection(ctx);}}.visit(tree);}
}
生成的解析树结构:
(document (preamble \documentclass { article }) (section \section { Introduction } (textContent This is a \textbf { test })) (itemize (item \item (textContent First point)) (item \item (textContent Second point with math: $E=mc^2$))) (task \task { Solve the equation } (solution \solution { $x=1$ })))
4. 关键特性支持
LaTeX 结构 | 是否支持 | 示例 |
---|---|---|
文档类声明 | ✅ | \documentclass{article} |
章节标题 | ✅ | \section{Introduction} |
无序列表 | ✅ | \itemize \item ... |
有序列表 | ✅ | \enumerate \item ... |
自定义命令 | ✅ | \textbf{text} |
数学公式 | ✅ | $E=mc^2$ |
自定义环境 | ✅ | \task{...}\solution{...} |
可选参数 | ✅ | \documentclass[12pt]{...} |
嵌套结构 | ✅ | 列表中的列表 |
5. 扩展建议
-
支持更多环境:
figure: '\\begin{figure}' ('[' options ']')? content '\\end{figure}';
-
完善数学公式:
MATH: '$' .*? '$'| '\\[' .*? '\\]';
-
错误恢复:
添加error
规则:UNKNOWN_CMD: '\\' ~[a-zA-Z] -> skip;
-
注释处理:
COMMENT: '%' ~[\n]* -> skip;
6. 典型应用场景
-
LaTeX 文档分析:
- 提取所有章节标题
- 统计数学公式数量
-
自动化批改系统:
- 解析
\task
和\solution
环境 - 对比学生答案与标准解
- 解析
-
文档转换:
- 将 LaTeX 列表转为 Markdown
- 提取文档结构生成目录
这个语法文件提供了 LaTeX 的核心结构解析,可根据实际需求进一步扩展复杂环境(如表格、图表等)。