用于字段验证的 ANTLR4 语法
ANTLR4 Grammar for field validation
我目前正在做一个项目,我的任务是使用 ANTLR4 语法验证标识符。这部分项目如果前端使用Angular6,语法也会编译成后端微服务。
验证包括验证以字母|数字字符开头的字符串,然后它可以有字母|数字|下划线并以字母|数字字符结尾。
我目前在语法实现(因为我没有使用 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;
我的问题是,即使我的语法正确,我对错误处理的实现也不正确,我还没有找到material研究antlr4ts的错误处理。
所以,如果你能帮助我,我将不胜感激关于语法的反馈(它应该如何,或者它有 atm 的问题),以及关于错误处理的实现(一些关于这个的信息,因为当测试,我看到 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)
。
如果不接受该字符串作为标识符,它将 return false
。
请注意,您在 ANTLR 语法中对 identifier
的定义不正确。它需要至少两个字符,因为有两个 +
量词,并且它在长度为 1 的字符串(例如 a
上失败。正则表达式版本也修复了这个问题。
预计此后端微服务将来会'do more',目前的最低语法要求可以满足
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 中具有几乎等效的实现。
我目前正在做一个项目,我的任务是使用 ANTLR4 语法验证标识符。这部分项目如果前端使用Angular6,语法也会编译成后端微服务。
验证包括验证以字母|数字字符开头的字符串,然后它可以有字母|数字|下划线并以字母|数字字符结尾。
我目前在语法实现(因为我没有使用 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;
我的问题是,即使我的语法正确,我对错误处理的实现也不正确,我还没有找到material研究antlr4ts的错误处理。
所以,如果你能帮助我,我将不胜感激关于语法的反馈(它应该如何,或者它有 atm 的问题),以及关于错误处理的实现(一些关于这个的信息,因为当测试,我看到 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)
。
如果不接受该字符串作为标识符,它将 return false
。
请注意,您在 ANTLR 语法中对 identifier
的定义不正确。它需要至少两个字符,因为有两个 +
量词,并且它在长度为 1 的字符串(例如 a
上失败。正则表达式版本也修复了这个问题。
预计此后端微服务将来会'do more',目前的最低语法要求可以满足
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 中具有几乎等效的实现。