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

时间:2019-03-04 10:53:26

标签: antlr antlr4

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

 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规则。

  

窗口_添加

它正在将其解析为winfunc,但我不希望有多余的空间。如何使Window_ADD解析为winfunc规则而不是Window_ADD?

1 个答案:

答案 0 :(得分:1)

您有两个选择:

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+;

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