【问题标题】:How to parse type names defined during parse如何解析在解析期间定义的类型名称
【发布时间】:2016-12-07 21:06:59
【问题描述】:

我正在使用 pegjs 定义允许定义新类型的语法。然后我如何识别它们定义之后的那些类型?我有一个定义内置类型的产品,例如

BuiltInType
  = "int"
  / "float"
  / "string"
  / TYPE_NAME

但是最后一个我该怎么办?在源代码中定义之前,我不知道哪些字符串可能是类型名称。

在同时存在词法分析器和解析器的传统解析方式中,解析器会将类型名称添加到表中,词法分析器将使用该表来确定是否返回特定令牌的 TYPE_NAME 或 IDENTIFIER。但是 pegjs 没有这种分离。

【问题讨论】:

    标签: parsing typedef pegjs


    【解决方案1】:

    您是对的,您不能(轻松)在不了解其内部结构的情况下即时修改 pegjs 生成的解析器。但是,您从标准 LALR 中失去的,是在整个解析器规则本身中散布 JavaScript 代码。

    为了实现您的目标,您需要识别新类型(在上下文中)并保留它们以供以后使用,如下所示:

    {
      // predefined types
      const types = {'int':true, 'float':true, 'string':true}
    
      // variable storage
      const vars = {}
    }
    
    start = statement statement* {
      console.log(JSON.stringify({types:types,vars:vars}, null, 2))
    }
    
    statement
      = WS* typedef EOL
      / WS* vardef EOL
    
    typedef "new type definition" // eg. 'define myNewType'
      = 'define' SP+ type:symbol {
        if(types[type]) {
          throw `attempted redefinition of: "${type}"`
        }
        types[type]=true
      }
    
    // And then, when you need to recognize a type, something like:
    
    vardef "variable declaration" // eg: 'let foo:myNewType=10'
      = 'let' SP+ name:symbol COLON type:symbol SP* value:decl_assign? {
       if(!types[type]) {
         throw `unknown type encountered: ${type}`
       }
       vars[name] = { name: name, type:type, value: value }
    }
    
    decl_assign "variable declaration assignment"
      = '=' SP* value:number {
        return value
      }
    
    symbol = $( [a-zA-Z][a-zA-Z0-9]* )
    
    number = $( ('+' / '-')? [1-9][0-9]* ( '.' [0-9]+ )? )
    
    COLON = ':'
    SP = [ \t]
    WS = [ \t\n]
    EOL = '\n'
    

    当被要求解析时:

    define fooType
    let bar:fooType = 1
    

    将打印:

    {
      "types": {
        "int": true,
        "float": true,
        "string": true,
        "fooType": true
      },
      "vars": {
        "bar": {
          "name": "bar",
          "type": "fooType",
          "value": "1"
        }
      }
    }
    

    【讨论】:

    • 如果我理解您的意思,您基本上是在将类型和标识符设为同一事物,并依靠上下文来确定您要查找的内容?
    • 是的。如果它们出现在定义的上下文中,则实习它们。然后当它们出现在其他上下文中时,请参考实习定义。
    • 好的。幸运的是,我正在为其编写解析器的语言会以这种方式工作,尽管我猜对于那些不会不走运的语言
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-29
    • 1970-01-01
    • 1970-01-01
    • 2020-08-29
    • 1970-01-01
    • 2021-09-22
    • 2015-02-26
    相关资源
    最近更新 更多