当前位置: 首页 > news >正文

安康免费做网站公司文化类网站建设

安康免费做网站公司,文化类网站建设,个人站长做什么类型的网站,企业关键词大全上一节我们研究了增强语法#xff0c;本节我们看看何为属性语法。属性语法实则是在语法规则上附带上一些重要的解析信息#xff0c;随着语法解析的进行#xff0c;我们可以利用附带的解析信息去进行一系列操作#xff0c;例如利用解析信息实现代码生成。我们先看属性语法的…上一节我们研究了增强语法本节我们看看何为属性语法。属性语法实则是在语法规则上附带上一些重要的解析信息随着语法解析的进行我们可以利用附带的解析信息去进行一系列操作例如利用解析信息实现代码生成。我们先看属性语法的一个实例 NUMBER(156, 156)NUMBER 是语法解析中的终结符他附带有两个属性一个是该标签对应字符串的内容“156”另一个是他对应的数值也就是 156如果符号是 ID也就是变量那么它可以附带一个属性就是一个指针指向符号表的入口该符号表包含了该变量的字符串名称该变量对应的数据等等。 属性信息分为两种一种是继承属性也就是属性从语法表达式箭头左边的符号传递给右边的符号另一种是综合属性属性信息从箭头右边符号汇总后传递给左边符号。从前面代码中我们看到语法解析本质上就是函数的调用例如语法 expr - term expr_prime对应的代码实现就是 expr() {term()expr_prime()}对于继承属性那就是父函数expr 在调用是被输入了某些参数这些参数再传递给里面的 term,和 expr_prime例如 expr(param) {term(param)expr_prime(param) }而综合属性就是子函数有返回值父函数获取子函数的返回值后综合起来处理例如 expr() {val_term : term()val_expr_prime : expr_prime(param)do_something(val_term, val_expr_prime)}在上一节我们使用增强语法来生成代码时代码生成所需要的信息例如寄存器等是从全局函数或全局变量例如全局寄存器数组等中获取在属性语法中我们就可以把这些信息作为参数传递给特定的语法解析函数这样在生成代码时就能更灵活。我们看具体的实现你就能更明白什么叫属性语法我们还是利用上一节识别算术表达式的语法 stmt - epsilon | expr SEMI stmt expr - term expr_prime expr_prime - PLUS term expr_prime term - factor term_prime term_prime - MUL factor term_prime | epsilon factor - NUMBER | LEFT_PAREN expr RIGHT_PAREN在原有项目中创建新文件夹 attribute_parser,在里面创建文件 attribute_parser.go添加代码如下 package attribute_parserimport (fmtlexer )type AttributeParser struct {parserLexer lexer.LexerreverseToken []lexer.Token//用于存储虚拟寄存器的名字registerNames []string//存储当前已分配寄存器的名字regiserStack []string//当前可用寄存器名字的下标registerNameIdx int }func NewAttributeParser(parserLexer lexer.Lexer) *AttributeParser {return AttributeParser{parserLexer: parserLexer,reverseToken: make([]lexer.Token, 0),registerNames: []string{t0, t1, t2, t3, t4, t5, t6, t7},regiserStack: make([]string, 0),registerNameIdx: 0,} }func (a *AttributeParser) putbackToken(token lexer.Token) {a.reverseToken append(a.reverseToken, token) }func (a *AttributeParser) getToken() lexer.Token {//先看看有没有上次退回去的 tokenif len(a.reverseToken) 0 {token : a.reverseToken[len(a.reverseToken)-1]a.reverseToken a.reverseToken[0 : len(a.reverseToken)-1]return token}token, err : a.parserLexer.Scan()if err ! nil token.Tag ! lexer.EOF {sErr : fmt.Sprintf(get token with err:%s\n, err)panic(sErr)}return token }func (a *AttributeParser) match(tag lexer.Tag) bool {token : a.getToken()if token.Tag ! tag {a.putbackToken(token)return false}return true }func (a *AttributeParser) newName() string {//返回一个寄存器的名字if a.registerNameIdx len(a.registerNames) {//没有寄存器可用panic(register name running out)}name : a.registerNames[a.registerNameIdx]a.registerNameIdx 1return name }func (a *AttributeParser) freeName(name string) {//释放当前寄存器名字if a.registerNameIdx len(a.registerNames) {panic(register name index out of bound)}if a.registerNameIdx 0 {panic(register name is full)}a.registerNameIdx - 1a.registerNames[a.registerNameIdx] name }func (a *AttributeParser) Parse() {a.stmt() }func (a *AttributeParser) stmt() {for a.match(lexer.EOF) ! true {t : a.newName()a.expr(t)a.freeName(t)if a.match(lexer.SEMI) ! true {panic(missing ; at the end of expression)}} }func (a *AttributeParser) expr(t string) {a.term(t)a.expr_prime(t) }func (a *AttributeParser) expr_prime(t string) {if a.match(lexer.PLUS) {t2 : a.newName()a.term(t2)fmt.Printf(%s %s\n, t, t2)a.freeName(t2)a.expr_prime(t)} }func (a *AttributeParser) term(t string) {a.factor(t)a.term_prime(t) }func (a *AttributeParser) term_prime(t string) {if a.match(lexer.MUL) {t2 : a.newName()a.factor(t2)fmt.Printf(%s * %s\n, t, t2)a.freeName(t2)a.term_prime(t)} }func (a *AttributeParser) factor(t string) {if a.match(lexer.NUM) {fmt.Printf(%s %s\n, t, a.parserLexer.Lexeme)} else if a.match(lexer.LEFT_BRACKET) {a.expr(t)if a.match(lexer.RIGHT_BRACKET) ! true {panic(missing ) for expr)}} } 我们可以看到 AttributeParser 跟我们前面实现的 AugmentedParser 区别不大一个明显区别是解析函数接受一个传进来的参数这个参数可以看做是语法属性他由语法表达式左边符号对应的函数创建然后传递给右边符号对应的函数。我们看如下代码 func (a *AttributeParser) stmt() {for a.match(lexer.EOF) ! true {t : a.newName()a.expr(t)a.freeName(t)if a.match(lexer.SEMI) ! true {panic(missing ; at the end of expression)}} }stmt 函数在调用时创建了一个寄存器名称然后调用 expr 时将该名称作为参数传入在语法表达上相当于 stmt_(t) - expr_(t) SEMI stmt其中 t 是左边 stmt 符号附带的参数他将该参数传递给右边符号 exprexpr 利用该传过来的符号在语法解析时进行代码生成。从上面代码我们也能看出它实际上是增强语法和属性语法的结合体例如代码将属性作为参数传入同时在解析的过程中又在特定位置执行特定步骤因此上面的解析过程其实可以对应成如下的“增强属性语法” stmt - epsilon | {tnewName()} expt_(t) SEMI stmt expr_(t) - term_(t) expr_prime_(t) expr_prime_(t) - PLUS {t2 newName()} term_(t2) {print(%s%s\n,t,t2) freenName(t2)} expr_prime_(t) | epsilon term_(t) - factor term_prime term_prime_(t) - MUL {t2 newName()} factor_(t2) {print(%s%s\n,t,t2) freeName(t2)} term_prime_(t) factor_(t) - NUM {print(%s*%s\n,t, lexeme)} | LEFT_PAREN expr_(t) RIGHT_PAREN最后我们在 main.go 中调用属性语法解析器看看运行结果 package mainimport (attribute_parserlexer )func main() {exprLexer : lexer.NewLexer(12*(43);)attributeParser : attribute_parser.NewAttributeParser(exprLexer)attributeParser.Parse() } 上面代码运行后结果如下 t0 1 t1 2 t2 4 t3 3 t2 t3 t1 * t2 t0 t1可以看到生成的结果跟我们上一节一样。更多内容请在 b 站搜索 coding 迪斯尼。代码下载 https://github.com/wycl16514/compiler-attribute-grammar.git
http://www.zqtcl.cn/news/747147/

