使用pegjs解析java程式碼
使用pegjs解析java程式碼
pegjs是什麼
pegjs是peg文法的一種實現,peg文法是一種解析表示式文法,其具體的解析公式和常用的正規表示式很像,需要注意的是peg不允許解析存在二義性。
pegjs官網 https://pegjs.org/
pegjs的作用
在正則匹配不能實現或困難時可以選擇pegjs來處理解析,如sql語句的解析,在構造dsl時編寫自定義規則也非常方便。
pegjs的簡單應用
1.這裡以一段java程式碼的解析為例,準備一段需要解析的java程式碼
class Test {
@tag(1)
@label("名字")
String name;
@tag(2)
@label("性別 0-男 1-女")
Int sex;
}
2.定義根節點,包含了型別、版本和程式碼塊陣列,使用*號表示多個
CodeBlock = blocks:IdlBlock* {
return {
type: 'javaSchema',
version: '1.0.0',
blocks
}
}
3.使用_表示空白符,匹配class關鍵字,使用Identifier這條規則匹配類名並賦值給className後返回,
_ '{' children:Children* '}'
解析空白符後兩個花括號中間的子節點
IdlBlock =
_ 'class'
_ className:Identifier
_ '{' children:Children* '}'
_ {
return {
className,
children
}
}
_ "whitespace" = [ \t\r\n]*
Identifier = $([a-zA-Z_])+
4.在子節點中解析變數
Children =
_ variable:Variable';'
_ {
return {
variable
}
}
5.定義變數解析規則
Variable =
_ tag:Tag?
_ label:Label?
_ type:DataType?
_ name:Identifier?
_ {
return {
tag,
label,
type,
name
}
}
6.解析@tag(1)
並返回其中的引數
Tag = '@tag('tagColumn:TagColumn')' {
return tagColumn
}
TagColumn = $([0-9])*
7.解析@label("名字")
並返回引數中的描述資訊
Label = '@label("'labelColumn:LabelColumn'")' {
return labelColumn
}
LabelColumn = $([^\r\n\t\"\)])*
8.解析變數的型別,這裡僅定義了程式碼塊中用到的兩種型別,也可以擴充套件更多型別
DataType = 'String' / 'Int'
完整的例項
CodeBlock = blocks:IdlBlock* {
return {
type: 'javaSchema',
version: '1.0.0',
blocks
}
}
IdlBlock =
_ 'class'
_ className:Identifier
_ '{' children:Children* '}'
_ {
return {
className,
children
}
}
_ "whitespace" = [ \t\r\n]*
Identifier = $([a-zA-Z_])+
Children =
_ variable:Variable';'
_ {
return {
variable
}
}
Variable =
_ tag:Tag?
_ label:Label?
_ type:DataType?
_ name:Identifier?
_ {
return {
tag,
label,
type,
name
}
}
Tag = '@tag('tagColumn:TagColumn')' {
return tagColumn
}
TagColumn = $([0-9])*
Label = '@label("'labelColumn:LabelColumn'")' {
return labelColumn
}
LabelColumn = $([^\r\n\t\"\)])*
DataType = 'String' / 'Int'
解析結果
{
"type": "javaSchema",
"version": "1.0.0",
"blocks": [
{
"className": "Test",
"children": [
{
"variable": {
"tag": "1",
"label": "名字",
"type": "String",
"name": "name"
}
},
{
"variable": {
"tag": "2",
"label": "性別 0-男 1-女",
"type": "Int",
"name": "sex"
}
}
]
}
]
}
上面的規則可以直接在pegjs官網的網頁版中驗證,pegjs也提供了npm包,pegjs的js api比較簡單可以參考pegjs官方文件
相關文章
- 使用java程式碼操作redisJavaRedis
- 幾行程式碼搞定java生成解析二維碼功能行程Java
- 如何使用 ABAP 程式碼解析 XML 檔案XML
- 使用acorn對JavaScript程式碼進行解析。JavaScript
- 使用Java程式碼配置MyBatis GeneratorJavaMyBatis
- Java程式碼工具EasyCode使用Java
- Java 中使用動態程式碼Java
- Java實現人民幣大寫程式碼解析Java
- 使用註解配置、使用java程式碼配置Java
- Java——HashMap原始碼解析JavaHashMap原始碼
- Java——ArrayList原始碼解析Java原始碼
- Java WeakHashMap 原始碼解析JavaHashMap原始碼
- Java TreeMap 原始碼解析Java原始碼
- java使用sax解析xmlJavaXML
- Kafka程式碼解析Kafka
- ERNIE程式碼解析
- Java 18 新特性:使用Java程式碼啟動jwebserverJavaWebServer
- Java——LinkedHashMap原始碼解析JavaHashMap原始碼
- 微信小程式掃碼解析小程式碼微信小程式
- 使用 Java 解析XML檔案JavaXML
- Java Timer原始碼解析(定時器原始碼解析)Java原始碼定時器
- Java集合框架之 Java HashMap 原始碼解析Java框架HashMap原始碼
- 幽默:過度使用Lambda的Java程式碼Java
- HashMap原始碼解析(java1.8.0)HashMap原始碼Java
- Java集合之Hashtable原始碼解析Java原始碼
- Java 集合Hashtable原始碼深入解析Java原始碼
- Java集合之ArrayList原始碼解析Java原始碼
- Java集合Stack原始碼深入解析Java原始碼
- JAVA集合:LinkedList原始碼解析Java原始碼
- Java集合之HashMap原始碼解析JavaHashMap原始碼
- Java1.8-ArrayList原始碼解析Java原始碼
- Java集合類:AbstractCollection原始碼解析Java原始碼
- 【Java利器】JDK5-9新特性解析+程式碼 - JDK7JavaJDK
- Java 併發程式設計解析Java程式設計
- Java使用程式碼模擬高併發操作Java
- Effective Java -- 使用try-with-resources優化程式碼Java優化
- 深度解析:清理爛程式碼
- EP01程式碼解析