问题描述
我将SemVer 2 BNF grammar转换为以下Antlr语法。
struct QrCodeView: View {
var body: some View {
Text("QrCode")
}
}
但是解析grammar SemVer;
@header {
package com.me.semver;
}
semVer : normal ('-' preRelease)? ('+' build)? ;
normal : major '.' minor '.' patch ;
major : NUM ;
minor : NUM ;
patch : NUM ;
preRelease : PRE_RELEASE ('.' preRelease)* ;
build : BUILD ('.' build)*;
NUM : '0'
| POSITIVE_DIGIT
| POSITIVE_DIGIT DIGITS
;
BUILD : ALPHANUM
| DIGITS
;
PRE_RELEASE : ALPHANUM
| NUM
;
fragment
ALPHANUM : NON_DIGIT
| NON_DIGIT CHARS
| CHARS NON_DIGIT
| CHARS NON_DIGIT CHARS
;
fragment
CHARS : CHAR+ ;
fragment
CHAR : DIGIT
| NON_DIGIT
;
fragment
NON_DIGIT : LETTER
| '-'
;
fragment
DIGITS : DIGIT+ ;
fragment
DIGIT : '0'
| POSITIVE_DIGIT
;
fragment
POSITIVE_DIGIT : [1-9] ;
fragment
LETTER : [a-zA-Z] ;
会出现以下错误:
第1行第4行的输入“ 0-beta”不匹配,期望NUM
侦听器的输出如下:
1.0.0-beta+exp.sha.5114f85
很明显,补丁版本不是应该的。正确的输出应为normal: 1.0.0-beta
Major: 1
Minor: 0
Patch: 0-beta
Build: exp.sha.5114f85
Build: sha.5114f85
Build: 5114f85
,Patch = 0
和Pre release = beta
。
我该如何修正语法?
解决方法
您有太多重叠的词法分析器规则。例如,输入0
可以通过以下3条规则中的任何一条进行匹配:
NUM : '0'
| POSITIVE_DIGIT
| POSITIVE_DIGIT DIGITS
;
BUILD : ALPHANUM
| DIGITS
;
PRE_RELEASE : ALPHANUM
| NUM
;
,由于NUM
放在首位,因此输入0
将始终成为NUM
令牌。解析器尝试匹配什么令牌都没有关系,它将始终是NUM
令牌。
这就是ANTLR的词法分析器的工作方式:
- 它尝试为每个令牌匹配尽可能多的字符,并且
- 当两个或多个词法分析器规则匹配相同数量的字符时,第一个定义为“获胜”。
鉴于您的语法和输入"1.0.0-beta+exp.sha.5114f85"
,将创建以下标记:
NUM `1`
null `.`
NUM `0`
null `.`
BUILD `0-beta`
null `+`
BUILD `exp`
null `.`
BUILD `sha`
null `.`
BUILD `5114f85`
请注意,0-beta
被标记为单个BUILD
标记(规则1)。
您应该做的是定义不重叠的词法分析器规则。在您的情况下,这意味着要定义以下规则/令牌:
HYPHEN
: '-'
;
PLUS
: '+'
;
DOT
: '.'
;
ZERO_DIGIT
: '0'
;
POSITIVE_DIGIT
: [1-9]
;
LETTER
: [a-zA-Z]
;
,然后像DIGIT
和DIGITS
这样的规则将变成解析器规则:
digits
: digit+
;
digit
: ZERO_DIGIT
| POSITIVE_DIGIT
;