我仍然在尝试使用ANTLR解析一个简单的Javadoc风格的格式。基本上,格式是这样的:
/**
* Description
*
* @name someId
*/我的解析器语法如下:
query_doc : BEGIN_QDOC description name NOMANSLAND* END_QDOC;
description : (DESCRIPTION_TEXT | NOMANSLAND)*;
name : OPEN_NAME INNER_WS NAMEID INNER_WS* CLOSE_NAME;我的词法分析器语法如下:
BEGIN_QDOC : '/**';
END_QDOC : ('*/');
NOMANSLAND : '\r'? '\n' (' ' | '\t')* '*' (' ' | '\t')*;
DESCRIPTION_TEXT : ~('\n');
OPEN_NAME : '@name' -> mode(NAME);
mode NAME;
INNER_WS : (' ' | '\t')+;
NAMEID : ('a'..'z' | 'A'..'Z' | '0'..'9' | '-' | '_' | '?')+;
CLOSE_NAME : (('\r'? '\n') | '*/') -> mode(DEFAULT_MODE);除了在以下情况下关闭@name定义之外,大多数情况下看起来工作正常:
/**
* @name someId*/上面的内容应该是完全有效的。在注释以“*/”结束之前,我们不应该需要换行。我遇到的问题是,'*/‘成功地终止了名称定义,但它使用了令牌,并且只返回到默认模式,因此我需要:
/**
* @name someId*/*/如果我真的想让它结束评论。我希望它返回到默认模式,然后意识到这个标记应该结束注释(即它应该与END_QDOC匹配)。我如何在ANTLR中实现这一点?我试着修复它,使CLOSE_NAME是ID的倒数:
CLOSE_NAME : ~('a'..'z' | 'A'..'Z' | '0'..'9' | '-' | '_' | '?');但ANTLR仍然使用*,在剩余的'/‘上留下一个无法识别的标记错误。我真正想做的是让ANTLR退出模式而不使用令牌,这样当我们返回到DEFAULT_MODE时,'*/‘就是下一个令牌。有什么想法吗?
发布于 2014-02-07 04:02:20
首先,您可能希望使用-> pushMode(NAME)和-> popMode返回到默认模式,而不是使用mode命令。
对于CLOSE_NAME规则,您可以使用谓词而不是匹配的文字来处理注释的结尾:
CLOSE_NAME
: ( '\r'? '\n'
| {_input.LA(1) == '*' && _input.LA(2) == '/'}?
)
-> popMode
;这可能会产生零长度令牌,这在ANTLR 4.0中是不允许的,但在ANTLR 4.1中删除了这个限制(更改为警告),因为我们意识到零长度令牌可以用来触发模式更改,从而避免无限循环。
https://stackoverflow.com/questions/21612068
复制相似问题