zoukankan      html  css  js  c++  java
  • 自制编译器 青木峰郎 笔记 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

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

  • 相关阅读:
    腾讯分析系统架构解析
    GreenPlum简单性能测试与分析--续
    我的一些提高效率的设置
    Windows 上借助注册表来修改键盘按键的映射
    WPF入门——Converter、XAML和Style
    30个极大提高开发效率的Visual Studio Code插件(转)
    USB PD充电
    macOS Mojave 美化一下终端
    WPF入门(4)——资源
    使用Duilib开发Windows软件(5)——使用VLC做视频播放
  • 原文地址:https://www.cnblogs.com/xuesu/p/14378307.html
Copyright © 2011-2022 走看看