ANTLR4中的上下文敏感的空白处理

时间:2015-03-12 12:49:16

标签: parsing antlr antlr4

我试图在ANTLR4中实现表达式/公式语言,并且遇到空白处理问题。在大多数情况下,我不关心空白,所以我有"标准"词法分析器将其发送到HIDDEN频道,即

// Whitespace
WS
    :   ( ' ' | '\t' |'\r' | '\n' ) -> channel(HIDDEN)
    ;

但是我有一个运算符在之前或之后都不允许空格,并且我无法在不更改WS词法分析器规则的情况下看到如何处理这种情况,以便将空格留在默认通道中并具有我所有其他解析器规则中的显式WS?术语(其中有很多)。

作为简化示例,我为假想谓词语言创建了以下语法:

grammar Logik;

/*
 * Parser Rules
 */

ruleExpression
    :   orExpression
    ;

orExpression
    :   andExpression ( 'OR' andExpression)*
    ;

andExpression
    :   primaryExpression ( 'AND' primaryExpression)*
    ;

primaryExpression
    :   variableExpression
    |   '(' ruleExpression ')'
    ;

variableExpression
    :   IDENTIFIER ( '.' IDENTIFIER )*
    ;

/*
 * Lexer Rules
 */

IDENTIFIER
    :   LETTER LETTERORDIGIT*
    ;

fragment LETTER : [a-zA-Z_];
fragment LETTERORDIGIT : [a-zA-Z0-9_];

// Whitespace
WS
    :   ( ' ' | '\t' |'\r' | '\n' ) -> channel(HIDDEN)
    ;

就目前而言,这会成功解析A OR B AND C.DA OR B AND C. D - 我需要的是.运算符不允许空格,以便第二个表达式无效

2 个答案:

答案 0 :(得分:3)

您可以从其他渠道获取令牌:

variableExpression
  :   IDENTIFIER ( '.' {_input.get(_input.index() -1).getType() != WS}? IDENTIFIER )*
  ;

A OR B AND C.D没问题,

A OR B AND C. D会打印错误

答案 1 :(得分:1)

您可以使用词法分析器谓词来执行前瞻(后面)并为''创建专用令牌。 。在您的示例中,它看起来像这样:

grammar Logik;

/*
 * Parser Rules
 */

ruleExpression
    :   orExpression
    ;

orExpression
    :   andExpression ( 'OR' andExpression)*
    ;

andExpression
    :   primaryExpression ( 'AND' primaryExpression)*
    ;

primaryExpression
    :   variableExpression
    |   '(' ruleExpression ')'
    ;

variableExpression
    :   IDENTIFIER ( POINT IDENTIFIER )*
    ;

/*
 * Lexer Rules
 */

POINT : {_input.LA(-1) != ' ' && _input.LA(2) != ' '}? '.';
IDENTIFIER
    :   LETTER LETTERORDIGIT*
    ;

fragment LETTER : [a-zA-Z_];
fragment LETTERORDIGIT : [a-zA-Z0-9_];

// Whitespace
WS
    :   ( ' ' | '\t' |'\r' | '\n' ) -> channel(HIDDEN)
    ;

这样,A OR B AND C.D即可,而A OR B AND C. D会出现错误(A OR B AND C .D),如:token recognition error at: '.' ...

有可能使用HIDDEN_CHANEL和语义谓词进入语法规则部分。但是,如果您有多次相同的约束,则必须在每个语法规则中编写谓词,其中应该启用约束。

相关问题