相关文章:

  • wordpress支持国内视频的编辑器网站优化排名软件网站
  • 建设摩托官方网站南京做网站群的公司
  • 晋城城乡建设局网站设计网站公司选泽y湖南岚鸿询 问
  • 思坎普网站建设湘潭网站推广
  • 北京网站建设公司哪个最好做投标网站条件
  • 网站建设的成本有哪些内容怎么样制作网页
  • 怎么做网站的seo排名知乎茂名网站制作公司
  • 建安证查询网站官方网站建设对比
  • 关于医院要求建设网站的请示市场推广12种推广渠道
  • php做不了大型网站深圳公司注册网址官方
  • 网站副标题怎么写杭州抖音代运营
  • 网站建设基本资料网站数据库连接出错
  • 娄底网站开发温州seo排名公司
  • 成都有哪些网站开发公司最新网推项目
  • 分享公众号的网站小型企业类网站开发公司
  • 青岛网站建设方案案例wordpress主题模板 国人
  • 哪家高端网站建设好贷款织梦网站模板
  • 北京网站建设公司价格最近中文字幕2018免费版2019
  • 帮人做设计的网站自己怎么做新闻开头视频网站
  • 网站开发搜索功能中国建设银行ie下载网站
  • 中山网站建设 骏域网站的形式有哪些
  • 深圳企业网站重庆建站塔山双喜
  • 征婚网站 女 做茶叶生意企业网站推广服务协议
  • 安徽省住房城乡建设厅网站官网英语机构网站建设方案
  • 电商建站价格深圳龙岗建站公司
  • 可以下载源程序的网站.htaccess wordpress
  • 国内优秀设计网站小程序推广方案
  • 网站构建是什么意思怎么做网站盗号
  • 学校网站建设行业现状wordpress怎么保存图片
  • 网站 框架网页建设title:(网站建设)