有什么方法可以删除语法规则中不需要的 space 吗?

Any method to remove unwanted space in grammar rule?

我正在尝试向我的 antlr 语法添加一种特殊类型的函数,称为 Window 函数。我的语法看起来像这样:

 stat: expression;
equation: expression relop expression;

expression:
    multiplyingExpression ((PLUS | MINUS) multiplyingExpression)*;

multiplyingExpression:
    powExpression ((TIMES | DIV) powExpression)*;

powExpression: signedAtom (POW signedAtom)?;

signedAtom:
    PLUS signedAtom
    | MINUS signedAtom
    | winfunc
    | func
    | iffunc
    | atom;

atom:
    scientific
    | string_literal
    | id
    | constant
    | LPAREN expression RPAREN;
string_literal: STRING;

scientific: SCIENTIFIC_NUMBER;

constant: PI | EULER | I;

variable: VARIABLE;

func: funcname LPAREN expression (COMMA expression)* RPAREN;
iffunc:
    'if' LPAREN equation COMMA expression COMMA expression RPAREN;
funcname: variable;

relop: EQ | GT | LT;

LPAREN: '(';

RPAREN: ')';

PLUS: '+';

MINUS: '-';

TIMES: '*';

DIV: '/';

GT: '>';

LT: '<';

EQ: '==';

COMMA: ',';

POINT: '.';

POW: '^';

id: '[' idx ']' {console.log($idx.text);};
idx:
    {(this.antlrHelper.isMetric(this.getCurrentToken().text))}? metricid
    | {(this.antlrHelper.isDimension(this.getCurrentToken().text))}? entityid
    | unknownid;
// metricid | entityid | unknownid;
metricid: VARIABLE;
entityid: VARIABLE;
unknownid: VARIABLE;
VARIABLE: VALID_ID_START VALID_ID_CHAR*;

fragment VALID_ID_START: ('a' .. 'z') | ('A' .. 'Z') | '_';

fragment VALID_ID_CHAR: VALID_ID_START | ('0' .. '9') | '.';

SCIENTIFIC_NUMBER: NUMBER ((E1 | E2) SIGN? NUMBER)?;

fragment NUMBER: ('0' .. '9')+ ('.' ('0' .. '9')+)?;

fragment E1: 'E';

fragment E2: 'e';

fragment SIGN: ('+' | '-');
STRING: '"' StringCharacters? '"';
fragment StringCharacters: StringCharacter+;
fragment StringCharacter: ~["\] | EscapeSequence;
// §3.10.6 Escape Sequences for Character and String Literals
fragment EscapeSequence: '\' [btnfr"'\] | OctalEscape;

fragment OctalEscape:
    '\' OctalDigit
    | '\' OctalDigit OctalDigit
    | '\' ZeroToThree OctalDigit OctalDigit;

fragment ZeroToThree: [0-3];
fragment OctalDigit: [0-7];
WS: [ \r\n\t]+ -> skip;

正在使用正常功能。对于 windows 函数,我添加了以下规则:

winfunc:
    WINDOW winfuncname LPAREN winMetricId COMMA scientific COMMA scientific RPAREN;

WINDOW: 'Window_';

winfuncname:
    variable;

winMetricId: '[' winMetricIdx ']';

winMetricIdx:
    {(this.antlrHelper.isMetric(this.getCurrentToken().text))}? metricid
    | otherid;

otherid: VARIABLE;

正在解析

Window_ADD

它正在将其解析为 func 规则,但我希望我的语法将其解析为 winfunc 规则。

Window_ ADD

它正在将其解析为 winfunc,但我不希望那里有额外的 space。如何让 Window_ADD 解析为 winfunc 规则而不是 Window_ ADD?

您有两个选择:

1. 如果您确切知道将使用哪些函数名称(终端),您可以简单地更改您的规则:

WINDOW: 'Window_';

WINDOW: 'Window_ADD';

如果你想添加更多的功能,比如说,Window_DEL,只需要在这个规则中再添加一个终端:

WINDOW: 'Window_' ('ADD' | 'DEL');

WINDOW: 'Window_'; WINDOW_ADD: WINDOW 'ADD'; WINDOW_DEL: WINDOW 'DEL';


2. 如果函数名称未知,您可能需要使用通配符来确定终端:

WINDOW: 'Window_' VALID_ID_CHAR+;

在这种情况下,函数的类型是在语义分析阶段确定的。