gpt4 book ai didi

java - ANTLR4 token 图像串联与混合中的注释

转载 作者:太空宇宙 更新时间:2023-11-04 07:37:56 25 4
gpt4 key购买 nike

我正在尝试为某种语言编写 ANTLR4 词法分析器。我已经有了一个可以工作的,但我对它并不完全满意。

keyword "my:little:uri" + /* my comment here */ ':it:is'
// nasty comment
+ ":mehmeh"; // single line comment

keyword + {}

这是该语言中的语句示例。它只是一堆关键字,后跟字符串参数,并以分号或子语句 block 结尾。字符串可以不加引号、单引号或双引号。带引号的字符串可以像上面的示例一样连接起来。包含加号 (+) 的不带引号的字符串是有效的。

我发现有问题的是评论。我想将关键字后面的任何内容识别为单个字符串标记,没有注释(和空格)。我通常使用 more 词法分析器命令,但我认为它不适用于上面的示例。有没有一种模式可以让我实现这样的目标?

我当前的词法分析器语法:

lexer grammar test;

@members {
public static final int CHANNEL_COMMENTS = 1;
}

WHITESPACE : (' ' | '\t' | '\n' | '\r' | '\f') -> skip;

SINGLE_LINE_COMMENT : '//' (~[\n\r])* ('\n' | '\r' | '\r\n')? -> channel(CHANNEL_COMMENTS);

MULTI_LINE_COMMENT : '/*' .*? '*/' -> channel(CHANNEL_COMMENTS);

KEYWORD : 'keyword' -> pushMode(IN_STRING_KEYWORD);

LBRACE : '{';
RBRACE : '}';
SEMICOLON : ';';

mode IN_STRING_KEYWORD;
STRING_WHITESPACE : WHITESPACE -> skip;
STRING_SINGLE_LINE_COMMENT : SINGLE_LINE_COMMENT -> type(SINGLE_LINE_COMMENT), channel(CHANNEL_COMMENTS);
STRING_MULTI_LINE_COMMENT : MULTI_LINE_COMMENT -> type(MULTI_LINE_COMMENT), channel(CHANNEL_COMMENTS);
STRING_LBRACE : LBRACE -> type(LBRACE), popMode;
STRING_SEMICOLON : SEMICOLON -> type(SEMICOLON), popMode;
STRING : ((QUOTED_STRING ('+' QUOTED_STRING)*) | UNQUOTED_STRING);
fragment QUOTED_STRING : (SINGLEQUOTED_STRING | DOUBLEQUOTED_STRING);
fragment UNQUOTED_STRING : (~[ \t;{}/*'"\n\r] | '/' ~[/*] | '*' ~['/'])+;
fragment SINGLEQUOTED_STRING : '\'' (~['])* '\'';
fragment DOUBLEQUOTED_STRING :
'"'
(
(~["\\]) |
('\\' [nt"\\])
)*
'"'
;

我是否可能试图在词法分析器内做太多事情,而应该将我当前拥有的内容提供给解析器并让它处理上述困惑?

编辑01

感谢 280Z28,我决定通过删除 STRING 标记并简单地使用 QUOTED_STRINGUNQUOTED_STRING 和运算符 CONCAT 来修复上述词法分析器语法。其余的将在解析器中处理。我还添加了一个额外的词法分析器模式,以区分 CONCATUNQUOTED_STRING

lexer grammar test;

@members {
public static final int CHANNEL_COMMENTS = 2;
}

WHITESPACE : (' ' | '\t' | '\n' | '\r' | '\f') -> skip;
SINGLE_LINE_COMMENT : '//' (~[\n\r])* -> channel(CHANNEL_COMMENTS);
MULTI_LINE_COMMENT : '/*' .*? '*/' -> channel(CHANNEL_COMMENTS);

KEYWORD : 'keyword' -> pushMode(IN_STRING_KEYWORD);

LBRACE : '{';
RBRACE : '}';
SEMICOLON : ';';

mode IN_STRING_KEYWORD;
STRING_WHITESPACE : WHITESPACE -> skip;
STRING_SINGLE_LINE_COMMENT : SINGLE_LINE_COMMENT -> type(SINGLE_LINE_COMMENT), channel(CHANNEL_COMMENTS);
STRING_MULTI_LINE_COMMENT : MULTI_LINE_COMMENT -> type(MULTI_LINE_COMMENT), channel(CHANNEL_COMMENTS);
STRING_LBRACE : LBRACE -> type(LBRACE), popMode;
STRING_SEMICOLON : SEMICOLON -> type(SEMICOLON), popMode;
QUOTED_STRING : (SINGLEQUOTED_STRING | DOUBLEQUOTED_STRING) -> mode(IN_QUOTED_STRING);
UNQUOTED_STRING : (~[ \t;{}/*'"\n\r] | '/' ~[/*] | '*' ~[/])+;
fragment SINGLEQUOTED_STRING : '\'' (~['])* '\'';
fragment DOUBLEQUOTED_STRING :
'"'
(
(~["\\]) |
('\\' [nt"\\])
)*
'"'
;

mode IN_QUOTED_STRING;
QUOTED_STRING_WHITESPACE : WHITESPACE -> skip;
QUOTED_STRING_SINGLE_LINE_COMMENT : SINGLE_LINE_COMMENT -> type(SINGLE_LINE_COMMENT), channel(CHANNEL_COMMENTS);
QUOTED_STRING_MULTI_LINE_COMMENT : MULTI_LINE_COMMENT -> type(MULTI_LINE_COMMENT), channel(CHANNEL_COMMENTS);
QUOTED_STRING_LBRACE : LBRACE -> type(LBRACE), popMode;
QUOTED_STRING_SEMICOLON : SEMICOLON -> type(SEMICOLON), popMode;
QUOTED_STRING2 : QUOTED_STRING -> type(QUOTED_STRING);
CONCAT : '+';

最佳答案

  • 不要在词法分析器中执行字符串连接。将 + 运算符作为运算符发送到解析器。这将使消除字符串和运算符之间出现的空格和/或注释变得容易。

    CONCAT : '+';
    STRING : QUOTED_STRING | UNQUOTED_STRING;
  • 您应该注意,ANTLR 4 将预定义的 HIDDEN channel 从 99 更改为 1,因此 HIDDENCHANNEL_COMMENTS 在您的语法中是相同的。

  • 请勿在 SINGLE_LINE_COMMENT 规则末尾包含行终止符。

    SINGLE_LINE_COMMENT
    : '//' (~[\n\r])*
    -> channel(CHANNEL_COMMENTS)
    ;
  • 您的 UNQUOTED_STRING token 当前包含集合 ['/']。如果您打算排除 ' 字符,则该集中的第二个 ' 是多余的,因此您可以使用 ['/]。如果您只想排除 /,则可以使用语法 [/]'/'

关于java - ANTLR4 token 图像串联与混合中的注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16520616/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com