gpt4 book ai didi

parsing - VBScript语法: How to model sub call without parentheses

转载 作者:行者123 更新时间:2023-12-02 12:09:47 24 4
gpt4 key购买 nike

我正在为 VBScript 编写一个 GOLD 解析器语法。以下是摘录:

<CallStmt>             ::= 'Call' <CallExpr>
| <CallExpr> <ParameterList>
!| <CallExpr> '(' <Expr> ')'
| <CallExpr> '(' ')'

<AssignStmt> ::= <CallExpr> '=' <Expr>
| 'Set' <CallExpr> '=' <Expr>
| 'Set' <CallExpr> '=' 'New' <CallExpr>

<CallExpr> ::= '.' <LeftExpr>
| <LeftExpr>

<LeftExpr> ::= ID
| IDDot <LeftExpr>
| ID '(' <ParameterList> ')'
| ID '(' <ParameterList> ').' <LeftExpr>

!VBScript allows to skip parameters a(1,,2)
<ParameterList> ::= <Expr> ',' <ParameterList>
| ',' <ParameterList>
| <Expr>
|

! Value can be reduced from <Expr>
<Value> ::= <ConstExpr>
| <CallExpr>
| '(' <Expr> ')'

我对 <CallStmt> ::= <CallExpr> <ParameterList> 有冲突规则。该规则描述了在没有括号的情况下调用子函数。例如,以下语句在语法上是正确的:

obj.sub1(1, 2).sub2 1, 2
obj.sub1(1, 2).sub2(1),(2)
Call obj.sub1(1, 2).sub2(1, 2)

如何区分带括号的子调用 sub1(1, 2)以及参数 sub2(1),(2) 周围带有括号的子调用?

最佳答案

您遇到的问题是 VBScript 语法不明确。

哪个变体是 obj.sub1 (1) ?参数两边有括号的,还是没有且第一个参数恰好在括号内的?

如果我们不能判断,那么解析器也不能...我们只能在有多个参数时才能确定,例如一个逗号。因此,假设默认情况下,当我们遇到多个参数或根本没有参数时,我们选择仅使用括号作为参数。

在努力解决这个问题的过程中,您已经开始制作功能过度的终端,其中也包括点。这是一个坏主意,因为它不起作用(“.”周围的空格是允许的,但这些终端不匹配)并且可能导致意外的标记化行为和性能下降。通常,它表明您的语法存在问题。

这是我编写的语法,它可以很好地解析您的示例,并且实际上还应该正确处理赋值和构造函数调用。请注意 <ParameterList>只会匹配两个或多个参数,但不匹配零个或一个参数;这是解决导致问题的歧义的关键。

<CallStmt>    ::= 'Call' <CallPath>
| <CallPath>

<AssignStmt> ::= <AssignPath> '=' <Expr>
| 'Set' <AssignPath> '=' <Expr>
| 'Set' <AssignPath> '=' 'New' <CtorPath>

<CtorPath> ::= ID '.' <CtorPath>
| ID
| <CallExpr>
| ID <ParameterList>

<CallExpr> ::= ID '(' ')'
| ID '(' <Expr> ')'
| ID '(' <ParameterList> ')'

<CallPath> ::= <Member> '.' <CallPath>
| ID
| <CallExpr>
| ID <ParameterList>

<Member> ::= <CallExpr>
| ID

<MemberPath> ::= <Member> '.' <MemberPath>
| <Member>

<AssignPath> ::= <Member> '.' <AssignPath>
| ID

!VBScript allows to skip parameters a(1,,2)
<ParameterList> ::= <Expr> ',' <ParameterList>
| <Expr> ',' <Expr>
| <Expr> ','
| ',' <ParameterList>
| ','

! Value can be reduced from <Expr>
<Value> ::= NumberLiteral
| StringLiteral
| <MemberPath>
| '(' <Expr> ')'

!--- The rest of the grammar ---
"Start Symbol" = <Start>

{WS} = {Whitespace} - {CR} - {LF}
{ID Head} = {Letter} + [_]
{ID Tail} = {Alphanumeric} + [_]
{String Chars} = {Printable} + {HT} - ["]

Whitespace = {WS}+
NewLine = {CR}{LF} | {CR} | {LF}

ID = {ID Head}{ID Tail}*
StringLiteral = ('"' {String Chars}* '"')+
NumberLiteral = {Number}+ ('.' {Number}+ )?

<nl>  ::= NewLine <nl>          !One or more
| NewLine

<nl Opt> ::= NewLine <nl Opt>      !Zero or more
          | !Empty

<Start> ::= <nl opt> <StmtList>

<StmtList> ::= <CallStmt> <nl> <StmtList>
| <AssignStmt> <nl> <StmtList>
|

<Expr> ::= <Add Exp>

<Add Exp> ::= <Add Exp> '+' <Mult Exp>
| <Add Exp> '-' <Mult Exp>
| <Mult Exp>

<Mult Exp> ::= <Mult Exp> '*' <Negate Exp>
| <Mult Exp> '/' <Negate Exp>
| <Negate Exp>

<Negate Exp> ::= '-' <Value>
| <Value>

关于parsing - VBScript语法: How to model sub call without parentheses,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23830614/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com