ANTLR - 带有空格的标识符

发布于 2024-11-26 12:53:19 字数 423 浏览 8 评论 0原文

我想要可以包含空格的标识符。

grammar WhitespaceInSymbols;

premise :   ( options {greedy=false;} : 'IF' )  id=ID{
System.out.println($id.text);
};

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

WS  :   ' '+ {skip();}
;

当我用“IF 语句分析”测试它时,我得到一个 MissingTokenException 和输出“IF 语句分析”。
我想,通过使用greedy = false我可以告诉ANTLR在'IF'之后退出并将其作为令牌。但 IF 是 ID 的一部分。 有办法实现我的目标吗?我已经尝试了贪婪=假选项的一些变体,但没有成功。

i want identifiers that can contain whitespace.

grammar WhitespaceInSymbols;

premise :   ( options {greedy=false;} : 'IF' )  id=ID{
System.out.println($id.text);
};

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

WS  :   ' '+ {skip();}
;

When i test this with "IF statement analyzed" i get a MissingTokenException and the output "IF statement analyzed".
I thought, that by using greedy=false i could tell ANTLR to exit afer 'IF' and take it as a token. But instead the IF is part of the ID.
Is there a way to achieve my goal? I already tried some variations of the greed=false-option, but without success.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

星軌x 2024-12-03 12:53:19

我想,通过使用greedy=false我可以告诉ANTLR在“IF”之后退出并将其作为令牌。

不,解析器对标记的创建没有任何说明:首先对输入进行标记,然后将解析器规则应用于这些标记。所以设置greedy=false没有效果。

可以这样做(创建带有空格的ID标记),但这将是一个可怕的解决方案,有许多谓词,并且词法分析器中的一些自定义方法进行手动查找 -前面:你真的、真的不想要这个!一种更简洁的解决方案是在解析器中引入一条 id 规则,并让它匹配一个或多个 ID 标记。

演示:

grammar WhitespaceInSymbols;

premise
  :  IF id THEN EOF
  ;

id
  :  ID+
  ;

IF
  :  'IF'
  ;

THEN
  :  'THEN'
  ;

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

WS  
  :  ' '+ {skip();}
  ;

将输入 IF 语句分析的 THEN 解析为以下树:

在此处输入图像描述

I thought, that by using greedy=false i could tell ANTLR to exit afer 'IF' and take it as a token.

No, the parser has nothing to say about the creation of tokens: the input is first tokenized and then the parser rules are applied on these tokens. So setting greedy=false has no effect.

You can do this (creating ID tokens with white spaces), but it will be a horrible solution with many predicates, and a few custom methods in the lexer doing manual look-aheads: you really, really don't want this! A much cleaner solution would be to introduce a id rule in your parser and let it match one or more ID tokens.

A demo:

grammar WhitespaceInSymbols;

premise
  :  IF id THEN EOF
  ;

id
  :  ID+
  ;

IF
  :  'IF'
  ;

THEN
  :  'THEN'
  ;

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

WS  
  :  ' '+ {skip();}
  ;

would parse the input IF statement analyzed THEN into the following tree:

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文