有什么方法可以删除语法规则中不需要的 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+;
在这种情况下,函数的类型是在语义分析阶段确定的。
我正在尝试向我的 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+;
在这种情况下,函数的类型是在语义分析阶段确定的。