String 无法识别ANTLr中的字符串和字符
在我的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
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和/或重新编译?如果不是这样,请发布您当前的全部语法、输入文件和确切的当前错误消息,因此我在测试它时运行的代码与您相同。