在 ANTLR 语法中使用不同的 case 关键字

发布于 2024-12-27 01:59:10 字数 1316 浏览 3 评论 0原文

我的语法中的一些关键字(字符串常量)包含大写字母 例如,

PREV_VALUE : 'PreviousValue';

这会导致奇怪的解析行为:包含相同大写字母('P','V')的其他标记被错误地解析。

这是词法分析器语法的简化版本:

lexer grammar ExpressionLexer;

COMMA : ',';
LPAREN : '(';
RPAREN : ')';
LBRACK : '[';
RBRACK : ']';
PLUS : '+';
MINUS : '-';
MULT : '*';
DIV : '/';
PREV_VALUE : 'PreviousValue';
fragment DIGIT : ('0'..'9');
fragment LETTER : ('a'..'z'|'A'..'Z'|'_');
fragment TAB : ('\t') ;
fragment NEWLINE : ('\r'|'\n') ;
fragment SPACE : (' ') ;

当我尝试解析这样的表达式时:

var expression = "P"; //Capital 'P' which included to the keyword 'PreviousValue'
var stringReader = new StringReader(expression);
var input = new ANTLRReaderStream(stringReader);
var expressionLexer = new ExpressionLexer(input);
var tokens = new CommonTokenStream(expressionLexer);

tokens._tokens 集合包含一个值

[0] = {[@0,1:1='<EOF>',<-1>,1:1]}

这是不正确的。

如果我将表达式更改为“p”(小写字母) tokens._tokens 集合包含两个值

[0] = {[@0,0:0='p',<0>,1:0]}
[1] = {[@1,1:1='<EOF>',<-1>,1:1]}

这是正确的。

当字符串 PREV_VALUE : 'PreviousValue'; 从语法中删除时,两个表达式都会被正确解析。

是否可以在关键字中使用不同的大小写? ANTLR语法中有使用此类关键字的例子吗?

Some keywords (string constant) in my grammar contain capital letters
e.g.

PREV_VALUE : 'PreviousValue';

This causes strange parsing behavior: other tokens that contain same capital letters ('P','V') are parsed incorrectly.

Here's a simplified version of the lexer grammar:

lexer grammar ExpressionLexer;

COMMA : ',';
LPAREN : '(';
RPAREN : ')';
LBRACK : '[';
RBRACK : ']';
PLUS : '+';
MINUS : '-';
MULT : '*';
DIV : '/';
PREV_VALUE : 'PreviousValue';
fragment DIGIT : ('0'..'9');
fragment LETTER : ('a'..'z'|'A'..'Z'|'_');
fragment TAB : ('\t') ;
fragment NEWLINE : ('\r'|'\n') ;
fragment SPACE : (' ') ;

When I try parsing such expression:

var expression = "P"; //Capital 'P' which included to the keyword 'PreviousValue'
var stringReader = new StringReader(expression);
var input = new ANTLRReaderStream(stringReader);
var expressionLexer = new ExpressionLexer(input);
var tokens = new CommonTokenStream(expressionLexer);

tokens._tokens collection contains one value

[0] = {[@0,1:1='<EOF>',<-1>,1:1]}

It's incorrect.

If I change expression to 'p' (lowercase letter)
tokens._tokens collection contains two values

[0] = {[@0,0:0='p',<0>,1:0]}
[1] = {[@1,1:1='<EOF>',<-1>,1:1]}

It's correct.

When string PREV_VALUE : 'PreviousValue'; is removed from grammar, both expressions are parsed correctly.

Is it possible to use different case in keywords?
Is there any example of using such keywords in ANTLR grammar?

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

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

发布评论

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

评论(1

青瓷清茶倾城歌 2025-01-03 01:59:10

我发现很难相信 p 标记是根据您发布的语法创建的。前面有 fragment 的词法分析器规则不会生成标记:这些规则仅由其他词法分析器规则使用。

一个简单的演示展示了这一点:

lexer grammar ExpressionLexer;

@lexer::members {
  public static void main(String[] args) throws Exception {
    ExpressionLexer lexer = new ExpressionLexer(new ANTLRStringStream(args[0]));
    CommonTokenStream tokens = new CommonTokenStream(lexer);
    tokens.fill(); // remove this line when using ANTLR 3.2 or an older version
    System.out.println(tokens);
  }
}

COMMA : ',';
LPAREN : '(';
RPAREN : ')';
LBRACK : '[';
RBRACK : ']';
PLUS : '+';
MINUS : '-';
MULT : '*';
DIV : '/';
PREV_VALUE : 'PreviousValue';
fragment DIGIT : ('0'..'9');
fragment LETTER : ('a'..'z'|'A'..'Z'|'_');
fragment TAB : ('\t') ;
fragment NEWLINE : ('\r'|'\n') ;
fragment SPACE : (' ') ;

现在生成词法分析器并编译 .java 源文件:

java -cp antlr-3.3.jar org.antlr.Tool ExpressionLexer.g 
javac -cp antlr-3.3.jar *.java

并运行一些测试:

java -cp .:antlr-3.3.jar ExpressionLexer p
line 1:0 no viable alternative at character 'p'

这是正确的,因为没有以 开头或匹配的(非片段)规则,一个“p”

java -cp .:antlr-3.3.jar ExpressionLexer P
line 1:1 mismatched character '' expecting 'r'

这是正确的,因为以 "P" 开头的唯一(非片段)规则期望 "r" 是下一个字符(不存在) 。

I find it hard to believe a p token is created based on the grammar you posted. Lexer rules that have fragment in front of them will not produce tokens: these rules are only used by other lexer rules.

A simple demo shows this:

lexer grammar ExpressionLexer;

@lexer::members {
  public static void main(String[] args) throws Exception {
    ExpressionLexer lexer = new ExpressionLexer(new ANTLRStringStream(args[0]));
    CommonTokenStream tokens = new CommonTokenStream(lexer);
    tokens.fill(); // remove this line when using ANTLR 3.2 or an older version
    System.out.println(tokens);
  }
}

COMMA : ',';
LPAREN : '(';
RPAREN : ')';
LBRACK : '[';
RBRACK : ']';
PLUS : '+';
MINUS : '-';
MULT : '*';
DIV : '/';
PREV_VALUE : 'PreviousValue';
fragment DIGIT : ('0'..'9');
fragment LETTER : ('a'..'z'|'A'..'Z'|'_');
fragment TAB : ('\t') ;
fragment NEWLINE : ('\r'|'\n') ;
fragment SPACE : (' ') ;

Now generate the lexer and compile the .java source file:

java -cp antlr-3.3.jar org.antlr.Tool ExpressionLexer.g 
javac -cp antlr-3.3.jar *.java

and run a few tests:

java -cp .:antlr-3.3.jar ExpressionLexer p
line 1:0 no viable alternative at character 'p'

which is correct since there is no (non-fragment) rule that starts with, or matches, a "p".

java -cp .:antlr-3.3.jar ExpressionLexer P
line 1:1 mismatched character '' expecting 'r'

which is correct since the only (non-fragment) rule that starts with a "P" expects an "r" to be the next character (which isn't there).

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