- 浏览: 1700362 次
- 性别:
- 来自: 杭州699号
文章分类
最新评论
-
莫莫摸:
为什么不用dubbo
RCP数据传输模型回顾 -
大胡子爸爸:
String, Class 都实现了Serializable接 ...
RPC框架几行代码就够了 -
lss598018587:
谢谢大神分享,比起新手看复杂的dubbo框架还不如看大神的这一 ...
RPC框架几行代码就够了 -
15606915740:
你好,请问一下。<dubbo:consumer filt ...
Dubbo文档 -
joqk12345:
...
一些设计上的基本常识
在设计MeteorTL(http://www.meteortl.org)模板引擎时,语法树的解析用到了有限状态自动机,这里稍讲一下。
由于将归约算法滞后单独处理(便于测试),这里只实现有限状态自动机,实现序列化分割。
如果后期实现XSLT解析,可能会改为下推自动机实现。
主控程序:
辅助SPI接口及类:
常用实现:
下面是Meteor模板alpha0.2.2版的语法解析:
指令解析:
由于将归约算法滞后单独处理(便于测试),这里只实现有限状态自动机,实现序列化分割。
如果后期实现XSLT解析,可能会改为下推自动机实现。
主控程序:
package org.meteortl.core.engine.parser.automata; import org.meteortl.core.util.Assert; /** * * Deterministic Finite state Automata(DFA)实现 * * @author liangfei0201@163.com * */ public class StateAutomata { // 状态图 private StateMap stateMap; // 输入字符类型识别器 private TypeResolver typeResolver; public StateAutomata(StateMap stateMap, TypeResolver typeResolver) { this.stateMap = stateMap; this.typeResolver = typeResolver; } public void scan(CharProvider charProvider, TokenReceiver tokenReceiver) { try { int state = StateMap.BEGIN; // 当前状态 int row = 0; // 所解释的char所在行 int column = 0; // 所解释的char所在列 StringBuffer buffer = new StringBuffer(); // 缓存 int bufferRow = 0; // 缓存开始char所在行 int bufferColumn = 0; // 缓存开始char所在列 while (charProvider.hasNextChar()) { char ch = charProvider.nextChar(); // 字符输入带 if (ch == '\n') { // 记录位置 row ++; column = 0; } else { column ++; } if (buffer.length() == 0) { // 记录缓存位置 bufferRow = row; bufferColumn = column; } buffer.append(ch); // 将内容加入缓存 int type = typeResolver.getType(ch, buffer.toString()); // 获取字符类型 state = stateMap.getNextState(state, type); // 从状态机图中取下一状态 Assert.assertFalse(state == StateMap.ERROR, "表达式串语法错误, 字符:" + ch + " 位置:(" + row + "," + column + ")"); if (state == StateMap.END) { // 正常结束 tokenReceiver.receive(new Token(buffer.toString(), bufferRow, bufferColumn, row, column)); // 接收缓存中的内容 buffer.setLength(0); // 清空缓存 state = StateMap.BEGIN; // 回归到初始状态 } else if (state == StateMap.BREAK) { // 中断型结束 if (buffer.length() > 1) { // 接收缓存中的内容,不包含最后一个字符 tokenReceiver.receive(new Token(buffer.toString().substring(0, buffer.length() - 1), bufferRow, bufferColumn, row, column)); } buffer.setLength(0); // 清空缓存 buffer.append(ch); // 保留最后一个字符 state = stateMap.getNextState(StateMap.BEGIN, type); // 回归到初始状态,并立即开始 } } if (buffer.length() > 0) { tokenReceiver.receive(new Token(buffer.toString(), bufferRow, bufferColumn, row, column)); // 接收最后缓存中的内容 } } catch (Exception e) { e.printStackTrace(); } } }
辅助SPI接口及类:
package org.meteortl.core.engine.parser.automata; /** * * 状态图 * @author liangfei0201@163.com * */ public interface StateMap { public static final int BEGIN = 0; // 开始状态 public static final int END = -1; // 结束状态(包含最后一个字符) public static final int BREAK = -2; // 中止状态(不包含最后一个字符) public static final int ERROR = -3; // 错误状态 /** * 获取下一状态 * @param 当前状态 * @param 输入字符类型 * @return */ public int getNextState(int state, int type); }
package org.meteortl.core.engine.parser.automata; /** * 输入子带供应器 * (迭代子模式) * @author liangfei0201@163.com * */ public interface CharProvider { /** * 判定是否还有下一字符 * @return */ public boolean hasNextChar(); /** * 取下一字符 * @return */ public char nextChar(); }
package org.meteortl.core.engine.parser.automata; /** * 输出片断信息 * (不变量-线程安全) * @author liangfei0201@163.com * */ public final class Token { private String message; private int beginRow; private int beginColumn; private int endRow; private int endColumn; public Token(String message, int beginRow, int beginColumn, int endRow, int endColumn) { this.message = message; this.beginRow = beginRow; this.beginColumn = beginColumn; this.endRow = endRow; this.endColumn = endColumn; } /** * 片断开始行数 * @return int */ public int getBeginRow() { return beginRow; } /** * 片断开始列数 * @return int */ public int getBeginColumn() { return beginColumn; } /** * 片断结束行数 * @return int */ public int getEndRow() { return endRow; } /** * 片断结束列数 * @return int */ public int getEndColumn() { return endColumn; } /** * 片断内容信息 * @return int */ public String getMessage() { return message; } private String toString; public String toString() { if (toString == null) { StringBuffer buffer = new StringBuffer(); buffer.append(message); buffer.append("("); buffer.append(beginRow); buffer.append(","); buffer.append(beginColumn); buffer.append("-"); buffer.append(endRow); buffer.append(","); buffer.append(endColumn); buffer.append(")"); toString = buffer.toString(); } return toString; } }
package org.meteortl.core.engine.parser.automata; /** * * 片断接收器 * @author liangfei0201@163.com * */ public interface TokenReceiver { /** * 接收片断 * @param 片断 */ public void receive(Token token); }
package org.meteortl.core.engine.parser.automata; /** * 输入char的类型判定 * @author liangfei0201@163.com * */ public interface TypeResolver { /** * 获取输入字节的类型 * @param 输入的字节 * @param 当前缓存中的内容 * @return 字节的类型 */ public int getType(char ch, String buffer); }
常用实现:
package org.meteortl.core.engine.parser.automata; /** * 使用数据作为状态图 * @author liangfei0201@163.com * */ public class ArrayStateMap implements StateMap { private int[][] states; public ArrayStateMap(int[][] states) { this.states = states; } public int getNextState(int state, int type) { return states[state][type]; } }
package org.meteortl.core.engine.parser.automata; import java.util.NoSuchElementException; /** * 使用字符串作为输入子带 * @author liangfei0201@163.com * */ public class StringCharProvider implements CharProvider { private String source; private int index; public StringCharProvider(String source) { this.source = source; this.index = 0; } public boolean hasNextChar() { if (source == null || source.length() == 0) { return false; } return index < source.length(); } public char nextChar() { if (! hasNextChar()) { throw new NoSuchElementException(); } return source.charAt(index ++); } }
package org.meteortl.core.engine.parser.automata; import java.io.IOException; import java.io.Reader; import java.util.NoSuchElementException; /** * 使用读取器作为子带供应 * @author liangfei0201@163.com * */ public class ReaderCharProvider implements CharProvider { private Reader reader; private int next; public ReaderCharProvider(Reader reader) { this.reader = reader; try { next = reader.read(); } catch (IOException e) { e.printStackTrace(); next = -1; } } public boolean hasNextChar() { return next != -1; } public char nextChar() { if (! hasNextChar()) { throw new NoSuchElementException(); } char ch = (char)next; try { next = reader.read(); } catch (IOException e) { e.printStackTrace(); next = -1; } return ch; } }
package org.meteortl.core.engine.parser.automata; import java.util.ArrayList; import java.util.List; /** * 将所有输出片断收集成列表 * @author liangfei0201@163.com * */ public class ListTokenReceiver implements TokenReceiver { private List tokens; public ListTokenReceiver() { tokens = new ArrayList(); } public void receive(Token token) { tokens.add(token); } public List getTokens() { return tokens; } }
下面是Meteor模板alpha0.2.2版的语法解析:
指令解析:
package org.meteortl.core.engine.parser.directive; import java.io.Reader; import java.util.List; /** * 指令分解器 * @author liangfei0201@163.com * */ public interface DirectiveTokenizer { /** * 将模板分解成指令片断 * @param Reader - 模板供给者 * @return List<Token> - 指令片断 */ public List tokens(Reader templateProvider); }
package org.meteortl.core.engine.parser.directive; import java.io.Reader; import java.util.List; import org.meteortl.core.engine.parser.Syntax; import org.meteortl.core.engine.parser.automata.ArrayStateMap; import org.meteortl.core.engine.parser.automata.ListTokenReceiver; import org.meteortl.core.engine.parser.automata.ReaderCharProvider; import org.meteortl.core.engine.parser.automata.StateAutomata; import org.meteortl.core.engine.parser.automata.StateMap; import org.meteortl.core.engine.parser.automata.TypeResolver; /** * 使用DFA实现指令分割 * @author liangfei0201@163.com * */ public class DirectiveTokenizerImpl implements DirectiveTokenizer { // 状态机图 private static final int states[][] = { /* 0.空格, 1.反斜杠, 2.@符, 3.字母, 4.{, 5.}, 6.其它符号 */ /* 0.起始 */{ 6, 1, 2, 6, 6, 6, 6 }, /* 1.转义 */{ 6, 6, 6, 6, 6, 6, 6 }, /* 2.指令 */{ 2, StateMap.ERROR, StateMap.ERROR, 3, 5, StateMap.ERROR, StateMap.ERROR }, /* 3.名称 */{ 4, StateMap.ERROR, StateMap.BREAK, 3, 5, StateMap.BREAK, StateMap.BREAK }, /* 4.中间 */{ 4, StateMap.ERROR, StateMap.BREAK, StateMap.BREAK, 5, StateMap.BREAK, StateMap.BREAK }, /* 5.表达 */{ 5, 5, 5, 5, StateMap.ERROR, StateMap.END, 5 }, /* 6.文本 */{ 6, 1, StateMap.BREAK, 6, 6, 6, 6 } }; private StateAutomata stateAutomata; public DirectiveTokenizerImpl(final Syntax syntax) { stateAutomata = new StateAutomata(new ArrayStateMap(states), new TypeResolver() { public int getType(char ch, String buffer) { if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') return 0; if (ch == syntax.getEscape()) return 1; if (ch == syntax.getBegin()) return 2; if ((ch >= '0' && ch <= '9') || ch == '_' || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) return 3; if (ch == syntax.getExpressionBegin()) return 4; if (ch == syntax.getEnd()) return 5; return 6; } }); } public List tokens(Reader templateProvider) { ListTokenReceiver listTokenReceiver = new ListTokenReceiver(); // 接收器 stateAutomata.scan(new ReaderCharProvider(templateProvider), listTokenReceiver); return listTokenReceiver.getTokens(); } }
package org.meteortl.core.engine.parser.expression; import java.util.List; /** * 表达式分解器 * @author liangfei0201@163.com * */ public interface ExpressionTokenizer { /** * 将表达式串分解成表达式片断 * @param String - 表达式串 * @return List<Token> - 表达式片断 */ public List tokens(String expressionText); }
package org.meteortl.core.engine.parser.expression; import java.util.List; import org.meteortl.core.engine.parser.automata.ArrayStateMap; import org.meteortl.core.engine.parser.automata.ListTokenReceiver; import org.meteortl.core.engine.parser.automata.StateAutomata; import org.meteortl.core.engine.parser.automata.StateMap; import org.meteortl.core.engine.parser.automata.StringCharProvider; import org.meteortl.core.engine.parser.automata.TypeResolver; /** * * 使用状态机实现表达式分割 * * @author liangfei0201@163.com * */ public class ExpressionTokenizerImpl implements ExpressionTokenizer { // 状态机图 private static final int states[][] = { /* 0.空格, 1.字母, 2.数字, 3.点, 4.引号, 5.反斜杠, 6.括号, 7.其它符号 */ /* 0.起始 */{ StateMap.BEGIN, 1, 2, 7, 4, StateMap.ERROR, 6, 7}, /* 1.变量 */{ StateMap.BREAK, 1, 1, StateMap.BREAK, StateMap.ERROR, StateMap.ERROR, StateMap.BREAK, StateMap.BREAK}, /* 2.数字 */{ StateMap.BREAK, StateMap.ERROR, 2, 3, StateMap.ERROR, StateMap.ERROR, StateMap.BREAK, StateMap.BREAK}, /* 3.小数 */{ StateMap.BREAK, StateMap.END, 3, StateMap.BREAK, StateMap.ERROR, StateMap.ERROR, StateMap.BREAK, StateMap.BREAK}, /* 4.字符 */{ 4, 4, 4, 4, StateMap.END, 5, 4, 4}, /* 5.转义 */{ 4, 4, 4, 4, 4, 4, 4, 4}, /* 6.括号 */{ StateMap.BREAK, StateMap.BREAK, StateMap.BREAK, StateMap.BREAK, StateMap.BREAK, StateMap.BREAK, StateMap.BREAK, StateMap.BREAK}, /* 7.操作 */{ StateMap.BREAK, StateMap.BREAK, StateMap.BREAK, 7, StateMap.BREAK, StateMap.ERROR, StateMap.BREAK, 7} }; private static final StateAutomata stateAutomata = new StateAutomata(new ArrayStateMap(states), new TypeResolver() { public int getType(char ch, String buffer) { if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') return 0; if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) return 1; if (ch >= '0' && ch <= '9') return 2; // if (ch == '.') return 3; if (ch == '\"' || ch == '\'') return 4; if (ch == '\\') return 5; if (ch == '(' || ch == ')' || ch == '[' || ch == ']') return 6; return 7; } }); public List tokens(String expressionText) { ListTokenReceiver listTokenReceiver = new ListTokenReceiver(); // 接收器 stateAutomata.scan(new StringCharProvider(expressionText), listTokenReceiver); return listTokenReceiver.getTokens(); } }
发表评论
-
以HTTL为例讲讲模块分包&领域模型&扩展框架
2011-10-09 20:08 16741注:该博客内容已加入 ... -
CommonTemplate增加HTML标签版语法外套
2008-09-09 10:33 2972CommonTemplate(http://www.commo ... -
CommonTemplate访问者设计思考
2008-09-03 10:45 1779经过多个版本的调整, CommonTemplate(http: ... -
CommonTemplate发布0.8.6版本
2008-08-26 20:49 1802CommonTemplate发布0.8.6版本 ... -
CommonTemplate发布0.8.5版本
2008-08-04 13:23 1895CommonTemplate发布0.8.5版本(2008-08 ... -
CommonTemplate加入代码生成器
2008-07-21 13:15 2243模板引擎经常被用于做代码生成, 为此, CommonTempl ... -
加入对YAML数据格式的支持
2008-07-01 12:41 4003CommonTemplate(http://www.commo ... -
嵌套注释语法思考
2008-06-29 14:40 4018主流的C/C++/Java/C#等语言,都将注释语法设计成不可 ... -
转:开源协议
2008-06-10 17:23 2228来源:网络 (1)Contrib ... -
CommonTemplate完成查看器Viewer.exe(及安装程序)
2008-06-04 15:12 1874完成查看器初始版本. 实现功能: 双击*.ctl文件, 自动读 ... -
CommonTemplate完成外部构建树或表达式接口
2008-05-31 11:01 1950CommonTemplate: http://www.comm ... -
CommonTemplate异常国际化完成
2008-05-26 11:48 1926周未把一个累活给干了, 就是异常信息的国际化. 总共有220多 ... -
CommonTemplate加入对无穷数的支持.
2008-05-23 11:07 2741用"*"号表示无穷数, 常在下标号中使用, ... -
CommonTemplate导出模板所需变量结构
2008-05-12 18:28 2260在velocity的邮件列表中收到下面的邮件: Simon G ... -
CommonTemplate完成$snatch指令
2008-05-06 09:20 1905CommonTemplate(http://www.commo ... -
关于CTE当前API无法支持从非引擎方式构建模板树
2008-04-28 17:20 1795因隐藏了模板树的实现, 现在CommonTemplate(ht ... -
CommonTemplate完成DEBUG单步调试
2008-04-21 09:56 2533CommonTemplate(http://www.commo ... -
CommonTemplate准备加入$breakpoint指令
2008-04-19 10:30 2207准备在CommonTemplate( http://www.c ... -
很高兴桂林兄加入CommonTemplate的开发
2008-04-05 20:49 2933桂林的blog: http://jasongreen.itey ... -
展开式序列实现
2008-03-31 22:47 2098现在CommonTemplate(http://www.com ...
相关推荐
形式语言与自动机理论--第三章 有限状态自动机-1(第六周).ppt
形式语言与自动机理论--第三章 有限状态自动机-3(第八周).ppt
形式语言与自动机理论--第三章 有限状态自动机-2(第七周).ppt
是形式语言与自动机理论--第三章 有限状态自动机的ppt
"形式语言与自动机:第五讲 有限状态自动机 -正规表达式" 形式语言与自动机是计算机科学中的一门重要课程,本讲主要介绍了有限状态自动机和正规表达式之间的关系。 有限状态自动机(Finite Automaton)是一种计算...
有限状态自动机(Finite State Automaton,简称FSA)是一种计算模型,用于处理具有有限数量状态的系统。在计算机科学中,它常被用来解决模式匹配、正则表达式识别等问题。本篇将深入探讨如何使用Java语言实现有限...
【形式语言与自动机:第五讲 有限状态自动机 -正规表达式】 形式语言与自动机是一门重要的计算机科学理论,主要研究如何描述和处理不同的字符串集合,即语言。有限状态自动机(Finite State Automata, FSA)是这类...
实验目的:利用状态表和有限自动机的运行原理编写和设计程序,判断输入的自动机是DFA还是NFA,如果是NFA,利用子集法将其确定化,然后利用求同法或求异法将所得的DFA最小化。 实现功能:1.建议以文本文件形式来描述...
- 有限状态自动机通常用五元组 `(VT, Q, δ, q0, Qf)` 表示,其中 `VT` 是输入符号集,`Q` 是状态集,`δ` 是状态转换函数,`q0` 是初始状态,`Qf` 是终止状态集。 5. **接受语言**: - 给定的有限状态自动机M,...
### 不确定有限状态自动机的确定化及其原理 #### 实验背景及目的 在理论计算机科学领域中,有限状态自动机是一种重要的模型,用于描述计算系统的行为和特性。按照是否允许多重选择路径,有限状态自动机可分为确定...
在这些领域中,确定有限自动机可以用来识别和解析文本模式。 非确定有限自动机的应用领域包括模式识别、文本分类、信息检索等领域。在这些领域中,非确定有限自动机可以用来识别和分类文本模式。 从理论角度看,...
在计算机科学中,有限自动机主要用于处理形式语言,特别是文本解析、编译器设计和模式匹配等领域。在这个场景中,我们讨论的是如何使用VC++编程环境,结合MFC(Microsoft Foundation Classes)库来实现一个有限...
### 有限状态自动机(NFA)的确定化 #### 概述 有限状态自动机(Finite State Automaton, FSA)是理论计算机科学中的一个基本概念,它被广泛应用于形式语言理论、编译原理等领域。FSA有两种主要类型:非确定有限...
在探讨不确定DNA有限状态自动机在基因网络中的应用时,首先需要了解DNA计算机的含义和工作原理。DNA计算机是一种新型的计算机,与传统的电子计算机不同,它使用DNA分子进行信息处理。由于DNA分子的特殊性,使得DNA...
Finite Automaton 有限状态自动机 Finite Automaton 有限状态自动机是计算机科学中的一种基本模型,用于描述有限状态机的行为。它是一种数学模型,用于描述一个系统在不同的状态之间转换的过程。 Finite Automaton...
有限自动机(Finite Automaton,简称FA)是一种简单的计算模型,它包括有限个状态、一个输入字母表、一个初始状态、一组终态以及定义状态转换的规则。最常见的有限自动机类型有确定性有限自动机(Deterministic ...
### 元胞自动机-Java 实现解析 #### 一、元胞自动机简介 元胞自动机(Cellular Automata, CA)是一种数学模型,它由一系列状态相同的元胞组成,这些元胞遵循相同的规则在空间网格上进行迭代更新。元胞自动机广泛...