下划线被视为空白。正常吗?
undescores seen as white spaces. Is it normal?
在我的语法中,白色 spaces:
WS:
(' '|'\r'|'\t'|'\n') -> skip
;
但是,如果我使用下划线而不是 space,解析器不会阻塞。
My-first-module_DEFINITIONS_::=
被识别为
My-first-module DEFINITIONS ::=
是否有我必须在词法分析器中设置的选项?
谢谢
这是有助于重现我所见内容的精简语法
grammar ASN;
/*--------------------- Module definition -------------------------------------------*/
/* ModuleDefinition (see 13 in ITU-T X.680 (08/2015) */
moduleDefinition:
moduleIdentifier
DEFINITIONS_LITERAL
ASSIGN
BEGIN_LITERAL
END_LITERAL
;
moduleIdentifier:
UCASE_ID
;
/*--------------------- LITERAL -----------------------------------------------------*/
DEFINITIONS_LITERAL:
'DEFINITIONS'
;
BEGIN_LITERAL:
'BEGIN'
;
END_LITERAL:
'END'
;
ASSIGN:
'::='
;
UCASE_ID:
('A'..'Z') ('-'('a'..'z'|'A'..'Z'|'0'..'9')|('a'..'z'|'A'..'Z'|'0'..'9'))*
;
/* white-space (see 12.1.6 in ITU-T X.680 (08/2015) */
WS:
(' '|'\r'|'\t'|'\n') -> skip
;
以及不应该被解析器接受的例子:
My-first-module_DEFINITIONS_::=
BEGIN
END
编辑:我意识到我的问题是由于我使用 JUnit 运行 我的测试,我只是检查解析器发现的语法错误。
这是代码,包括 Bart 的回答,如果词法分析器有问题,它会使测试失败 ...
// load test data
InputStream inStream = getClass().getClassLoader().getResourceAsStream(resourceName);
if (inStream == null) {
throw new RuntimeException("Resource not found: " + resourceName);
}
// create a CharStream that reads from standard input
CharStream input = new ANTLRInputStream(inStream);
// create a lexer that feeds off of input CharStream
ASNLexer lexer = new ASNLexer(input);
lexer.addErrorListener(new BaseErrorListener() {
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
throw new RuntimeException(e);
}
}
);
// create a buffer of tokens pulled from the lexer
TokenStream tokens = new CommonTokenStream(lexer);
// create a parser that feeds off the tokens buffer
ASNParser parser = new ASNParser(tokens);
parser.moduleDefinition(); // begin parsing at moduleDefinition rule
assert(0 == parser.getNumberOfSyntaxErrors());
词法分析器从意外输入中恢复。你可以通过 运行 这个 class:
查看
public class Main {
public static void main(String[] args) {
String source = "My-first-module_DEFINITIONS_::= \n" +
"BEGIN \n" +
"\n" +
"END";
ASNLexer lexer = new ASNLexer(CharStreams.fromString(source));
ASNParser parser = new ASNParser(new CommonTokenStream(lexer));
parser.moduleDefinition();
}
}
这会将以下内容打印到您的标准输出:
line 1:15 token recognition error at: '_'
line 1:27 token recognition error at: '_'
这里有几个选项:
1。添加 catch-all 规则
在语法末尾添加这样的规则:
Other
: .
;
然后在您认为合适的解析器中处理 Other
。
2。添加自定义 ErrorListener
做这样的事情:
lexer.addErrorListener(new BaseErrorListener(){
@Override
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
throw new RuntimeException(e);
}
});
这将导致词法分析器中的任何错误抛出 RuntimeException
。
请注意,ANTLR4 支持更紧凑的定义字符集的表示法,如下所示:
UCASE_ID:
[A-Z] ( '-'? [a-zA-Z0-9] )*
;
WS:
[ \t\r\n] -> skip
;
在我的语法中,白色 spaces:
WS:
(' '|'\r'|'\t'|'\n') -> skip
;
但是,如果我使用下划线而不是 space,解析器不会阻塞。
My-first-module_DEFINITIONS_::=
被识别为
My-first-module DEFINITIONS ::=
是否有我必须在词法分析器中设置的选项?
谢谢
这是有助于重现我所见内容的精简语法
grammar ASN;
/*--------------------- Module definition -------------------------------------------*/
/* ModuleDefinition (see 13 in ITU-T X.680 (08/2015) */
moduleDefinition:
moduleIdentifier
DEFINITIONS_LITERAL
ASSIGN
BEGIN_LITERAL
END_LITERAL
;
moduleIdentifier:
UCASE_ID
;
/*--------------------- LITERAL -----------------------------------------------------*/
DEFINITIONS_LITERAL:
'DEFINITIONS'
;
BEGIN_LITERAL:
'BEGIN'
;
END_LITERAL:
'END'
;
ASSIGN:
'::='
;
UCASE_ID:
('A'..'Z') ('-'('a'..'z'|'A'..'Z'|'0'..'9')|('a'..'z'|'A'..'Z'|'0'..'9'))*
;
/* white-space (see 12.1.6 in ITU-T X.680 (08/2015) */
WS:
(' '|'\r'|'\t'|'\n') -> skip
;
以及不应该被解析器接受的例子:
My-first-module_DEFINITIONS_::=
BEGIN
END
编辑:我意识到我的问题是由于我使用 JUnit 运行 我的测试,我只是检查解析器发现的语法错误。 这是代码,包括 Bart 的回答,如果词法分析器有问题,它会使测试失败 ...
// load test data
InputStream inStream = getClass().getClassLoader().getResourceAsStream(resourceName);
if (inStream == null) {
throw new RuntimeException("Resource not found: " + resourceName);
}
// create a CharStream that reads from standard input
CharStream input = new ANTLRInputStream(inStream);
// create a lexer that feeds off of input CharStream
ASNLexer lexer = new ASNLexer(input);
lexer.addErrorListener(new BaseErrorListener() {
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
throw new RuntimeException(e);
}
}
);
// create a buffer of tokens pulled from the lexer
TokenStream tokens = new CommonTokenStream(lexer);
// create a parser that feeds off the tokens buffer
ASNParser parser = new ASNParser(tokens);
parser.moduleDefinition(); // begin parsing at moduleDefinition rule
assert(0 == parser.getNumberOfSyntaxErrors());
词法分析器从意外输入中恢复。你可以通过 运行 这个 class:
查看public class Main {
public static void main(String[] args) {
String source = "My-first-module_DEFINITIONS_::= \n" +
"BEGIN \n" +
"\n" +
"END";
ASNLexer lexer = new ASNLexer(CharStreams.fromString(source));
ASNParser parser = new ASNParser(new CommonTokenStream(lexer));
parser.moduleDefinition();
}
}
这会将以下内容打印到您的标准输出:
line 1:15 token recognition error at: '_'
line 1:27 token recognition error at: '_'
这里有几个选项:
1。添加 catch-all 规则
在语法末尾添加这样的规则:
Other
: .
;
然后在您认为合适的解析器中处理 Other
。
2。添加自定义 ErrorListener
做这样的事情:
lexer.addErrorListener(new BaseErrorListener(){
@Override
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
throw new RuntimeException(e);
}
});
这将导致词法分析器中的任何错误抛出 RuntimeException
。
请注意,ANTLR4 支持更紧凑的定义字符集的表示法,如下所示:
UCASE_ID:
[A-Z] ( '-'? [a-zA-Z0-9] )*
;
WS:
[ \t\r\n] -> skip
;