语言翻译器可以从一种计算机语言翻译成另外一种语言,比如一种DSL的标量乘法axb翻译成java就变成a*b:如果DSL里面有矩阵运算,就需要翻译成for循环.翻译器需要完全理解输入语言的所有结构,并选择输出结构:简单的关键字或模式替换几乎肯定不会奏效."语言翻译"是一个庞大的主题,这一章只关注大体的策略和几个基本模式. Pattern 29, Syntax-Directed Translator,在parser里面嵌入操作,直接产生输出: Pattern 30, Rule-Based…
如果要解释执行或转换一段语言,那么就无法在识别语法规则的同时达到目标,只有那些简单的,比如将wiki markup转换成html的功能,可以通过一遍解析来完成,这种应用叫做 syntax-directed应用. 更负载的功能,需要我们在完成parse的同时构建某种中间表示形式(Intermediate representation),简称为IR.实际上,我们一般构建一种叫做AST(abstract syntax tree)的结构,它保存了所有的token以及token之间的语法关系.在一个语言应…
前面讲述了如何验证语句,这章讲述如何构建一个解释器来执行语句,解释器有两种,高级解释器直接执行语句源码或AST这样的中间结构,低级解释器执行执行字节码(更接近机器指令的形式). 高级解释器比较适合DSL,而不适合通用编程语言:一般来说,DSL更需要简单.廉价的实现,不是很在乎执行效率:这个笔记只学习高级解释器,下面的文字如果提到解释器就是指"高级"解释器.为了简单起见,下面的讨论假定目标DSL是动态类型的. 解释器有两种模式: Pattern 24,Syntax-Directed In…
语句的语义取决于其语法结构和相关符号:前者说明了了要"做什么",后者说明了操作"什么对象".所以即使语法结构正确的,如果被操作的对象不合法,语句也是不合法的.语言一般有很多语义规则,有些是运行时的(dynamic semantics),比如"不能除以零"."不能越界访问数组":有些是编译时的(static semantics).运行时&编译时的界限取决于具体的语言,python是动态类型的语言,所有的值编译时都不会指定…
前面的章节我们学会了如何解析语言.构建AST,如何访问重写AST,有了这些基础,我们可以开始进行"语义分析"了. 在分析语义的一个基本方面是要追踪"符号",符号是语句定义的变量.函数,我们通过建立一种叫做"符号表"的基础结构来完成此项工作. 有两种模式的符号表: Pattern 16, Symbol Table for Monolithic Scope,所有的符号存在于单一的作用域内,早期的BASIC使用这种模式: Pattern 17, Sym…
每个编程的人都学习过树遍历算法,但是AST的遍历并不是开始想象的那么简单.有几个因素会影响遍历算法:1)是否拥有节点的源码:2)是否子节点的访问方式是统一的:3)ast是homogeneous或heterogeneous:4)遍历的过程中是否需要修改ast:5)以何种顺序呢遍历.这一章会讨论常用的四个ast遍历模式. Pattern 12, Embedded Heterogeneous Tree Walker, AST的node类包含了对应的访问方法,后者执行嵌入的操作,并访问所有的子节点.这种…
上一章节讲述了基本的语言解析模式,LL(k)足以应付大多数的任务,但是对一些复杂的语言仍然显得不足,已付出更多的复杂度.和运行时效率为代价,我们可以得到能力更强的Parser. Pattern 5 :回朔解析器(Backtracking Parser),这种解析器晖尝试规则的每个分支来进行匹配,与LL(k)比较的话,Backtracking Parser支持任意长度的预读token,这种Parser的能力极强,运行时的代价可能会很大. Pattern 6 :Memoizing Parser, 这…
本章学习一种新的作用域,叫做数据聚合作用域(data aggregate scope),和其他作用域一样包含符号,并在scope tree里面占据一个位置. 区别在于:作用域之外的代码能够通过一种特殊的表达式user.name来访问数据成员:以下两个模式分别描述非面向对象语言和面向对象语言的数据聚合作用域. Pattern 18, Symbol Table for Data Aggregates,描述了如何定义和访问简单的数据聚合,比如C struct; Pattern 19, Symbol T…
Generating Your Classes - 生成类 要生成Java.Python.C++.Go.Ruby.ObjuleC或C代码,需要使用.proto文件中定义的消息类型,还需要在.proto上运行协议缓冲区编译器protoc.如果尚未安装编译器,请下载该软件包并按照自述文件中的说明进行操作.对于Go,您还需要为编译器安装一个特殊的代码生成器插件:您可以在GitHub上的golang/protobuf存储库中找到这个插件和安装说明. 协议编译器的调用方式如下: protoc --prot…
前言 近日在学习gRPC框架的相关知识时接触到Protobuf(protocol-buffers,协议缓冲区),proto3等知识.网上很多文章/帖子经常把gRPC与proto3放在一起,为避免初学者产生混淆,这里先简单介绍一下gRPC.Protobuf.proto3三者以及他们之间的关系: gRPC:一个高性能.开源的通用RPC框架,它可以使用Protobuf定义服务 Protobuf:协议缓冲区是一种与语言无关.与平台无关的可扩展机制,用于序列化结构化的数据(参考JSON) proto3:p…
一.九种图 二.类间关系 一.UML中的九种图 1.用例图(use case diagrams) [概念]描述用户需求,从用户的角度描述系统的功能 [描述方式]椭圆表示某个用例:人形符号表示角色 [目的]帮组开发团队以一种可视化的方式理解系统的功能需求 [用例图] 2.静态图 2-1)类图(class  diagrams) [概念]显示系统的静态结构,表示不同的实体是如何相关联的 [可见性]公有类型(public).受保护类型(protected).私有类型(private).Implement…
<script language="javascript" type="text/javascript"> var request = false; try { request = new XMLHttpRequest();//最重要的对象. } catch (trymicrosoft) { try { request = new ActiveXObject("Msxml2.XMLHTTP"); } catch (othermicro…
Options - 选项 .proto文件中的单个声明可以使用许多 选项 进行注释.选项不会更改声明的总体含义,但可能会影响在特定上下文中处理声明的方式.可用选项的完整列表在google/protobuf/descriptor.proto中定义. 有些选项是文件级选项,这意味着它们应该写在顶级作用域中,而不是写在任何消息.枚举或服务定义中.有些选项是消息级别的选项,这意味着它们应该写在消息定义中.有些选项是字段级选项,这意味着它们应该写在字段定义中.也可以在枚举类型.枚举值.字段之一.服务类型和…
Defining Services - 定义服务 如果要在RPC(Remote Procedure Call,远程过程调用)系统中使用消息类型,可以在.proto文件中定义RPC服务接口,协议缓冲区编译器将根据所选语言生成服务接口代码和存根.因此,例如,如果您想用一个方法定义一个RPC服务,该方法接受您的SearchRequest并返回一个SearchResponse,您可以在.proto文件中这样定义它: service SearchService { rpc Search(SearchReq…
Packages - 包 可以向.proto文件中添加可选的package明符,以防止协议消息类型之间的名称冲突. package foo.bar; message Open { ... } 然后你可以在定义你的消息类型的字段时使用包说明符: message Foo { ... foo.bar.Open open = 1; ... } 包说明符对生成代码的影响取决于您选择的语言: 在C++中,生成的类被封装在C++命名空间内.例如,Open将位于名称空间foo::bar中. 在Java中,该包用…
Maps - 映射 如果要创建关联映射作为数据定义的一部分,协议缓冲区提供了一种方便的快捷语法: map<key_type, value_type> map_field = N; -其中key_type可以是任何整型或字符串类型(因此,除了浮点类型和字节之外的任何标量类型).注意enum不是一个有效的key_type.value_type可以是除其他map以外的任何类型. 因此,例如,如果您想创建一个项目映射,其中每个Project消息都与一个字符串键相关联,您可以这样定义它: map<…
Oneof - Oneof结构 如果消息包含多个字段,并且最多只能同时设置一个字段,则可以使用oneof功能强制执行此行为并节省内存. oneof字段与常规字段类似,但oneof共享内存中的所有字段除外,并且oneof最多只能同时设置一个字段.设置oneof的任何成员将自动清除所有其他成员.您可以使用特殊的case()或WhichOneof()方法检查oneof中设置了哪个值(如果有被设置),具体取决于您选择的语言. 使用oneof结构 要在.proto中定义oneof结构,请使用oneof关键…
未知字段和任意类型篇幅较少,因此将他们合并到本文进行描述. Unknown Fields - 未知字段 未知字段是格式良好的协议缓冲区序列化数据,表示解析器无法识别的字段.例如,当一个旧二进制代码解析一个带有新字段的新二进制代码发送的数据时,这些新字段在旧二进制代码中成为未知字段. 最初,proto3消息在解析过程中总是丢弃未知字段,但在3.5版中,我们重新引入了未知字段的保留,以匹配proto2的行为.在版本3.5和更高版本中,解析期间保留未知字段,并将其包含在序列化输出中. Any - 任意…
Updating A Message Type - 更新消息类型 如果现有的消息类型不再满足您的所有需要(例如,您希望消息格式有一个额外的字段),但是您仍然希望使用用旧格式创建的代码,不要担心!在不破坏任何现有代码的情况下更新消息类型非常简单.记住以下规则: 不要更改任何现有字段的字段编号. 如果添加新字段,则使用"旧"消息格式的代码序列化的任何消息仍然可以由新生成的代码进行解析.您应该记住这些元素的默认值,以便新代码可以正确地与旧代码生成的消息交互.类似地,由新代码创建的消息也可以由…
枚举类型 定义消息类型时,可能希望其中一个字段只包含预定义值列表中的一个.例如,假设您想为每个SearchRequest添加一个corpus(语料库)字段,其中语料库的值可以是UNIVERSAL.WEB.IMAGES.LOCAL.NEWS.PRODUCTS或VIDEO.您只需在消息定义中添加一个枚举,每个可能的值都有一个常量,就可以做到这一点. 在下面的示例中,我们添加了一个名为Corpus的枚举,其中包含所有可能的值,以及一个类型为Corpus的字段: message SearchReques…
默认值 解析消息时,如果编码的消息不包含特定的单数元素,则解析对象中的相应字段将设置为该字段的默认值.这些默认值是特定于类型的: string:默认值为空字符串 bytes:默认值为空字节 boolean:默认值为false 数值类型:默认值为0 枚举:默认值为第一个定义的枚举值,该值必须是0 消息字段:不设默认值,它的确切值取决于语言.有关详细信息,请参阅生成代码指南 重复字段的默认值为空(通常是适当语言中的空列表). 请注意,对于标量消息字段,一旦解析了消息,就无法判断字段是显式设置为默认值…
定义消息类型 首先让我们看一个非常简单的例子.假设您想定义一个搜索请求消息格式,其中每个搜索请求都有一个查询字符串.您感兴趣的特定结果页以及每页的结果数.下面是用于定义.proto消息类型的文件. syntax = "proto3"; message SearchRequest { string query = 1; int32 page_number = 2; int32 result_per_page = 3; } 文件第一行指定您使用的语法:如果不这样做,协议缓冲区编译器将假定您…
DDL对数据库的操作:http://blog.csdn.net/baidu_37107022/article/details/72334560 DDL对数据库中表的操作 1)方法概览 2)演示 //创建的前提条件:指明使用的数据库 :use database test1; //创建表create table student (id int,name varchar(100),age int); //查看数据库下的所有表show tables; //查看指定的表的字段信息(表的内容)desc st…
https://github.com/ewen0930/WebStorm-Chinese http://ewen0930.github.io/2016/04/webstorm-chinese-language-pack/…
在之前的几个博客中,我主要讲了两个saga的实现模式: 基于command的控制者模式 基于事件的观察者模式 当然,这些都不是实现saga的唯一方式.我们甚至可以将这些结合起来. 发布者——收集者 回顾我们的麦当劳的例子,我们可以稍稍改进一下我们的方案.我们可以通过一个command去启动一个saga,然后这个saga就会发布消息.然后saga就等待回复事件(忽略顺序): 这里有一个优点,那就是我们的saga只有一个入口.因此我们不必担心我们的saga被其他消息触发. 当你在麦当劳下一个订单的时…
https://lostechies.com/jimmybogard/2013/03/11/saga-implementation-patterns-observer/ 侵删. NServiceBus sagas 是一个Process Manager pattern的实现,在实现的时候经常使用它的一两种主要形式.虽然各有差别,但总的来说saga的实现也就总是那几种. 第一种是观察者模式.作为一个观察者,saga通过响应事件来协调业务: 观察者有一些特性: 消息以事件的形式接收 saga并不控制消…
https://lostechies.com/jimmybogard/2013/03/14/saga-implementation-patterns-controller/ 之前的文章中我们介绍了观察者模式.在这个模式里,saga在整个业务中是一个被动的参与者,和大多数快餐店完成订单流程类似.但是并不是所有的快餐店都用这种方式,还有更多的更有效率的方式能够完成这种工作. 我们可以让我们的saga在整个业务过程中扮演一个主动的角色.saga直接控制整个流程,向特定的工作者发出command,等待回…
import urllib.request import urllib.parse import json while True: content = input('请输入需要翻译的内容(退出输入Q):') if content == 'Q': break else: url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=http:…
JSON Mapping - JSON映射 Proto3支持JSON中的规范编码,使得在系统之间共享数据更加容易.下表按类型对编码进行了描述. 如果JSON编码的数据中缺少一个值或者它的值为null,那么在解析到协议缓冲区时,它将被解释为适当的默认值.如果某个字段在协议缓冲区中有默认值,则在JSON编码的数据中默认会省略该字段以节省空间.一个实现可以提供在JSON编码的输出中使用默认值发出字段的选项. proto3 JSON JSON example 描述[译] message object {…
Nested Types - 嵌套类型 您可以在其他消息类型中定义和使用消息类型,如以下示例所示--这里的Result消息是在SearchResponse消息中定义的: message SearchResponse { message Result { string url = 1; string title = 2; repeated string snippets = 3; } repeated Result results = 1; } 如果要在其父消息类型之外重用此消息类型,请将其指定为…