【问题标题】:PEG.js extension with predefined functions and variables具有预定义函数和变量的 PEG.js 扩展
【发布时间】:2014-12-04 21:18:29
【问题描述】:

我查看了用于 JavaScript 的 PEG.js 解析器生成器。它看起来很不错!

我在指定语法方面没有太多经验。我正在寻求帮助以扩展 1 的示例语法以允许

  1. 十进制数
  2. 运算符 ^
  3. 预定义函数(不是函数声明,仅用于调用我预先指定的一些函数),其中参数本身是一阶表达式,例如f(g(2+4) + 3)
  4. 变量 A-Z(不是声明,只有用法定义——这些是为了指向一个也包含程序的输入框,字母 A 到 Z 就足够了)

你能帮我看看在哪里可以找到帮助吗?

【问题讨论】:

    标签: javascript parsing peg


    【解决方案1】:

    这里是快速演示:

    {
      variables = { 
        PI : Math.PI, 
        E  : Math.E 
      };
      functions = {
        squared : function(n) { return n * n; },
        incr    : function(n) { return n + 1; }
      }
    }
    
    start
     = additive
    
    additive
     = left:multiplicative "+" right:additive { return left + right; }
     / multiplicative
    
    multiplicative
     = left:power "*" right:additive { return left * right; }
     / power
    
    // evaluated left to right!
    power
     = left:primary "^" right:additive { return Math.pow(left, right); }
     / primary
    
    primary
     = integer
     / "(" e:additive ")"      { return e; }
     / i:id "(" e:additive ")" { return functions[i.join("")](e); }
     / i:id                    { return variables[i.join("")]; }
    
    integer
      = digits:[0-9]+ { return parseInt(digits.join(""), 10); }
    
    id
     = [a-zA-Z]+
    

    如果您现在使用输入测试解析器(在线):

    PI+incr(squared(3))^2
    

    你会看到它被评估为:

    103.1415926535898
    

    【讨论】:

    • 谢谢!为了添加十进制数字,我从here 添加了包含numbernumber_frac 的shippet,并将其放在primary 规则中的第一优先级。请参阅我的答案以获取更新的语法。看起来对吗?
    • 虽然在我看来整数规则永远不会被使用。对吗?
    • @mikldk,为什么不用呢?如果不这样,就永远不会有任何正确评估的表达式(are)。
    • 对不起,我应该更准确:在更新的语法中,包括(十进制)数字,在我看来整数无法​​达到:数字在主要规则中的整数之前,并且数字有正则表达式frac:number_frac?。因此,似乎 number 也会捕获整数。并且可以删除整数规则。还是我错过/误解了什么?缺点当然是所有数字都是浮点数,不存在整数。
    • 是否可以注入运行时变量或函数而不是pegjs语法文件中预定义的?
    【解决方案2】:
    {
      variables = { 
        PI : Math.PI, 
        E  : Math.E 
      };
      functions = {
        squared : function(n) { return n * n; },
        incr    : function(n) { return n + 1; }
      }
    }
    
    start
     = additive
    
    additive
     = left:multiplicative "+" right:additive { return left + right; }
     / multiplicative
    
    multiplicative
     = left:power "*" right:power { return left * right; }
     / power
    
    // evaluated left to right!
    power
     = left:primary "^" right:primary { return Math.pow(left, right); }
     / primary
    
    primary
     = number
     / integer
     / "(" e:additive ")"      { return e; }
     / i:id "(" e:additive ")" { return functions[i.join("")](e); }
     / i:id                    { return variables[i.join("")]; }
    
    number_frac
        = "." chars:[0-9]* { return "." + chars.join(''); }
    
    number
        = chars:[0-9]+ frac:number_frac? { return parseFloat(chars.join('') + frac); }
    
    integer
      = digits:[0-9]+ { return parseInt(digits.join(""), 10); }
    
    id
     = [a-zA-Z]+
    

    【讨论】:

      猜你喜欢
      • 2014-07-21
      • 2018-09-02
      • 1970-01-01
      • 1970-01-01
      • 2011-12-21
      • 2016-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多