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

时间:2018-09-29 21:01:11

标签: string character antlr antlr4 double-quotes

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

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

grun A1_lexer tokens -tokens test.txt

由于我的test.txt文件是一个简单的字符串(例如“菠萝”),因此无法识别不同的标记。

在我的词法分析器中,我定义了以下辅助标记:

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

它输出以下内容:

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:

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: '\"' ;

我已经更新了代码,我摆脱了Char分类中不必要的单引号。但是,我得到的输出与以前相同。

更新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文件如下所示:

#!/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

即使我重新编译,我的antlr代码仍然无法识别令牌。

我的代码现在也像这样:

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*'”'

test.txt:

"pineapple"

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]

我真的不确定为什么会这样。

1 个答案:

答案 0 :(得分:0)

fragment Char: ['a'-'z'] | ['A' - 'Z'] | ['0' - '9']

['a'-'z']的含义不是“ a到z”,而是“单引号或a或单引号或单引号或z或单引号”,它简化为“单引号,a或z”。您想要的只是[a-z],不带引号,其他字符类也是如此,除了它们还包含空格之外,因此它是“单引号,A,单引号,空格到空格,单引号, Z,或“单引号”等。另外,您也不需要“或”字符类,您只需将所有内容写在一个字符类中,例如:[a-zA-Z0-9](就像您已经为Alpha做的一样)规则)。

Digit规则也是如此。

请注意,只允许在引号内使用这些特定字符有点不寻常。通常,您会允许所有非转义引号或无效转义序列的内容。但是当然,这完全取决于您要解析的语言。