草庐IT

c++ - 在 C++ 编译过程中,上下文敏感性在哪里得到解决?

coder 2024-02-20 原文

昨天我问了关于 C++ 上下文敏感性的问题,参见 here .在众多优秀答案中,here是被接受的,通过 dmckee .

但是,我仍然认为对此有话要说(也许是一些术语混淆?)。问题是:编译的哪一部分处理歧义?

为了澄清我的术语:CFG 是一种语法,它在规则的左侧只有一个非终结符(例如 A->zC),CSG 是在左侧 (aAv->QT) 有一个终结符(加上一个非终结符),其中大写字母是非终结符,小写字母是终结符。

语法解析C++源码中有没有类似后者的表现形式?

谢谢,很抱歉推送这个问题。

最佳答案

没有我所知道的 C++ 前端(解析器、名称/类型解析器) ( including the one we built ) 使用您定义的 CSG 语法规则实现上下文相关的解析器。几乎它们使用仍然有歧义的上下文无关语法显式或隐式操作。

他们中的许多人结合使用自上而下的解析和类型信息的交织集合来区分不明确的情况。

将解析和类型收集结合在一起使得以这种方式构建解析器变得非常困惑和困难,产生了民间定理“C++ 很难解析”。

像许多这样的“定理”一样,这不是真的,除非你也坚持用一只手绑在背后进行解析(例如,递归下降、LL(k)、LALR [例如,YACC])。如果使用可以处理歧义的解析技术,C++语法其实没有那么难。我们(和其他人,例如 Elsa C++ 解析器)为此使用 GLR 解析技术。 (我们更进一步,在 C++ 语法中捕获宏定义、使用和预处理器条件,因为我们有兴趣在处理器破坏代码之前转换代码;通常预处理器指令在独立的预处理器中完全分开处理)。

我认为 Elsa 仍然将歧义消除交织到解析过程中,但因为解析非常干净,所以更容易做到。我们的前端构建一个带有歧义节点的 AST,在构建树之后,我们使用属性语法评估器遍历树以收集名称和类型,并消除那些类型不一致的歧义分支。后者是一个非常漂亮的方案,并且完全解耦了解析和名称解析。

的困难实际上是进行名称解析。 C++ 有一个非常神秘的查询方案,它分布在标准的 600 页中,并且被各种方言以各种方式弯曲。将名称解析与解析分开使这种丑陋更易于管理,但民间定理应该是“C++ 很难进行名称解析”。

关于c++ - 在 C++ 编译过程中,上下文敏感性在哪里得到解决?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1179879/

有关c++ - 在 C++ 编译过程中,上下文敏感性在哪里得到解决?的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby - Sinatra set cache_control to static files in public folder编译错误 - 2

    我不知道为什么,但是当我设置这个设置时它无法编译设置:static_cache_control,[:public,:max_age=>300]这是我得到的syntaxerror,unexpectedtASSOC,expecting']'(SyntaxError)set:static_cache_control,[:public,:max_age=>300]^我只想将“过期”header设置为css、javaascript和图像文件。谢谢。 最佳答案 我猜您使用的是Ruby1.8.7。Sinatra文档中显示的语法似乎是在Ruby1.

  3. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  4. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  5. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  6. ruby - 在 Ruby 中,在类方法的上下文中,什么是实例变量和类变量? - 2

    如果我有以下一段Ruby代码:classBlahdefself.bleh@blih="Hello"@@bloh="World"endend@blih和@@bloh到底是什么?@blih是Blah类中的一个实例变量,@@bloh是Blah类中的一个类变量,对吗?这是否意味着@@bloh是Blah的类Class中的一个变量? 最佳答案 人们似乎忽略了该方法是类方法。@blih将是常量Bleh的类Class实例的实例变量。因此:irb(main):001:0>classBlehirb(main):002:1>defself.blehirb

  7. ruby-on-rails - ActiveRecord::Associations::CollectionProxy 从哪里获取.each 实例方法? - 2

    假设我有模型Topics和Posts,其中Topichas_many:posts和Postbelongs_to:topic。此时我的数据库中已经有了一些东西。如果我进入Rails控制台并输入Topic.find(1).posts我相信我得到了一个CollectionProxy对象。=>#]>我可以对此调用.each以获得枚举器对象。=>#]:each>我对CollectionProxy如何处理.each感到困惑。我意识到它在某些时候是继承的,但我一直在阅读API文档,他们并没有说得很清楚CollectionProxy是从什么继承的,除非我遗漏了一些明显的东西。Thispage似乎并没有

  8. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

  9. ruby-on-rails - 闪存消息存储在哪里? - 2

    我以为它们存储在cookie中-但不,检查cookie没有任何结果。session也不存储它们。那么,我在哪里可以找到它们?我需要这个来直接设置它们(而不是通过flashhash)。 最佳答案 它们存储在inyoursessionstore.自rails2.0以来的默认设置是cookie存储,但请检查config/initializers/session_store.rb以检查您是否使用默认设置以外的东西。 关于ruby-on-rails-闪存消息存储在哪里?,我们在StackOverf

  10. += 的 Ruby 方法 - 2

    有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=

随机推荐