文章目錄
- 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 的核心結構解析,可根據實際需求進一步擴展復雜環境(如表格、圖表等)。