代码之家  ›  专栏  ›  技术社区  ›  Serafina Brocious

解析的部分求值

  •  3
  • Serafina Brocious  · 技术社区  · 15 年前

    as discussed here

    我看到的最大问题是,在运行受影响的代码之前,您无法找到解析错误。但是,这不会影响很多情况,例如,像[]、{}、()和``这样的组运算符仍然需要配对(我的标记器/列表解析器的要求),顶级语法(如类和函数)不会受到影响,因为它们的“运行时”实际上是加载时,在加载时会计算语法并生成它们的对象。

    6 回复  |  直到 7 年前
        1
  •  3
  •   A. Rex    15 年前

    以下是一些可能的问题:

    • 如果出现问题,您可能会发现很难向用户提供有用的错误消息。这似乎是可能的,因为任何编译时语法错误都可能只是语法扩展。
    • 表演命中。

    在20世纪60年代,人们知道没有界限。拒绝 提出灵活的想法,或 至少是可扩展语言。这个 然后将指导通用解析器 在解析后续程序时。 更进一步:语法规则将 不仅在计划之前,而且他们 可以散布在任何地方 有人想用一种特殊的方法 别出心裁的私人陈述形式, 为应用程序指定不同的变体 不同章节中的相同概念 同样的程序。这个概念 人类已经完全融合在一起了 很显然,现在每个人都可以出去了 在飞行中定义自己的语言。 当试图指定时,这些是什么 私人建筑应该意味着。像 可扩展语言逐渐消失,而不是

    编辑 :这是Perl 6的 Synopsis 6: Subroutines ,不幸的是,在标记形式中,因为我找不到更新的格式化版本;在中搜索“宏”。不幸的是,事实并非如此 有趣的是,您可能会发现一些相关的东西,比如Perl6的一次传递解析规则,或者它的抽象语法树语法。Perl 6采用的方法是,宏是一个函数,在解析其参数后立即执行,并返回AST或字符串;Perl6继续解析,就好像源代码实际包含返回值一样。这里提到了错误消息的生成,但它们使宏返回AST时,您似乎可以做得很好。

        2
  •  2
  •   sth ypicasso    15 年前

    def fun():
       not implemented yet
    
    try:
      fun()
    except:
      pass
    

    这将是一个有趣的效果,但它是否有用或可取则是另一个问题。一般来说,即使您现在不调用代码,了解错误也是很好的。

    在控件到达宏之前,不会对宏进行求值,解析器自然已经知道所有以前的定义。此外,宏定义甚至可能使用程序到目前为止已经计算过的变量和数据(比如为以前计算过的列表中的所有元素添加一些语法)。但是,对于那些通常也可以直接用这种语言完成的事情,开始编写自修改程序可能不是一个好主意。这可能会让人困惑。。。

    在任何情况下,您都应该确保只解析代码一次,如果第二次执行,请使用已解析的表达式,这样就不会导致性能问题。

        3
  •  2
  •   Yuval F    15 年前

    本文主要研究自然语言的鲁棒性分析。 文本(或者,在您的例子中,是python程序)。如果解析失败,您将有一个部分生成的解析树。使用树结构建议新的语法规则,以更好地覆盖已解析的文本。 我可以把我的论文寄给你,但除非你读希伯来文,否则这可能没用。

    我用了一个 bottom-up chart parser . 这种类型的解析器根据语法为产品生成边。每条边都用已消耗的树部分进行标记。每个边根据其接近完全覆盖的程度获得分数,例如:

    S -> NP . VP
    

    得分为一半(我们成功地覆盖了NP,但没有覆盖VP)。 一般来说,图表解析器的效率低于普通的LALR或LL解析器(通常用于编程语言的类型)-O(n^3)而不是O(n)复杂度,但是您再次尝试了比解析现有语言更复杂的事情。 我相信看一下自然语言解析器可能会给你一些其他的想法。

        4
  •  1
  •   Serafina Brocious    15 年前

    我考虑过的另一件事是将此作为默认行为,但允许语言(即一组宏来解析给定语言)在编译时抛出解析错误。例如,在我的系统中,Python2.5可以做到这一点。

    代替存根思想,只需重新编译在执行时无法在编译时完全处理的函数。这也将使自修改代码变得更容易,因为您可以修改代码并在运行时重新编译它。

        5
  •  0
  •   Dickon Reed    15 年前

    您可能会发现解析算法和lexer以及它们之间的接口都需要更新,这可能会排除大多数编译器创建工具。

    (更常见的方法是为此目的使用字符串常量,可以在运行时将其解析为一个小型解释器)。

        6
  •  0
  •   user51568    15 年前

    define some syntax M1 with definition D1
    if _whatever_:
        define M1 to do D2
    else:
        define M1 to do D3
    code that uses M1
    

    因此,有一个例子,如果您允许在运行时重新定义语法,您会遇到一个问题(因为按照您的方法,使用M1的代码将由定义D1编译)。请注意,验证是否发生语法重新定义是不可判定的。过近似可以通过某种类型的类型系统或某种其他类型的静态分析来计算,但Python并不为此而广为人知:D。

    另一件让我困扰的事情是,你的解决方案“感觉”不对。我发现存储无法解析的源代码是一件坏事,因为您可以在运行时解析它。

    ...function definition fun1 that calls fun2...
    define M1 (at runtime)
    use M1
    ...function definition for fun2
    

    从技术上讲,当您使用M1时,您无法解析它,因此您需要将程序的其余部分(包括fun2的函数定义)保留在源代码中。当您运行整个程序时,您将看到对fun2的调用,即使已定义,也无法调用该调用。