Skip to content Skip to sidebar Skip to footer

How To Implement Javascript/ecmascript "no Lineterminator Here" Rule In Javacc?

I continue working on my JavaCC grammar for ECMAScript 5.1. It actually goes quite well, I think I've covered most of the expressions now. I have now two questions, both of them ar

Solution 1:

I think for the "restricted productions" you can do this

voidPostfixExpression() : 
{} {
     LeftHandSideExpression() 
     (
         LOOKAHEAD( "++", {getToken(0).beginLine == getToken(1).beginLine})
         "++"
     |
         LOOKAHEAD( "--", {getToken(0).beginLine == getToken(1).beginLine})
         "--"
     |
         {}
     )
}

Solution 2:

Update As Gunther pointed out, my original solution was not correct due to this paragraph in 7.4 of the spec:

Comments behave like white space and are discarded except that, if a MultiLineComment contains a line terminator character, then the entire comment is considered to be a LineTerminator for purposes of parsing by the syntactic grammar.

I'm posting a correction but leaving my original solution at the end of the question.

Corrected solution

The core idea, as proposed by Theodore Norvell is to use semantic lookahead. However I have decided to implement a more safe check:

publicstaticbooleanprecededByLineTerminator(Token token) {
    for (TokenspecialToken= token.specialToken; specialToken != null; specialToken = specialToken.specialToken) {
        if (specialToken.kind == EcmaScriptParserConstants.LINE_TERMINATOR) {
            returntrue;
        } elseif (specialToken.kind == EcmaScriptParserConstants.MULTI_LINE_COMMENT) {
            finalStringimage= specialToken.image;
            if (StringUtils.containsAny(image, (char)0x000A, (char)0x000D, (char)0x2028,
                    (char)0x2029)) {
                returntrue;
            }
        }
    }
    returnfalse;
}

And the grammar is:

expression = LeftHandSideExpression()
(
    LOOKAHEAD ( <INCR>, { !TokenUtils.precededByLineTerminator(getToken(1))} )
    <INCR>
    {
        return expression.postIncr();
    }
|   LOOKAHEAD ( <DECR>, { !TokenUtils.precededByLineTerminator(getToken(1))} )
    <DECR>
    {
        return expression.postDecr();
    }
) ?
{
    return expression;
}

So the ++ or -- are considered here iff they are not preceded by a line terminator.


Original solution

This not is how I finally solved it.

The core idea, as proposed by Theodore Norvell is to use semantic lookahead. However I have decided to implement a more safe check:

publicstaticbooleanprecededBySpecialTokenOfKind(Token token, int kind) {
    for (TokenspecialToken= token.specialToken; specialToken != null; specialToken = specialToken.specialToken) {
        if (specialToken.kind == kind) {
            returntrue;
        }
    }
    returnfalse;
}

And the grammar is:

expression = LeftHandSideExpression()
(
    LOOKAHEAD ( <INCR>, { !TokenUtils.precededBySpecialTokenOfKind(getToken(1), LINE_TERMINATOR)} )
    <INCR>
    {
        return expression.postIncr();
    }
|   LOOKAHEAD ( <DECR>, { !TokenUtils.precededBySpecialTokenOfKind(getToken(1), LINE_TERMINATOR)} )
    <DECR>
    {
        return expression.postDecr();
    }
) ?
{
    return expression;
}

So the ++ or -- are considered here iff they are not preceded by a line terminator.

Post a Comment for "How To Implement Javascript/ecmascript "no Lineterminator Here" Rule In Javacc?"