按照BNF语法重新写就的JsonAnalyzer2
本例源码:https://files.cnblogs.com/files/heyang78/JsonAnalyzer2-20200525-01.rar
自从按BNF重新书写了算术表达式解析(https://www.cnblogs.com/heyang78/p/12951492.html)后,深感这种方式精简,于是又用它重写了Json解析器.
此解析器通过的测试用例在:https://www.cnblogs.com/heyang78/p/12955028.html
新Json解析器核心类:
package com.heyang; import java.util.List; public class TreeBuilder { private Node root; private List<Token> tokens; private int tokenIdx; public TreeBuilder(List<Token> tokens) throws Exception{ this.tokens=tokens; this.tokenIdx=0; root=new Node(null,Node.Type_List); parse_object(root); } private void parse_object(Node parent) throws Exception{ Token token; token=fetchToken(); if(token.getType()!=Token.TYPE_OPEN_BRACE) { throw new Exception("Missing '{'"); } for(;;) { token=fetchToken(); if(token.getType()!=Token.TYPE_TEXT) { break; } String key=token.getText(); token=fetchToken(); if(token.getType()!=Token.TYPE_COLON) { throw new Exception("Should be ':' after key:"+key); } token=fetchToken(); if(token.getType()==Token.TYPE_TEXT) { String value=token.getText(); parent.addChild(new Node(key,value)); }else if(token.getType()==Token.TYPE_OPEN_BRACE){ Node node=new Node(key,Node.Type_List); parent.addChild(node); returnToken(); parse_object(node); }else if(token.getType()==Token.TYPE_OPEN_BRACKET) { Node node=new Node(key,Node.Type_Array); parse_array(node); parent.addChild(node); }else { throw new Exception("value should be string/object/array but not."); } token=fetchToken(); if(token.getType()==Token.TYPE_COMMA) { continue; }else { returnToken(); break; } } token=fetchToken(); if(token.getType()!=Token.TYPE_CLOSE_BRACE) { throw new Exception("Missing '}'"); } } private void parse_array(Node parent) throws Exception { Token token; for(;;) { token=fetchToken(); if(token.getType()==Token.TYPE_TEXT) { String value=token.getText(); Node node=new Node(null,value); parent.addChild(node); }else if(token.getType()==Token.TYPE_OPEN_BRACE) { Node node=new Node(null,Node.Type_List); parent.addChild(node); returnToken(); parse_object(node); }else { returnToken(); } token=fetchToken(); if(token.getType()==Token.TYPE_COMMA) { continue; }else { returnToken(); break; } } token=fetchToken(); if(token.getType()!=Token.TYPE_CLOSE_BRACKET) { throw new Exception("Missing ']'"); } } private Token fetchToken() { if(tokenIdx>=tokens.size()) { return null; }else { Token t=tokens.get(tokenIdx); tokenIdx++; return t; } } private void returnToken() { if(tokenIdx>0) { tokenIdx--; } } public Node getRoot() { return root; } }
该解析器目前有bug,即;,{}[]出现在值的字符串中时,会导致解析异常.这个需要调整Lexer,此事留待日后完成.
--2020年5月25日--
分类:
Java.Compiler
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)