我在理解'reportAttemptingFullContext'和'reportContextSensitivity'时遇到了一些麻烦,并且在我的语法中避免了这些问题。这是一个例子:
IF L_COUNT > 0 THEN
LINEFEED;
END IF;
这是我的语法摘录:
if_statement
:
IF plsql_condition THEN
seq_of_statements? elsif_statement* else_statement? END IF
;
plsql_condition
: expr_bool
;
expr_bool
:
expr_or (OR expr_or)*
;
expr_or
:
expr_and (AND expr_and)*
;
expr_and
:
NOT? expr_not
;
expr_not
:
expr_not_is |
expr_not_between |
expr_not_in |
expr_not_op |
expr_add
;
错误消息:
line 1:13 TIME: 2013-02-12 09:15:52.225, reportAttemptingFullContext d=116, rule='expr_not', input='L_COUNT > 0'
line 1:11 TIME: 2013-02-12 09:15:52.228,reportContextSensitivity d=116, rule='expr_not', input='L_COUNT >'
line 1:11 TIME: 2013-02-12 09:15:52.354, reportAttemptingFullContext d=120, rule='expr_not_op', input='>'
line 1:11 TIME: 2013-02-12 09:15:52.355,reportContextSensitivity d=120, rule='expr_not_op', input='>'
整个语法非常大。这是一个简单的例子。每次我有替代方案时基本上都会出现问题(如上面'expr_not')。我该如何避免这些?我尝试过使用语义谓词,但只有在代码生成时固定规则中令牌的位置时,这才有可能(据我所知)。在以下代码中进行注释时(更复杂的示例):
COLUMN FORMAT FORMAT.PRICE(OBJ_CURRY(TOP.STRIKE_CURRY_ID).RD(TOP.INTR_PAY * (TOP.NOTE_RATIO * L_ALLOC)),TOP.STRIKE_CURRY_ID);
我将解析时间乘以20;这是相当痛苦的。在这种情况下,我也得到一个'reportAttemptingFullContext'。
我的问题: 如何在备选方案中避免使用'reportAttemptingFullContext'。
感谢您的帮助。 亲切的问候,WolfgangHämmer
答案 0 :(得分:2)
完整上下文解析的唯一问题是潜在的性能影响(取决于它所需的频率以及解决SLL冲突所需的前瞻性)。如果您的语法在SLL模式下是明确的,那么ANTLR书中描述的两阶段解析策略(带one implementation here)将阻止对不包含语法错误的所有源文件进行全上下文解析。两阶段解析始终产生与启用完全上下文的解析相同的最终结果,但是对于满足以下属性的语法+输入获得了主要的性能优势。
PredictionMode.SLL
和PredictionMode.LL
提供了相同的解析树(请参阅PredictionMode
枚举)。