• 自制编译器 青木峰郎 笔记 Ch5 基于JavaCC的解析器描述


    5。1 基于EBNF语法的描述

    种类 含义 e.g
    终端符 token , , '=', "Var"
    非终端符 语法树非叶节点 stmt(), expr()

    可以省略的元素用[]括起: e.g: storage() typeref() name ["=" expr()] ";"

    5.2 语法二义性和token的超前扫描

    语法二义性可能由语言定义本身也可能由choice conflict产生。

    Choice Conflict

    如果出现了choice conflict,应该试着先提取共同部分,如果不行,那么就需要LOOKAHEAD。

    LookAhead

    1. 可以使用Lookahead(storage() type() ";")这样的语法预读不确定数目的token,javacc会读取直到该规则完全匹配/不符合该规则为止。
    2. javacc不会再对加了lookahead的地方做任何检查,所以需要编写者确保lookahead正确

    省略与冲突

    如果是语义本身的二义性,例如悬空else

    if(x) if(y){f();}else{g();}
    

    有时也可以采用LOOKAHEAD来解决。
    比如我们规定else属于最内侧的if。
    那么对于规则

    if_stmt(): {}
    {
          <IF> "(" expr() ")" stmt() {<ELSE> stmt();}
    }
    

    还是会在是否省略上产生矛盾。
    使用LOOKAHEAD改为:

    if_stmt(): {}
    {
          <IF> "(" expr() ")" stmt() {LOOKAHEAD(1) <ELSE> stmt();}
    }
    

    重复和冲突

    下列规则会导致可变长参数"," "..."不被解析,因为每次javacc都只读一个token,所以会优先匹配[",", type()]并发现无法匹配。

    param_decls(): {}
    {
          type() ("," type())* ["," "..."]
    }
    

    使用LOOKAHEAD后:

    param_decls(): {}
    {
          type() (LOOKAHEAD(2) "," type())* ["," "..."]
    }
    

    Packrat

    支持无限的超前扫描,无需区分扫描器和解析器,语法无二义性

    parser combinator

    直接用编程语言来描述语法,解析器生成器是单纯的程序库,无需导入额外的工具生成代码

  • 相关阅读:
    Tomcat配置JMX远程监控(Windown7 Linxu)
    Maven Tomcat:run 使用tomcat7
    关于C3P0容错和自动重连特性的研究
    密码算法记录
    Linxu 安装Nignx
    Linxu Yum方式安装Mysql
    Linxu
    tomcat结合nginx使用小结
    Tomcat性能优化(三) Executor配置
    深入学习C#匿名函数、委托、Lambda表达式、表达式树类型——Expression tree types
  • 原文地址:https://www.cnblogs.com/xuesu/p/14378307.html
Copyright © 2020-2023  润新知