我目前正在开发一个项目,我有一个任务是使用ANTLR4语法验证标识符。这部分项目如果前端使用Angular 6,那么语法也会编译成后端微服务。
验证包括验证以字母|字符开头的字符串,然后它可以具有字母|数字|下划线并以字母|数字字符结束。
我目前在语法实现方面遇到问题(因为我没有Lex的经验)并且处理错误。这是我的语法,以及错误的实现。
grammar test;
goal: identifier;
identifier: Alphanum+ Alphanumsymb* Alphanum+;
Alphanum: [a-zA-Z0-9];
Alphanumsymb: [a-zA-Z0-9_];
我的实现是根据语法检测字符串是否有效。
const teststring = "2019_Test_Identifier";
const inputStream = new ANTLRInputStream(teststring);
const lex = new lexer.TestGrammarLexer(inputStream);
const tokenStream = new CommonTokenStream(lex);
const pars = new parser.TestGrammarParser(tokenStream);
pars.goal();
console.log(pars.numberOfSyntaxErrors);
if ( pars.numberOfSyntaxErrors > 0 ) {
return false;
}
return true;
我的问题是,即使我得到正确的语法,我的错误处理实现也不正确,我没有找到材料来研究使用antlr4ts进行错误处理。
所以,如果你可以帮助我,我会很感激有关语法的反馈(它应该如何,或者它有什么问题),以及错误处理的实现(有关这方面的一些信息,因为在测试时,我看到了ConsoleErrorListener向控制台抛出语法错误,但我的函数显示0语法错误)。
感谢您的阅读,希望您能帮助我。
我认为使用ANTLR对你的任务来说有点过分。 ANTLR或任何其他解析工具适用于构造字符串的结构,但在这里,您只想知道字符串是否是标识符。如果您真的需要ANTLR,请详细说明原因,然后我可以帮助您处理错误。
对于此任务,我建议您只需使用如下的正则表达式来测试标识符:
const regex = /^[a-zA-Z0-9]+|[a-zA-Z0-9][a-zA-Z0-9_]*[a-zA-Z0-9]+$/
然后用它作为regex.text(str)
。
如果不接受字符串作为标识符,它将返回false
。
请注意,您在ANTLR语法中对identifier
的定义不正确。它需要至少两个字符,因为有两个+
量词,并且它在长度为1的字符串上失败,例如a
。正则表达式版本也修复了这个问题。
预计这个后端微服务将来会“做得更多”,目前的最低语法要求可以通过以下方式满足:
ident : Alphanum (( Alphanum | Symb )* Alphanum )? ;
Alphanum : [a-zA-Z0-9] ;
Symb : '_' ;
现在,ident
规则允许单个字符标识符,这显然是原始规范所允许的。 Symb
规则现在代表唯一没有被原始语法中的Alphanum
规则遮蔽的内容。
默认情况下,词法分析器和解析器包含控制台错误侦听器。
使用Recognizer#addErrorListener
添加ANTLRErrorListener
的自定义扩展,根据需要计算和报告任何错误ConsoleErrorListener
是一个源示例。可以在词法分析器和解析器上设置相同的侦听器。
如果控制台消息不需要,请使用Recognizer#removeErrorListeners
首先删除控制台侦听器。
顺便说一句,所有的ANTLR运行时在功能上都是相同的,在架构上非常相似。因此,{Java,Python,...}中的任何ANTLR代码示例都将在TypeScript中具有几乎相同的实现。