В продолжение http://blog.ptsecurity.com/2016/06/theory-and-practice-of-source-code.html#java--and-java8-grammars, Я пытаюсь уменьшить левую рекурсию в моей довольно сложной грамматике. Из того, что я понимаю, не примитивная форма рекурсии может привести к проблемам с производительностью как с точки зрения памяти, так и времени процесса.
Поэтому я пытаюсь реорганизовать эти правила в моей грамматике, чтобы использовать только "примитивную" рекурсию,Конечно, это сообщение в блоге - единственный раз, когда я видел фразу «примитивная» рекурсия по отношению к Antlr. Так что я просто догадываюсь о его значении / намерении. Мне кажется, это означает, что правило относится к самому себе как к lhs не более чем для одной ветви правила. Правильно?
На данный момент у меня есть правило выражения вроде:
expression
: expression DOUBLE_PIPE expression # ConcatenationExpression
| expression PLUS expression # AdditionExpression
| expression MINUS expression # SubtractionExpression
| expression ASTERISK expression # MultiplicationExpression
| expression SLASH expression # DivisionExpression
| expression PERCENT expression # ModuloExpression
...
;
* ...
включает в себя довольно много подправил, которые также ссылаются на expression
. Но это единственные с прямой рекурсией.
Если я правильно понимаю, рефакторинг их как "примитивной" рекурсии будет выглядеть примерно так:
expression
: binaryOpExpression # BinaryOpExpression
...
;
binaryOpExpression
: expression DOUBLE_PIPE expression # ConcatenationExpression
| expression PLUS expression # AdditionExpression
| expression MINUS expression # SubtractionExpression
| expression ASTERISK expression # MultiplicationExpression
| expression SLASH expression # DivisionExpression
| expression PERCENT expression # ModuloExpression
;
Во-первых, это правильный рефакторинг?
Во-вторых, это действительно поможет производительности? В конце концов, это все те же решения, поэтому я не совсем понимаю, как это помогает производительности (кроме может производить меньше объектов ATNConfig).
Спасибо