Parsing 如何解析在解析过程中定义的类型名

Parsing 如何解析在解析过程中定义的类型名,parsing,typedef,pegjs,Parsing,Typedef,Pegjs,我使用pegjs定义了一个语法,允许定义新类型。然后,我如何识别这些定义之后的类型?我有一个定义内置类型的产品,例如 BuiltInType = "int" / "float" / "string" / TYPE_NAME 但最后一个我该怎么办?在源代码中定义类型名称之前,我不知道哪些字符串可能是类型名称 在传统的解析方法中,同时存在一个lexer和一个解析器,解析器将向表中添加类型名称,lexer将使用该表来确定是否返回特定令牌的类型名称或标识符。但是pegjs没有这种分离。

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

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

在传统的解析方法中,同时存在一个lexer和一个解析器,解析器将向表中添加类型名称,lexer将使用该表来确定是否返回特定令牌的类型名称或标识符。但是pegjs没有这种分离。

你是对的,你不能(轻松地)动态修改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"
    }
  }
}

如果我理解你所说的,你基本上是在使类型和标识符相同,并且依赖上下文来确定你要找的是哪一个?是的。如果它们出现在定义的上下文中,则对它们进行实习。然后,当它们出现在其他上下文中时,请参考interned定义。Ok。幸运的是,我正在为之编写解析器的语言将以这种方式工作,尽管我想对于不这样做的语言来说,这可能是一种运气