Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Compiler construction 将链式表达式建模到AST中 前言_Compiler Construction_Expression_Abstract Syntax Tree_Sprache_Superpower - Fatal编程技术网

Compiler construction 将链式表达式建模到AST中 前言

Compiler construction 将链式表达式建模到AST中 前言,compiler-construction,expression,abstract-syntax-tree,sprache,superpower,Compiler Construction,Expression,Abstract Syntax Tree,Sprache,Superpower,我第一次尝试编写一个解释器/编译器。标记化和解析已经是一件事了,我似乎已经弄明白了。我仍然发现自己在挣扎,因为有些语言结构很难建模。请参阅我试图转换为抽象语法树的示例代码 class Class1 { var someVariable = true; } class Class2 { var instanceOf1 = new Class1(); func getSomething(): Class1 { return instanceOf1; } } class C

我第一次尝试编写一个解释器/编译器。标记化和解析已经是一件事了,我似乎已经弄明白了。我仍然发现自己在挣扎,因为有些语言结构很难建模。请参阅我试图转换为
抽象语法树的示例代码

class Class1 {
  var someVariable = true;
}

class Class2 {
  var instanceOf1 = new Class1();
  func getSomething(): Class1 {
    return instanceOf1;
  }
}

class Class3 {
  func assignFromChainedExpressions() {
    var result = new Class2().getSomething().someVariable;
                 -----------1 -------------2 -----------3
  }

  func assignToChainedExpressions() {
    new Class2().getSomething().someVariable = false;
    -----------4 -------------5 -----------6
  }
}
带下划线的表达式在
AST
中建模为:

1,4: ClassInstantiation
2,5: MethodCall
4,6: VariableAccess

问题: A.链接的
表达式
是否应建模为数组?它们是否应相互嵌套?对于以后的评估和遍历,最实用的模型是什么

B.
函数中
分配给链表达式
中,如果第一个
表达式
是一个
类设置
,则将值分配给链是否有意义?我想,
实例
本身将在运行时被丢弃

C.大多数示例使用非常简单的模型进行
赋值操作。见:

类赋值{字符串标识符{get;}表达式{get;}
如果操作的左侧也是一个
表达式
,那么应该如何对更复杂的赋值进行建模


Edit1:

assignFromChainedExpressions
进行如下建模是一个好主意:

AnonymousVariableDeclaration(value: new Class2())          // anon1
AnonymousVariableDeclaration(value: anon1.getSomeThing())  // anon2
VariableDeclaration(name: "result", value: anon2.someVariable);
AnonymousVariableDeclaration(value: new Class2())          // anon1
AnonymousVariableDeclaration(value: anon1.getSomeThing())  // anon2
Assign(anon2.someVariable, false)
像这样建模
分配到链表达式是不是一个好主意:

AnonymousVariableDeclaration(value: new Class2())          // anon1
AnonymousVariableDeclaration(value: anon1.getSomeThing())  // anon2
VariableDeclaration(name: "result", value: anon2.someVariable);
AnonymousVariableDeclaration(value: new Class2())          // anon1
AnonymousVariableDeclaration(value: anon1.getSomeThing())  // anon2
Assign(anon2.someVariable, false)

嵌套版本似乎更常见。代码有意义吗?不是真的,但这并不意味着你不应该允许。像这样的代码在我所知道的任何语言中都是合法的(当然,没有对象或赋值的语言除外)。常见的解决方案是使左操作数也成为一个表达式,然后拒绝任何在语义分析期间无法赋值的表达式。您还可以定义一个
LValue
类,该类仅表示可分配给的表达式,然后在解析器操作中直接拒绝非l值的表达式。@sepp2k非常感谢您的帮助!提出了一些好的观点。请看一下
Edit1
我不太确定
匿名变量声明
在您的编辑中起什么作用。
new Class2().getSomething().someVariable
的AST应该是这样的:然后您可以使用该AST作为
VariableDeclaration
中的值,或者分别作为
Assign
中的左操作数。对于
形式的表达式,我有一种类型的表达式(即“显式”字段访问)另一个用于
形式的表达式(即访问局部或全局范围内的变量,或访问
上的隐式字段)。对于后一种类型的变量访问,将由语义分析来确定访问的变量属于哪个范围。顺便说一句,对于此类问题有帮助的是查看真实编译器生成的AST并查看它们的功能。对于C#来说,有用于VisualStudio的Roslyn语法可视化工具,还有一个。