遇到ANTLR swallow_to_semi规则的问题

时间:2014-02-24 15:58:24

标签: java antlr

我试图用ANTLR解析几句话。我已经为此写了基本语法。

语法说每个句子都可以启动关键字'KEYWORDTYPE1'或'KEYWORDTYPE2' 每个句子以';'结尾。只有以“KEYWORDTYPE1”和“KEYWORDTYPE2”开头的句子之间的区别在于,对于第一个,我想要包含空格,而对于第二个,我想跳过所有空格。

grammar Hello;

options {
language = Java;
output   = AST;
}

sentence
:
(
'KEYWORDTYPE1' swallow_to_semi_with_whitespace SEMI
| 'KEYWORDTYPE2' swallow_to_semi_remove_whitespace SEMI
)*
;

swallow_to_semi_with_whitespace : ~(SEMI )+ ;
swallow_to_semi_remove_whitespace : ~(SEMI )+ ;

SEMI :';' ;
ID : ( 'a'..'z' | 'A'..'Z' )+ ;
INT : '0'..'9'+;
NEWLINE :('\r'? '\n')*;

WS
:
( ' ' | '\t')
 {
  $channel = HIDDEN;
 }
;

预期生成的树:

null
 0 KEYWORDTYPE1
 1  
 2 TRUE
 3  
 4  
 5 111
 6  
 7 FALSE
 8  
 9 FALSE
 10  
 11  
 12 FALSE
 13  
 14 FALSE
 15  
 16 ;
 17 KEYWORDTYPE2
 18 TRUE
 19 TRUE
 20 TRUE
 21 TRUE
 22 TRUE
 23 TRUE
 24 ;

但在两种情况下都使用当前的语法WHITESPACE。

你能否建议我应该做些什么改变?

2 个答案:

答案 0 :(得分:1)

您的问题措辞不当但如果我理解,您希望将空格发送给解析器。如果是这样,请从WS中删除该操作。此外,这条规则将“无”作为错误的选项:

NEWLINE :('\r'? '\n')*;

答案 1 :(得分:-1)

我已经通过声明来改变语法以维持Lexer的状态

private boolean insideStatement = false;

然后在 KEYWORDTYPE1和SEMI Lexer中添加 @after ,将insideStatement分别更改为 true false

最后的更改是WS Lexer规则更改为基于insideStatement发送到HIDDEN $ channel设置为true / false。

if (!insideStatement ) {
            $channel = HIDDEN;
        }

以下是完整的语法:

grammar Hello;

options {
 language = Java;
 output   = AST;
}

@lexer::members {
private boolean insideStatement = false;
}

statement
  :
  (
    KEYWORDTYPE1 swallow_to_semi SEMI
    | KEYWORDTYPE2 swallow_to_semi SEMI
  )*
  ;

KEYWORDTYPE1
@after {
insideStatement = true;
}
  :
  'KEYWORDTYPE1'
  ;

KEYWORDTYPE2
  :
  'KEYWORDTYPE2'
  ;

swallow_to_semi
  :
  ~(SEMI )+
  ;

SEMI
@after {
insideStatement = false;
}
  :
  ';'
  ;

ID
  :
  (
    'a'..'z'
    | 'A'..'Z'
  )+
  ;

INT
  :
  '0'..'9'+
  ;

NEWLINE
  :
  ('\r'? '\n')* 
                {
                 $channel = HIDDEN;
                }
  ;

WS
  :
  (
    ' '
    | '\t'
  )

   {
    if (!insideStatement ) {
        $channel = HIDDEN;
    }
   }
    ;