我正在编写基于VBScript的脚本的语法。
在脚本中,变量赋值以i=10
的常规方式完成,另外还有以下变体:Set i=10
方法调用可以通过多种方式在对象上调用方法来完成,例如:
Another(10).Call(20).Chain(30)
我认为'Set'是我语法中的关键词。但是,在某些预定义的calsses中,开发人员可以将方法命名为“Set”,因此,可能会调用(我将其标记为line A
):
Another(10).Call(20,30).Set 40,50
我的语法:
definition: body EOF;
body: NL_WS* bodyElement NL_WS*;
bodyElement: statement (NL_WS+ statement)* ;
statement: assignment | chainCall;
assignment: (START_SET)? IDENTIFIER WS? EQUALS WS? (chainCall | VALID_NUMBER) ;
chainCall: methodCall ('.' methodCall)* ;
methodCall: IDENTIFIER WS? LPAREN? WS? argumentList? WS? RPAREN?;
argumentList: VALID_NUMBER (WS? COMMA WS? VALID_NUMBER)* ;
START_SET: 'Set' WS;
VALID_NUMBER: [1-9] NUMBER? ;
IDENTIFIER: LETTER LETTER_OR_DIGIT*;
LETTER: [a-zA-Z_];
NUMBER: [0-9];
LETTER_OR_DIGIT: [a-zA-Z0-9_];
EQUALS: '=' ;
LPAREN: '(';
RPAREN: ')';
COMMA: ',';
NL_WS: WS? NEWLINE WS?;
NEWLINE: [\r\n];
WS: [ \t]+;
这在我标记为line A
(其中Set是对象内的方法调用)中失败:
line 10:24 mismatched input 'Set ' expecting IDENTIFIER
1)我无法理解为什么。我的想法是,在assignment
规则中,(START_SET)?
在开头定义,它应该期望在开头设置,因此,最后的方法调用应该与IDENTIFIER
匹配
2)当我尝试使用getCharPositionInLine
时,例如:
START_SET: {getCharPositionInLine() == 0}? 'Set' WS;
它工作正常,但是,我必须处理另一个问题。也就是说,在“Set”赋值之前可能会有前导空格,例如:
' Set k=10'
在这种情况下,它没有说:
line 16:8 mismatched input 'k' expecting {<EOF>, '.', NL_WS}
(在这种情况下,我认为它与chainCall
匹配而不是assignment
,这是可以理解的,因为它不是行中的第一个字符。)
那么,是否有一种替代方法,就像'第一个字符在行中减去空格'?
我也试过了,START_SET: {getCharPositionInLine() == 0}? WS? 'Set' WS;
认为最初的WS?
会覆盖第一个字符,但我得到同样的错误。
感谢任何帮助。
答案 0 :(得分:0)
我找到了解决此问题的方法。我写了一个所谓的预处理器,它删除了一行中的所有前导空格,然后由ANTLR解析。这样我就可以成功使用{getCharPositionInLine() == 0}
。
此外,这有助于保持语法更简单。
HTH。