2014-11-21 1 views
0

Я заканчиваю свой ECMAScript 5.1/JavaScriptgrammar for JavaCC. Я выполнил все жетоны и постановления в соответствии со спецификацией.Как реализовать автоматическую вставку точки с запятой JavaScript в JavaCC?

Теперь у меня возникает большой вопрос, который я не знаю, как решить.

JavaScript имеет этот хороший функцию автоматической вставки точек с запятой:

What are the rules for JavaScript's automatic semicolon insertion (ASI)?

К quote the specifications, правила:

Есть три основных правила точкой с запятой вставка:

  1. Когда, как программа анализируется слева направо, маркер (называемый токеном-нарушителем) встречается, что не допускается любым производства грамматики, то точка с запятой автоматически вставляется перед токеном-нарушителем если один или несколько из следующих условий верно:

    • токен-нарушитель отделен от предыдущего токена по меньшей мере, одним КонцомСтроки.
    • Оскорбительный токен }.
  2. Когда, как программа анализируется слева направо, конец входного потока токенов, и парсер не в состоянии разбора лексем входного потока как единственный нетерминал Программа, затем точка с запятой автоматически вставлена ​​в конец входного потока .

  3. Когда, как программа анализируются слева направо, знак встречается, что допускаются некоторым производством грамматики, но производства является ограниченным производством и маркер будет первым маркером для терминал или нетерминал сразу после аннотацию [no LineTerminator here] в пределах ограниченного производства (и, следовательно, такой маркер называется ограниченный маркером), а ограничивается маркер отделен от предыдущих маркеров, по меньшей мере, один LineTerminator, то точка с запятой автоматически вставлен перед ограниченным токеном .

Однако, есть дополнительное условие наиважнейшая на предыдущих правилах: точка с запятой никогда не вставляется автоматически, если точку с запятой затем будет распознана как пустое заявление или если точка с запятой станет один из двух точки с запятой в заголовке оператора (см. 12.6.3).

Как я мог реализовать это с помощью JavaCC?

Замкнутой вещь ответа я нашел до сих пор является this grammar из Dojo Toolkit, который имеет JAVACODE части под названием insertSemiColon посвященной задачу. Но я не вижу, что этот метод называется где угодно (ни в грамматике, ни во всем коде jslinker).

Как я могу подойти к этой проблеме с JavaCC?

Смотрите также вопрос: (. Нет ответа там)

javascript grammar and automatic semocolon insertion

вопрос из комментариев:

Правильно ли сказать, что точки с запятой нужно вставлять только там, где синтаксически разрешены точки с запятой?

Я думаю, что было бы правильно сказать, что точка с запятой должен быть вставлен только там, где точка с запятой синтаксически требуется.

Соответствующая часть здесь §7.9:

7,9 Автоматической Запятая Вставка

Некоторые ECMAScript заявление (пустой оператор, переменное заявление, выражение оператор, то, в то время как заявления, продолжить заявление, заявление перерыва , return statement и оператор throw) должны быть завершены точкой с запятой. Такие точки с запятой могут всегда отображаться явно в исходном тексте. Однако для удобства такие точки с запятой могут быть опущены из исходного текста в определенных ситуациях. Эти ситуации описаны, говоря, что точки с запятой автоматически вставлены в токен исходного кода поток в этих ситуациях.

Давайте возьмем return заявление, например:

ReturnStatement : 
    return ; 
    return [no LineTerminator here] Expression ; 

Так (из моего понимания) синтаксически точка с запятой требуется, а не только позволили (как в вашем вопросе).

+0

Правильно ли сказать, что точка с запятой должен быть вставлен только там, где точка с запятой синтаксически разрешено? –

+0

@ TheodoreNorvell Я обновил свой вопрос, не могли бы вы увидеть обновление? Спасибо. – lexicore

+0

См. Также: http://stackoverflow.com/questions/15068782/automatic-semicolon-insertion-in-javascript-without-parsing – lexicore

ответ

1

В 3 правило для вставки точек с запятой можно найти в section 7.9.1 of the ECMAScript 5.1 standard

Я думаю, что правила 1 и 2 от стандарта могут быть обработаны с семантическим опережающим просмотром.

void PossiblyInsertedSemicolon() 
{} 
{ 
    LOOKAHEAD({semicolonNeedsInserting()}) {} 
| 
    ";" 
} 

Итак, когда нужно вставить точку с запятой?Когда один из них является истинным

  • Когда следующая лексема не является точкой с запятой, и на другой линии (getToken(1).kind != SEMICOLON && getToken(0).endLine < getToken(1).beginLine)
  • Когда следующая лексема является правая скобка.
  • Когда следующий маркер EOF

Так что нам нужно

boolean semicolonNeedsInserting() { 
    return (`getToken(1).kind != SEMICOLON && getToken(0).endLine < getToken(1).beginLine`) 
    || getToken(1).kind == RBRACE 
    || getToken(1).kind == EOF ; 
} 

Это заботится о правилах 1 и 2 стандарта.

Для правила 3 ​​(ограниченные производства), как указано в моем ответе this question, вы можете сделать следующее

void returnStatement() 
{} 
{ 
    "return" 
    [ // Parse an expression unless either the next token is a ";", "}" or EOF, or the next token is on another line. 
     LOOKAHEAD({ getToken(1).kind != SEMICOLON 
        && getToken(1).kind != RBRACE 
        && getToken(1).kind != EOF 
        && getToken(0).endLine == getToken(1).beginLine}) 
     Expression() 
    ] 
    PossiblyInsertedSemicolon() 
} 
+0

Вы, скорее всего, правы. Я вижу нечто подобное в этой грамматике (https://code.google.com/p/yaji-ecmascript-interpreter/source/browse/trunk/yaji-ecmascript-interpreter/src/FESI/Parser/EcmaScript.jjt) , Только проверка EOL выполняется по-разному (через специальный токен). Я попробую и расскажу позже. – lexicore

+0

Я думаю, что когда вы попробуете, вы обнаружите, что существует множество предупреждений о неоднозначности. Это будет раздражать. Однако лучше иметь грамматику, которая проста и работает, чем одна, свободная от предупреждений, но некорректная или сложная. –

+0

Не могли бы вы объяснить, что вы подразумевали под *, когда вы пытаетесь ** это ***? Вы имели в виду ваш подход или один из [этой грамматики] (https://code.google.com/p/yaji-ecmascript-interpreter/source/browse/trunk/yaji-ecmascript-interpreter/src/FESI/Parser/ EcmaScript.jjt). [Моя собственная грамматика] (https://github.com/highsource/javascript-codemodel/blob/master/parser/src/main/javacc/ecmascript-262.jj) без предупреждения на данный момент (спасибо вам, кстати), но я еще не закончил. Автоматическая точка с запятой - одна из оставшихся проблем, а регулярные выражения - другие – lexicore