我正在与第三方解析器一起使用具有数组和结构的编程语言。假设Str是一个结构类型变量,包含一个名为A的数组,并且我是一个整数变量,对于以下表达式:
Str.A[I]
解析器生成以下表达式树(伪代码):
StructMember
(
Left = "Str"
Right = ArraySubscript
(
Left = "A"
Right = "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"
)
)
从执行顺序的角度来看,这也没有多大意义。
答案 0 :(得分:1)
可能有助于考虑我们可能需要哪些简单的信息:
X[i]
在这里,我希望解析树看起来像:
ArraySubscript
(
Left = "X"
Right = "i"
)
因此,对于数组,您需要完全属性Left和Right。 对于结构成员的引用,我希望左侧引用解析树的结构和右侧来引用struct属性。例如,假设struct属性是一个简单类型(如整数),那么StructMember可能如下所示:
StructMember
(
Left = "Str"
Right = "simple"
)
指的是:
Str.simple
您看到的结果与如何考虑每个属性的简单细分一致。
答案 1 :(得分:0)
在大多数语言中,成员访问运算符的右操作数将是标识符,而不是表达式。这个语法看起来像这样:
expression ::=
...
| expression '.' identifier
在这种情况下,你得到的AST不符合语法。事实上,right
节点的StructMember
成员甚至不应该有expression
类型,而是键入string
(或者用于表示标识符的任何内容)。
您获得的树将等同于Str.(A[I])
,根据该语法,它甚至不是有效的语法。
理论上,您语言的语法可能会像这样:
expression ::=
...
| expression '.' expression
如果是这种情况,Str.(A[I])
将是有效的语法,如果.
的优先级低于数组下标的优先级,Str.A[I]
确实会被解析为Str.(A[I])
,让你得到正确的树。这将是非常不寻常的,在评论中你说,据你所知,事实并非如此。
因此,我们必须假设您的语言语法看起来像我展示的第一个语法,并且您的解析器要么是错误的,要么不是为了给出与语法完全匹配的树。