C:值vs类型vs表达式

C:值vs类型vs表达式,c,compiler-construction,C,Compiler Construction,假设我想用一些OO语言构建一个C编译器,所以我创建了一些类,比如范围,对象,左值,类型,指针,表达式,等等 我需要了解的是类型、值、表达式和对象之间的确切关系。因为有些C参考表示: 表达式的计算结果为左值 在其他地方,您可以阅读以下内容: 左值是一个表达式 那么,C概念之间到底有什么关系呢 对于二进制表达式,比如说加法a+b,a和b操作数就是这些表达式吗?还是物体?或者只是类型,可能是对象,也可能不是对象 考虑一个简单的代码: int a = 1; a++; a++是表达式语句,对吗 a++

假设我想用一些OO语言构建一个C编译器,所以我创建了一些类,比如
范围
对象
左值
类型
指针
表达式
,等等

我需要了解的是类型、值、表达式和对象之间的确切关系。因为有些C参考表示:

表达式的计算结果为左值

在其他地方,您可以阅读以下内容:

左值是一个表达式

那么,C概念之间到底有什么关系呢

对于二进制表达式,比如说加法
a+b
a
b
操作数就是这些表达式吗?还是物体?或者只是类型,可能是对象,也可能不是对象

考虑一个简单的代码:

int a = 1;
a++;
  • a++是表达式语句,对吗
  • a++
    是表达式,带有后缀增量运算符,对吗
  • a
    ,那么什么是
    a
    ?它是表达式、对象还是左值?或者,
    a
    是一个计算为左值的表达式,并且这个左值具有关联的对象和类型

EDIT:我正在编写一个库(称为
jsc
),允许“用JavaScript编写C”

考虑以下C函数:

void main() {
    int a = 100;
    int b = 200;
    int c = 300;
    return a + (b + c);
}
使用JavaScript中的
jsc
builder界面,您可以这样编写该函数:

var _ = require('jsc').Builder.context();

var main = _.func(_ => {
    var a = _.int(100);
    var b = _.int(200);
    var c = _.int(300);
    _.return(_.['+'](a, _['+'](b, c)));
});

console.log(main.compile());
内部
jsc
将生成如下内容:

var fs = new FunctionScope();

var a = new Object(Type.int(), 100);
var b = new Object(Type.int(), 200);
var c = new Object(Type.int(), 300);
fs.body.push(new Declaration(a));
fs.body.push(new Declaration(b));
fs.body.push(new Declaration(c));

var pa = new PrimaryExpression(a);
var pb = new PrimaryExpression(b);
var pc = new PrimaryExpression(c);
var expr1 = new AdditionExpression(pb, pc);
var expr2 = new AdditionExpression(pa, expr1);
fs.body.push(new ReturnStatement(expr2));

var codegen = new Codegen();
var bin = codegen.compileFunction(fs);
console.log(bin);
我需要了解的是类型、值、表达式和对象之间的确切关系是什么

表达式具有类型,并计算为值。对象包含的数据在解释为特定类型时可能表示值(可能是因为对象可能未初始化或包含无效数据)。左值(是表达式的一种类型)引用对象。引用标准中的相关定义:

3.15

对象

执行环境中的数据存储区域,其内容可以表示值

3.19

当解释为具有特定类型时,对象内容的精确含义

6.3.2.1左值、数组和函数指示符

左值是一个表达式(对象类型不是
void
),它可能指定一个对象


a++是表达式语句,对吗

是的,表达式语句是后跟分号的表达式(本标准第6.8.3节中的语法规则:“表达式声明:expressionopt
a++
是一个表达式,因此
a++是一个表达式语句

a++
是表达式,带有后缀增量运算符,对吗

对。语法的相关条款为“后缀表达式:后缀表达式++”、“后缀表达式:主要表达式”(第6.5.2节)和“主要表达式:标识符”(第6.5.1节)。因此,我们得到了
a++的以下派生(为了简洁起见跳过了表达式层次结构的一部分)

     expression-statement
   expression           ';'
   postfix-expression   ';'
postfix-expression '++' ';'
primary-expression '++' ';'
identifier         '++' ';'
'a'                '++' ';'
a
,那么什么是
a
?它是表达式、对象还是左值?或者,
a
是一个计算为左值的表达式,并且这个左值具有关联的对象和类型


语法上
a
是一个标识符,它是一个主表达式,它是一个表达式。从语义上讲,它是一个变量的名称,而变量是一个对象。如上所述,“左值是一个表达式(对象类型不是
void
),可能指定一个对象”(第6.3.2.1节),因此
a
也是一个
lvalue

每个左值都是一个表达式,并不是每个表达式都是左值的。你确定要用宝贵的时间再做一个C编译器吗?这东西很难弄对。@Vad这主要是因为没有人需要JavaScript中的C编译器。@Vad呃,我对此表示怀疑。看起来更像是XY问题。我很有信心,因为在现实生活中没有人会这么做,这对于一个任务来说是非常重要的,@BaummitAugen不,这绝对不是XY问题,我在现实生活中这么做,其实并不难,难的部分显然是优化机器代码,这是一个独立的问题。值有一个类型,表达式产生值。您的答案可能是链接到C标准的注释(可能是更简单、更有用的方法)@Olaf表达式具有类型,这些类型确定如何将给定对象解释为值(来自6.2.5。值:“存储在对象中或由函数返回的值的含义由用于访问它的表达式的类型决定。”).是的,我本可以发布一个标准的链接,这当然会少一些努力,但a)我不认为总结和引用相关章节比…不这样做更有帮助,b)问题不应该在评论中得到回答,因为这样问题会一直以未回答的问题出现。嗯,这对我来说是正确的左值。非左值表达式只产生一个值,值有类型。主要的问题是问题本身太广泛了。无论如何,应该阅读和理解标准,编译器的设计是一个意见问题。我没有说这个问题应该在评论中得到回答,但在网站规则中没有可接受的答案。我不会回答gree表示“表达式”的值“。如果表达式是左值,则其计算结果不是值。左值到右值的转换过程与评估是分开的,并且只在某些上下文中发生。那么您对下面的OO设计有何看法?我将有一个基本的
Expression
类,所有不同的表达式都将从该类继承。
表达式
类将有一个
.evaluate()