【问题标题】:Parsing constant and identifier解析常量和标识符
【发布时间】:2015-08-01 07:58:30
【问题描述】:

我想匹配一个常量,它基本上是一个全大写的字符串。

另外,我想匹配一个标识符,它可以包含小写和大写字母的混合。

Start 
  = Constant
  / Identifier

Identifier
  = h:[A-Za-z_] t:[a-zA-Z0-9_]* { return { type: 'IDENTIFIER', value: h + t.join('') } }

Constant
  = h:[A-Z] t:[A-Z_0-9]* { return { type: 'CONSTANT', value: h + t.join('') } }

问题是,当我尝试匹配 Asd 时,它显示:Line 1, column 2: Expected [A-Z_0-9] or end of input but "s" found.

它似乎符合常量规则,但即使失败也不会切换到标识符...

问题似乎是一个常量也是一个有效的标识符,但我无法找出打破歧义的规则,我认为如果常量匹配失败它应该只尝试标识符规则......

【问题讨论】:

    标签: peg pegjs


    【解决方案1】:

    这里出现问题是因为解析表达式语法不像上下文无关语法。他们得到第一场比赛而不是回溯。 Constant 规则在 Identifier 之前定义。 Asd 匹配常量规则的起始字符,但下一个字符不匹配,因此它会引发错误,因为它是确定性的。希望它很容易修复:

    Start 
      = Constant
      / Identifier
    
    Identifier
      = h:[A-Za-z_] t:[a-zA-Z0-9_]* { return { type: 'IDENTIFIER', value: h + t.join('') } }
    
    Constant
      = h:[A-Z] ![a-z] t:[A-Z_0-9]* { return { type: 'CONSTANT', value: h + t.join('') } }  
    

    输出:

    {
       "type": "IDENTIFIER",
       "value": "Asd"
    }
    

    按照您的规则定义,默认情况下,PEG 具有确定性并避免歧义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多