String 无法识别ANTLr中的字符串和字符

String 无法识别ANTLr中的字符串和字符,string,character,antlr,antlr4,double-quotes,String,Character,Antlr,Antlr4,Double Quotes,在我的ANTLr代码中,我们应该能够识别字符串、字符、十六进制数字等 但是,在我的代码中,当我这样测试它时: grun A1_lexer tokens -tokens test.txt grun A1_lexer tokens -tokens test.txt #!/bin/bash FILE="A1_lexer" ANTLR=$(echo $CLASSPATH | tr ':' '\n' | grep -m 1 "antlr-4.7.1- complete.jar") java -jar

在我的ANTLr代码中,我们应该能够识别字符串、字符、十六进制数字等

但是,在我的代码中,当我这样测试它时:

grun A1_lexer tokens -tokens test.txt
grun A1_lexer tokens -tokens test.txt
#!/bin/bash
FILE="A1_lexer"
ANTLR=$(echo $CLASSPATH | tr ':' '\n' | grep -m 1 "antlr-4.7.1- 
complete.jar")
java -jar $ANTLR $FILE.g4
javac $FILE*.java
fragment Delimiter: ' ' | '\t' | '\n' ;
fragment Alpha: [a-zA-Z_];
fragment Char: [a-zA-Z0-9] ;
fragment Digit: [0-9] ;
fragment Alpha_num: Alpha | Digit ;
fragment Single_quote: '\'' ;
fragment Double_quote: '"' ;
fragment Hex_digit: Digit | [a-fA-F] ;
fragment Eq_op: '==' | '!=' ;

Char_literal : (Single_quote)Char(Single_quote) ;
String_literal : (Double_quote)Char*(Double_quote) ;
Decimal_literal : Digit+ ;
Id: Alpha Alpha_num* ;
由于我的test.txt文件是一个简单的字符串,例如“菠萝”,它无法识别不同的标记

在我的lexer中,我定义了以下helper标记:

fragment Delimiter: ' ' | '\t' | '\n' ;
fragment Alpha: [a-zA-Z_];
fragment Char: ['a'-'z'] | ['A' - 'Z'] | ['0' - '9'] ;
fragment Digit: ['0'-'9'] ;
fragment Alpha_num: Alpha | Digit ;
fragment Single_quote: '\'' ;
fragment Double_quote: '\"' ;
fragment Hex_digit: Digit | [a-fA-F] ;
我定义了以下标记:

Char_literal : (Single_quote)Char(Single_quote) ;
String_literal : (Double_quote)Char*(Double_quote) ;
Id: Alpha Alpha_num* ;
我是这样运行的:

grun A1_lexer tokens -tokens test.txt
grun A1_lexer tokens -tokens test.txt
#!/bin/bash
FILE="A1_lexer"
ANTLR=$(echo $CLASSPATH | tr ':' '\n' | grep -m 1 "antlr-4.7.1- 
complete.jar")
java -jar $ANTLR $FILE.g4
javac $FILE*.java
fragment Delimiter: ' ' | '\t' | '\n' ;
fragment Alpha: [a-zA-Z_];
fragment Char: [a-zA-Z0-9] ;
fragment Digit: [0-9] ;
fragment Alpha_num: Alpha | Digit ;
fragment Single_quote: '\'' ;
fragment Double_quote: '"' ;
fragment Hex_digit: Digit | [a-fA-F] ;
fragment Eq_op: '==' | '!=' ;

Char_literal : (Single_quote)Char(Single_quote) ;
String_literal : (Double_quote)Char*(Double_quote) ;
Decimal_literal : Digit+ ;
Id: Alpha Alpha_num* ;
它的输出是:

line 1:0 token recognition error at: '"'
line 1:1 token recognition error at: 'p'
line 1:2 token recognition error at: 'ine'
line 1:6 token recognition error at: 'p'
line 1:7 token recognition error at: 'p'
line 1:8 token recognition error at: 'l'
line 1:9 token recognition error at: 'e"'
[@0,5:5='a',<Id>,1:5]
[@1,12:11='<EOF>',<EOF>,2:0]
我更新了代码,去掉了字符分类中不必要的单引号。但是,我得到了与以前相同的输出

更新2:

即使我做了建议的更改,我仍然会得到相同的错误。我相信问题是我没有重新编译,但我是。这些是我重新编译的步骤

antlr4 A1_lexer.g4 
javac A1_lexer*.java
chmod a+x build.sh
./build.sh
grun A1_lexer tokens -tokens test.txt
我的build.sh文件如下所示:

grun A1_lexer tokens -tokens test.txt
grun A1_lexer tokens -tokens test.txt
#!/bin/bash
FILE="A1_lexer"
ANTLR=$(echo $CLASSPATH | tr ':' '\n' | grep -m 1 "antlr-4.7.1- 
complete.jar")
java -jar $ANTLR $FILE.g4
javac $FILE*.java
fragment Delimiter: ' ' | '\t' | '\n' ;
fragment Alpha: [a-zA-Z_];
fragment Char: [a-zA-Z0-9] ;
fragment Digit: [0-9] ;
fragment Alpha_num: Alpha | Digit ;
fragment Single_quote: '\'' ;
fragment Double_quote: '"' ;
fragment Hex_digit: Digit | [a-fA-F] ;
fragment Eq_op: '==' | '!=' ;

Char_literal : (Single_quote)Char(Single_quote) ;
String_literal : (Double_quote)Char*(Double_quote) ;
Decimal_literal : Digit+ ;
Id: Alpha Alpha_num* ;
即使在重新编译时,我的antlr代码仍然无法识别标记

我的代码现在也是这样:

grun A1_lexer tokens -tokens test.txt
grun A1_lexer tokens -tokens test.txt
#!/bin/bash
FILE="A1_lexer"
ANTLR=$(echo $CLASSPATH | tr ':' '\n' | grep -m 1 "antlr-4.7.1- 
complete.jar")
java -jar $ANTLR $FILE.g4
javac $FILE*.java
fragment Delimiter: ' ' | '\t' | '\n' ;
fragment Alpha: [a-zA-Z_];
fragment Char: [a-zA-Z0-9] ;
fragment Digit: [0-9] ;
fragment Alpha_num: Alpha | Digit ;
fragment Single_quote: '\'' ;
fragment Double_quote: '"' ;
fragment Hex_digit: Digit | [a-fA-F] ;
fragment Eq_op: '==' | '!=' ;

Char_literal : (Single_quote)Char(Single_quote) ;
String_literal : (Double_quote)Char*(Double_quote) ;
Decimal_literal : Digit+ ;
Id: Alpha Alpha_num* ;
更新3:

语法:

program
:'class Program {'field_decl* method_decl*'}'

field_decl
: type (id | id'['int_literal']') ( ',' id | id'['int_literal']')*';'
| type id '=' literal ';'

method_decl
: (type | 'void') id'('( (type id) ( ','type id)*)? ')'block

block
: '{'var_decl* statement*'}'

var_decl
: type id(','id)* ';'

type
: 'int'
| 'boolean'

statement
: location assign_op expr';'
| method_call';'
| 'if ('expr')' block ('else' block  )?
| 'switch' expr '{'('case' literal ':' statement*)+'}'
| 'while (' expr ')' statement
| 'return' ( expr )? ';'
| 'break ;'
| 'continue ;'
| block

assign_op
: '='
| '+='
| '-='

method_call
: method_name '(' (expr ( ',' expr )*)? ')'
| 'callout (' string_literal ( ',' callout_arg )* ')'

method_name
: id

location
: id
| id '[' expr ']'

expr
: location
| method_call
| literal
| expr bin_op expr
| '-' expr
| '!' expr
| '(' expr ')'

callout_arg
: expr
| string_literal

bin_op
: arith_op
| rel_op
| eq_op
| cond_op

arith_op
: '+'
| '-'
| '*'
| '/'
| '%'

rel_op
: '<'
| '>'
| '<='
| '>='

eq_op
: '=='
| '!='

cond_op
: '&&'
| '||'

literal
: int_literal
| char_literal
| bool_literal

id
: alpha alpha_num*

alpha
: ['a'-'z''A'-'Z''_']

alpha_num
: alpha
| digit 

digit
: ['0'-'9']

hex_digit
: digit
| ['a'-'f''A'-'F']

int_literal
: decimal_literal
| hex_literal

decimal_literal
: digit+

hex_literal
: '0x' hex_digit+

bool_literal
: 'true'
| 'false'

char_literal
: '‘'char'’'

string_literal
: '“'char*'”'
A1_lexer:

fragment Delimiter: ' ' | '\t' | '\n' ;
fragment Alpha: [a-zA-Z_];
fragment Char: [a-zA-Z0-9] ;
fragment Digit: [0-9] ;
fragment Alpha_num: Alpha | Digit ;
fragment Single_quote: '\'' ;
fragment Double_quote: '"' ;
fragment Hex_digit: Digit | [a-fA-F] ;
fragment Eq_op: '==' | '!=' ;

Char_literal : (Single_quote)Char(Single_quote) ;
String_literal : (Double_quote)Char*(Double_quote) ;
Decimal_literal : Digit+ ;
Id: Alpha Alpha_num* ;
我在终端上写的是:

grun A1_lexer tokens -tokens test.txt
line 1:0 token recognition error at: '"'
line 1:1 token recognition error at: 'p'
line 1:2 token recognition error at: 'ine'
line 1:6 token recognition error at: 'p'
line 1:7 token recognition error at: 'p'
line 1:8 token recognition error at: 'l'
line 1:9 token recognition error at: 'e"'
[@0,5:5='a',<Id>,1:5]
[@1,12:11='<EOF>',<EOF>,2:0]
终端中的输出:

grun A1_lexer tokens -tokens test.txt
line 1:0 token recognition error at: '"'
line 1:1 token recognition error at: 'p'
line 1:2 token recognition error at: 'ine'
line 1:6 token recognition error at: 'p'
line 1:7 token recognition error at: 'p'
line 1:8 token recognition error at: 'l'
line 1:9 token recognition error at: 'e"'
[@0,5:5='a',<Id>,1:5]
[@1,12:11='<EOF>',<EOF>,2:0]
行1:0令牌识别错误位于:''''
第1行:1令牌识别错误位于:“p”
第1行:2“ine”处的令牌识别错误
第1行:6“p”处的令牌识别错误
第1行:7“p”处的令牌识别错误
第1行:8令牌识别错误位于:“l”
第1:9行:“e”处的令牌识别错误
[@0,5:5='a',1:5]
[@1,12:11='',,2:0]
我真的不知道为什么会这样

['a'-'z']
并不是指“a到z”,而是指“单引号,或a,或单引号到单引号,或z,或单引号”,简化为“单引号,a或z”。您需要的是不带引号的
[a-z]
,这同样适用于其他字符类-除了它们也包含空格,所以是“单引号、a、单引号、空格到空格、单引号、z或单引号”等等。您也不需要“或”字符类,您可以这样在一个字符类中编写所有内容:
[a-zA-Z0-9]
(就像您已经为
Alpha
规则所做的那样)

这同样适用于
数字
规则


请注意,只允许在引号中包含这些特定字符有点不寻常。通常,您会允许所有不是未转义引号或无效转义序列的内容。当然,这一切都取决于您正在解析的语言。

不幸的是,即使我做了这些更改,错误仍然存在。我的词法分析器无法识别“作为令牌,它也无法识别其中的字符。我也不知道为什么它会将字母‘a’视为标识符。@你能发布更新后的代码吗?”?它认为
a
是一个标识符,因为
a
实际上是“单引号、a或z”中实际包含的少数几个字母之一。因此,它会丢弃所有未知的内容,只留下一个与Id规则匹配的字符。@seeplus另外,您真的会收到相同的错误吗?因为现在这些都应该消失了。当我运行你的语法时,我得到的是一个警告,
\“
是一个无效的转义序列(删除
`)然后在运行时执行无限循环。删除
``后,它可以正常工作。如果您仍然收到旧错误,可能您忘记重新运行ANTLR和/或重新编译?如果不是这样,请发布您当前的全部语法、输入文件和确切的当前错误消息,因此我在测试它时运行的代码与您相同。