有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

混合中带有注释的java ANTLR4标记图像连接

我想为某种语言写一个ANTLR4词法。我有一个有效的,但我并不完全满意

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

keyword + {}

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

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

我目前的lexer语法:

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"\\])
      )* 
    '"'
;

我是不是试图在lexer内部做太多的事情,应该把我目前拥有的东西输入解析器,让它来处理上面的混乱

Edit01

多亏了280Z28,我决定通过去掉我的STRING标记,简单地解决QUOTED_STRINGUNQUOTED_STRING和操作符CONCAT来修复上面的lexer语法。其余的将在解析器中处理。我还添加了一个额外的lexer模式,以便区分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 : '+';

共 (0) 个答案