Parsing 分析结构引用中的数组

Parsing 分析结构引用中的数组,parsing,compiler-construction,abstract-syntax-tree,Parsing,Compiler Construction,Abstract Syntax Tree,我正在为一种具有数组和结构的编程语言使用第三方解析器。假设Str是一个结构类型变量,其中包含一个名为a的数组,I是一个整数变量,对于以下表达式: Str.A[I] 解析器生成以下表达式树(伪代码): 我还期待着别的事情: ArraySubscript ( Left = StructMember ( Left = "Str" Right = "A" ) Right = "I" ) 因为在执行或生成代码时,首先解析结构成员,然后执行

我正在为一种具有数组和结构的编程语言使用第三方解析器。假设Str是一个结构类型变量,其中包含一个名为a的数组,I是一个整数变量,对于以下表达式:

Str.A[I]
解析器生成以下表达式树(伪代码):

我还期待着别的事情:

ArraySubscript
(
    Left = StructMember
    (
        Left = "Str"
        Right = "A"
    )
    Right = "I"
)
因为在执行或生成代码时,首先解析结构成员,然后执行下标

从理论上讲,首先计算的操作在语法树中不应该比接下来计算的操作更深吗?换句话说,这种行为应该被认为是解析器中的错误吗

为rici编辑:如果StrA是一个结构数组,我得到的树如下:

StructMember
(
    Left = ArraySubscript
    (
        Left = "StrA"
        Right = "I"
    )
    Right = ArraySubscript
    (
        Left = "A"
        Right = "I"
    )
)
这是表达式StrA[I].A[I]的结果

EDIT2:对于表达式S.A[I].T,我得到以下结果:

StructMember
(
    Left = "S"
    Right = StructMember
    (
        Left = ArraySubscript
        (
            Left = "A"
            Right = "I"
        )
        Right = "T"
     )
 )

这从执行顺序的角度看也没有什么意义。

它可能有助于考虑我们可能需要的信息,例如:

X[i]

在这里,我希望解析树看起来像:

ArraySubscript
(
Left=“X”
Right=“i”
)

因此,对于数组,您需要的属性正好是Left和Right。 而对于对结构成员的引用,我希望左侧引用结构,右侧引用解析树的struct属性。例如,如果Stutt属性是一个简单类型,例如一个整数,那么StuttEnter成员可能看起来像这样:

expression ::=
    ...
    | expression '.' identifier
StructMember
(
Left=“Str”
Right=“简单”
)

指的是:

Str.simple


您所看到的结果与如何考虑每个属性的简单故障是一致的。

< P>在大多数语言中,成员访问运算符的右操作数将是一个标识符,而不是表达式。其语法如下所示:

expression ::=
    ...
    | expression '.' identifier
在这种情况下,你得到的AST不符合语法。事实上,
StructMember
节点的
right
成员甚至不应该有type
表达式,而是type
字符串
(或用于表示标识符的任何内容)

您得到的树相当于
Str.(A[I])
,根据该语法,它甚至不是有效的语法

从理论上讲,您的语言语法可能是这样的:

expression ::=
    ...
    | expression '.' expression
如果是这种情况,
Str.(A[I])
将是有效的语法,如果
的优先级低于数组下标的优先级,
Str.A[I]
将被解析为
Str.(A[I])
,从而使树正确。这将是非常不寻常的,你在评论中说,就你所知,情况并非如此


因此,我们必须假设您的语言的语法与我展示的第一个类似,并且您的解析器要么有缺陷,要么不打算给出与语法完全匹配的树。

我不相信。您的原始示例是无可挑剔的,但就我的具体情况而言,有两个看似可行的选项—上下标和上结构成员。问题是——理论认为哪一个是正确的。任一元素中的左和右都可以是表达式。请参见,A[I]不是结构成员。A是啊。我理解你的问题。问题的答案最终将由操作顺序和约束规则来解决。如果在解析结构属性成员身份时放置更高的操作优先级,则将得到结果。或者,如果你决定从右向左,你就会得到你的结果。如果从左向右解析或对数组引用放置更高的操作优先级,则将得到所看到的结果。这真的是一个语法如何定义的问题。除了从左到右,没有办法解决这样一个表达式<代码>A
仅存在于结构范围中;无法先解析[I],然后再查看
Str
。执行顺序是明确的。@SevaAlekseyev这里的“操作顺序”不是这个意思。该术语通常用于指优先级。例如,在
a+b*c
中,操作顺序告诉我们它相当于
a+(b*c)
,而不是
(a+b)*c
——它没有告诉我们计算
a
b
c
的顺序。如果
运算符将表达式作为其正确的操作数(这将是非常不寻常的),那么从理论上讲,运算顺序可以说明
Str.A[i]
Str.(A[i])
相同,其语义仍然可能是……您的语言是否允许您编写类似
Foo.(X+Y)的东西
作为
Foo.X+Foo.Y
的捷径?这对我来说也有点奇怪,但没有真正的ASTs理论。有时,解析需求(特别是在使用LL语法时)会迫使您使用一种不完全符合您需要的语法,然后需要在后续过程中调整AST。只是出于好奇,如果A是一个结构数组,那么S.A[I]会得到什么呢?@sepp2k:据我所知,不是这样。对我来说,你的“我期待”假设是错误的。AST应该按照输入语言的语法捕获语言输入,抽象出标点符号、空格等。代码生成、表达式计算等通常在后期使用自己的数据结构(由AST构建)进行。因此,在我看来,这不是解析器错误,因为您对AST用途的假设是不正确的。顺便说一句:如果没有具体说明你的问题的语言,你的问题是不清楚的,不能回答为@rici关于你的编辑所指出的“没有真正的ASTs理论”:你得到那棵树的表达是什么?我不认为你输入了相同的表达式