如何解析在解析

时间:2016-12-07 21:07:00

标签: parsing typedef pegjs

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

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

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

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

1 个答案:

答案 0 :(得分:1)

你是对的,你不能(轻易)修改pegjs'生成的解析器在不知道很多关于它的内部的情况下。但是你从标准的LALR中失去了什么,你可以在整个解析器规则本身中散布JavaScript代码。

要实现目标,您需要识别新类型(在上下文中)并保留以供日后使用,如:

---
- hosts: bingo
...

当被要求解析时:

{
  // 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
相关问题