首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JavaScript/ECMAScript数组文字生成的LOOKAHEAD

JavaScript/ECMAScript数组文字生成的LOOKAHEAD
EN

Stack Overflow用户
提问于 2014-11-13 12:16:52
回答 3查看 125关注 0票数 1

目前,我使用ECMAScript 5.1实现了一个JavaScript/ JavaCC解析器,并且在ArrayLiteral生产中遇到了问题。

代码语言:javascript
复制
ArrayLiteral :
    [ Elision_opt ]
    [ ElementList ]
    [ ElementList , Elision_opt ]

ElementList :
    Elision_opt AssignmentExpression
    ElementList , Elision_opt AssignmentExpression

Elision :
    ,
    Elision ,

我有三个问题,我会一个一个地问他们。

这是第二个。

我已将此制作简化为以下形式:

代码语言:javascript
复制
ArrayLiteral:
    "[" ("," | AssignmentExpression ",") * AssignmentExpression ? "]"

请参阅第一个问题,即它是否正确:

如何简化JavaScript/ECMAScript数组的文字生成?

现在,我尝试在JavaCC中实现它,如下所示:

代码语言:javascript
复制
void ArrayLiteral() :
{
}
{
    "["
    (
        ","
    |   AssignmentExpression()
        ","
    ) *
    (
        AssignmentExpression()
    ) ?
    "]"
}

JavaCC抱怨,AssignmentExpression (其内容)不明确。显然,需要LOOKAHEAD规范。我花了很多时间试图找出LOOKAHEAD,尝试了不同的东西,比如

  • LOOKAHEAD (AssignmentExpression() ",") in (...)*
  • LOOKAHEAD (AssignmentExpression() "]") in (...)?

还有一些其他的变化,但我无法摆脱JavaCC的警告。

我不明白为什么这样做行不通:

代码语言:javascript
复制
void ArrayLiteral() :
{
}
{
    "["
    (
        LOOKAHEAD ("," | AssignmentExpression() ",")
        ","
    |   AssignmentExpression()
        ","
    ) *
    (
        LOOKAHEAD (AssignmentExpression() "]")
        AssignmentExpression()
    ) ?
    "]"
}

好的,AssignmentExpression()本身是模棱两可的,但是LOOKAHEAD中的尾随",""]"应该清楚地表明应该选择哪一个--还是我弄错了?

对于这个产品,正确的LOOKAHEAD 规范是什么样子的?

更新

不幸的是,这一做法没有奏效:

代码语言:javascript
复制
void ArrayLiteral() :
{
}
{
    "["
    (
        ","
    |
        LOOKAHEAD (AssignmentExpression() ",")
        AssignmentExpression()
        ","
    ) *
    (
        AssignmentExpression()
    ) ?
    "]"
}

警告:

代码语言:javascript
复制
Warning: Choice conflict in (...)* construct at line 6, column 5.
         Expansion nested within construct and expansion following construct
         have common prefixes, one of which is: "function"
         Consider using a lookahead of 2 or more for nested expansion.

第6行是第一个(之前的LOOKAHEAD。公共前缀"function"只是AssignmentExpression的一个可能的开始。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-11-14 05:28:36

这是另一种方法。它的优点是识别哪些逗号表示未定义的元素,而不使用任何语义操作。

代码语言:javascript
复制
void ArrayLiteral() : {} { "[" MoreArrayLiteral() }

void MoreArrayLiteral() : {} {
    "]"
|    "," /* undefined item */ MoreArrayLiteral()
|    AssignmentExpression() ( "]" |  "," MoreArrayLiteral() )
}
票数 1
EN

Stack Overflow用户

发布于 2014-11-13 15:43:35

JavaCC生成自顶向下的解析器。首先,我不喜欢自上而下的解析器生成器,所以我不是JavaCC专家,也没有方便的测试工具。

(编辑:,我认为其他东西会起作用,但后来我意识到,我不明白JavaCC是如何对实际的选择进行展望的;就( A | B )* C而言,实际上有三种可能的选择: A、B和C。我以为它会考虑所有这三种选择,但有可能一次做到两种。因此,以下是另一种猜测。

话虽如此,我认为下面的方法是可行的,但它涉及到几乎每一个AssignmentExpression()解析两次。

代码语言:javascript
复制
{
    "["
    (
        ","
    |
        AssignmentExpression()
        ","
    ) *
    (
        LOOKAHEAD (AssignmentExpression() "]")
        AssignmentExpression()
    ) ?
    "]"
}

正如我在关联问题中指出的,更好的解决方案是以不同的方式重写产品:

代码语言:javascript
复制
"[" AssignmentExpression ? ("," AssignmentExpression ?) * "]"

这将导致一种单向查找语法,因此您将不需要LOOKAHEAD声明来处理它。

票数 2
EN

Stack Overflow用户

发布于 2014-11-13 20:18:10

我就是这样解决这个问题的(多亏了@rici的回答):

代码语言:javascript
复制
JSArrayLiteral ArrayLiteral() : 
{
    boolean lastElementWasAssignmentExpression = false;
}
{
    "["
    (
        (
            AssignmentExpression()
            {
                // Do something with expression
                lastElementWasAssignmentExpression = true;
            }
        ) ?
        (
            ","
            {
                if (!lastElementWasAssignmentExpression)
                {
                    // Do something with elision
                }
            }
            (
                AssignmentExpression()
                {
                    // Do something with expression
                    lastElementWasAssignmentExpression = true;
                }
            ) ?
        ) *
    )
    "]"
    {
        // Do something with results
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26908705

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档