将getCharPositionInLine()与ANTLR4中的前导空格一起使用

时间:2016-01-21 15:24:53

标签: antlr4

我正在编写基于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?会覆盖第一个字符,但我得到同样的错误。

感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

我找到了解决此问题的方法。我写了一个所谓的预处理器,它删除了一行中的所有前导空格,然后由ANTLR解析。这样我就可以成功使用{getCharPositionInLine() == 0}。 此外,这有助于保持语法更简单。 HTH。