【已解决】antlrworks中调试出错:xxxParser.java:1870: error: <identifier> expected

【问题】

用的是antlrworks 1.5rc2,去使用如下antlr v3的语法:

grammar DDParserDemo;

options {
	output = AST;
	ASTLabelType = CommonTree; // type of $stat.tree ref etc...
}

/*
//NEWLINE :   '\r'? '\n' ;
//NEWLINE :   '\r' '\n' ;
fragment 
NEWLINE :   '\r'? '\n' ;
*/

/* 
fragment
FLOAT
    :   ('0'..'9')+ '.' ('0'..'9')* EXPONENT?
    |   '.' ('0'..'9')+ EXPONENT?
    |   ('0'..'9')+ EXPONENT
    ;
*/

COMMENT
    :   '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
    |   '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
    ;

//fragment WS  :   ( ' ' | '\t' | '\r' | '\n') {skip();};
//fragment WS  :   ( ' ' | '\t' | '\r' | '\n') {$channel=HIDDEN;};
//WS  :   ( ' ' | '\t' | '\r' | '\n');
//WS  :   ( ' ' | '\t' | '\r' | '\n') {$channel=HIDDEN;};
WS  :   ( ' ' | '\t' | '\r' | '\n')+ {$channel=HIDDEN;};


STRING
    :  '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
    ;

/*
CHAR:  '\'' ( ESC_SEQ | ~('\''|'\\') ) '\''
    ;
*/

fragment
EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;


ESC_SEQ
    :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
    |   UNICODE_ESC
    |   OCTAL_ESC
    ;

fragment
OCTAL_ESC
    :   '\\' ('0'..'3') ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7')
    ;

fragment
UNICODE_ESC
    :   '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
    ;

fragment
DIGIT
	:	'0'..'9';

//FAKE_TOKEN 	:	'1' '2' '3';

/*
DECIMAL_VALUE
	:	'1'..'9' DIGIT*;
*/

//DECIMAL_VALUE	:	DIGIT*;
DECIMAL_VALUE	:	DIGIT+;
//DECIMAL_VALUE	:	'1'..'9' DIGIT*;

//HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;
//HEX_DIGIT : (DIGIT|'a'..'f'|'A'..'F') ;
HEX_DIGIT : ('a'..'f'|'A'..'F' | DIGIT) ;


HEX_VALUE
	:	'0x' HEX_DIGIT+;

/*
fragment
HEADER_FILENAME
	:	('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'_')*;
*/


//BLANK	:	(' '|'\t')+ {$channel=HIDDEN;};
//BLANK	:	(' '|'\t')+ {skip();};
//BLANKS_TABS	:	(' '|'\t')+;
//fragment 
//BLANKS_TABS	:	(' '|'\t')+;

//fragment
ID  :	('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
    ;

HEADER_FILENAME	:	ID '.h';

//singleInclude	:	'#include' BLANKS_TABS '"' ID '.h' '"';
//singleInclude	:	'#include' BLANKS_TABS '"' HEADER_FILENAME '"';
//singleInclude	:	'#include' WS '"' HEADER_FILENAME '"';
singleInclude	:	'#include' '"' HEADER_FILENAME '"';

//include		:	singleInclude WS*;
include		:	singleInclude;

define_value	:	ID;
imported_value	:	'[' ID ']'; /* normal ID with [] */
define_imported_value
		:	define_value | imported_value;	
direct_value	:	(DECIMAL_VALUE | HEX_VALUE);
string_value	:	(STRING | define_imported_value);

//manufacture	:	'MANUFACTURER'^ 	BLANKS_TABS (direct_value | define_value) (','?)! WS*;
manufacture	:	'MANUFACTURER'^ 	(direct_value | define_value) (','?)!;
//deviceType	:	'DEVICE_TYPE'^ 		(DECIMAL_VALUE | HEX_VALUE) (','?)!;
deviceType	:	'DEVICE_TYPE'^ 		(direct_value | define_value) (','?)!;
//deviceRevison	:	'DEVICE_REVISION'^ 	(DECIMAL_VALUE | HEX_VALUE) (','?)!;
deviceRevison	:	'DEVICE_REVISION'^ 	(direct_value | define_value) (','?)!;
//ddRevision	:	'DD_REVISION'^ 		(DECIMAL_VALUE | HEX_VALUE) (','?)!;
ddRevision	:	'DD_REVISION'^ 		(direct_value | define_value) (','?)!;

//label_value	:	define_value | imported_value;
label		:	'REDEFINE'? 'LABEL' define_imported_value ';';

//help_value	:	define_value | imported_value;
help		:	'REDEFINE'? 'HELP' define_imported_value ';';

single_class_value
		: 	('ALARM'| 'ANALOG_INPUT'| 'ANALOG_OUTPUT'| 'COMPUTATION'| 'CONTAINED'| 'CORRECTION'| 'DEVICE'| 'DIAGNOSTIC'| 'DIGITAL_INPUT'| 'DIGITAL_OUTPUT'| 'DISCRETE_INPUT'| 'DISCRETE_OUTPUT'| 'DYNAMIC'| 'FREQUENCY_INPUT'| 'FREQUENCY_OUTPUT'| 'HART'| 'INPUT'| 'LOCAL'| 'LOCAL_DISPLAY'| 'OPERATE'| 'OUTPUT'| 'SERVICE'| 'TUNE');
class_value	:	single_class_value ('&' single_class_value)*;
class		:	'CLASS' class_value ';' ;

/*
TYPE            ENUMERATED (4)
{
    {0x1E6D11, "|en|Softing", [mfr_id_help]}
}

TYPE            UNSIGNED_INTEGER (4) ;

TYPE            ENUMERATED (1)
{
    _UNINITIALIZED_VALUE,
    { 0x01,    [restart_run],           [restart_run_help] },
    { 0x02,    [restart_resource],      [restart_resource_help] },
    { 0x03,    [restart_defaults],      [restart_defaults_help] },
    { 0x04,    [restart_processor],     [restart_processor_help] },
    { 0x05,    RESTART_FACTORY_DEFAULT, RESTART_FACTORY_DEFAULT_HELP }
}

TYPE            BIT_ENUMERATED (2)
{
    FEATURES_RES2
}
*/
single_type_value
		: 	('DOUBLE'| 'FLOAT'| 'INTEGER'| 'UNSIGNED_INTEGER'| 'DATE'| 'DATE_AND_TIME'| 'DURATION'| 'TIME'| 'TIME_VALUE'| 'BIT_ENUMERATED'| 'ENUMERATED'| 'INDEX'| 'OBJECT_REFERENCE'| 'ASCII'| 'BITSTRING'| 'EUC'| 'OCTET'| 'PACKED_ASCII'| 'PASSWORD'| 'VISIBLE');
triplet_interger:	direct_value;/* TODO: support diffrent values(dicimal and others) */
triplet_description
		:	string_value;
triplet_help	:	string_value;
triplet		:	'{' triplet_interger ',' triplet_description ',' triplet_help '}' ; 
enumerate_line	:	(define_value | triplet) ',';
type_struct	:	'{' enumerate_line+ '}';
type		:	single_type_value '(' DECIMAL_VALUE ')' type_struct? ';' ;


/*

CONSTANT_UNIT   "|en|1/32 millisec" ;

CONSTANT_UNIT   [blank] ;

*/
constant_unit_value
		:	(imported_value | STRING);
constant_unit	:	constant_unit_value ';' ;

/*
7.27.2.5 HANDLING
*/
single_handling_value
		:	('READ' | 'READ_WRITE' | 'WRITE');
handling_value	:	single_handling_value ('&' single_handling_value)*;
handling	:	handling_value ';' ;

/*
7.27 VARIABLE
Table 138 – VARIABLE attributes
*/
single_variable_field_m
		:	class | label | type;
variable_fields_o:	help | constant_unit | handling;
variable	:	'REDEFINE'? 'VARIABLE' ID '{' (single_variable_field_m+ | variable_fields_o?) '}';

everything	:	'EVERYTHING' ';';
//redefinitions	:	'REDEFINITIONS' WS* '{' WS* (variable | record)+ '}';
redefinitions	:	'REDEFINITIONS' '{' (variable)+ '}';
//single_import	:	'IMPORT' BLANKS_TABS manufacture deviceType deviceRevison ddRevision WS* '{' WS* everything WS* redefinitions WS* '}' ;
//single_import	:	'IMPORT' manufacture deviceType deviceRevison ddRevision WS* '{' WS* everything WS* redefinitions WS* '}' ;
single_import	:	'IMPORT' manufacture deviceType deviceRevison ddRevision '{' everything redefinitions '}' ;
//single_import	:	'IMPORT' (' ' | '\t')+ manufacture deviceType deviceRevison ddRevision WS* '{' WS* everything WS* redefinitions WS* '}' ;
//single_import	:	'IMPORT' WS+ manufacture deviceType deviceRevison ddRevision WS* '{' WS* everything WS* redefinitions WS* '}' ;

startParse	:	include+ manufacture deviceType deviceRevison ddRevision single_import+;

去解析一个ddl文件。

已经是可以正常编译通过的(虽然有warning)。

但是去用antlrworks去debug时出错:

[14:44:43] D:\DevRoot\IndustrialMobileAutomation\HandheldDataSetter\ANTLR\projects\v1.5\DDParserDemo\output\DDParserDemoParser.java:1870: error: <identifier> expected

[14:44:43]     public final DDParserDemoParser.class_return class() throws RecognitionException {

[14:44:43]                                                 ^

[14:44:43] D:\DevRoot\IndustrialMobileAutomation\HandheldDataSetter\ANTLR\projects\v1.5\DDParserDemo\output\DDParserDemoParser.java:1870: error: illegal start of type

[14:44:43]     public final DDParserDemoParser.class_return class() throws RecognitionException {

[14:44:43]                                                       ^

[14:44:43] D:\DevRoot\IndustrialMobileAutomation\HandheldDataSetter\ANTLR\projects\v1.5\DDParserDemo\output\DDParserDemoParser.java:1870: error: <identifier> expected

[14:44:43]     public final DDParserDemoParser.class_return class() throws RecognitionException {

[14:44:43]                                                        ^

[14:44:43] D:\DevRoot\IndustrialMobileAutomation\HandheldDataSetter\ANTLR\projects\v1.5\DDParserDemo\output\DDParserDemoParser.java:1870: error: ‘;’ expected

[14:44:43]     public final DDParserDemoParser.class_return class() throws RecognitionException {

[14:44:43]                                                         ^

[14:44:43] D:\DevRoot\IndustrialMobileAutomation\HandheldDataSetter\ANTLR\projects\v1.5\DDParserDemo\output\DDParserDemoParser.java:1870: error: <identifier> expected

[14:44:43]     public final DDParserDemoParser.class_return class() throws RecognitionException {

[14:44:43]                                                                                     ^

[14:44:43] D:\DevRoot\IndustrialMobileAutomation\HandheldDataSetter\ANTLR\projects\v1.5\DDParserDemo\output\DDParserDemoParser.java:1872: error: <identifier> expected

[14:44:43]         retval.start = input.LT(1);

[14:44:43]                     ^

。。。

。。。

。。。

【解决过程】

1.所以就去看了看,生成的DDParserDemoParser.java的1870行的内容:

	// $ANTLR start "class"
	// D:\\DevRoot\\IndustrialMobileAutomation\\HandheldDataSetter\\ANTLR\\projects\\v1.5\\DDParserDemo\\DDParserDemo.g:142:1: class : 'CLASS' class_value ';' ;
	public final DDParserDemoParser.class_return class() throws RecognitionException {
		DDParserDemoParser.class_return retval = new DDParserDemoParser.class_return();
		retval.start = input.LT(1);

即,对应的是:

public final DDParserDemoParser.class_return class() throws RecognitionException {

结果就是,根本看不出来,搞不懂为何出错。

2.后来发现,原来之前自己就遇到过类似的问题,在:

【已解决】ANTLRWorks 1.5编译代码出错:Compiler failed with result code 1

中,就有:

error: <identifier> expected

3.参考:

[antlr-interest] Antlr 3.0: run time and java compiling errors

去看到解释:

This seems to be an actual problem of the grammar. It probably has a rule called "class", which is illegal in Java as "class" is a keyword. Simply rename the rule in the .g file.

看懂了,意思就是,此处,java中本身就有个关键字是class,但是由于antlr中有个token(变量)也被定义成class,所以冲突了。

解决办法就是去把antlr中对应class这个变量改个名字。

然后就去看看原先的语法,果然有这个class:

class		:	'CLASS' class_value ';' ;

所以就随便改个别的:

class_line	:	'CLASS' class_value ';' ;

single_variable_field_m
		:	class_line | label | type;

然后再去编译和调试antlr。

然后就可以正常编译和调试了。

 

【总结】

现象:

antlr调试中出现“error: <identifier> expected”的错误

原因:(很可能就是由于)

antrl中的语法代码中,定义了某个token,即变量,名字叫做class

导致生成的Parser(和Lexer)的java文件中,对应的函数名或类名,叫做class

这与Java语言本身的class这个关键字冲突了。

解决办法:

把antlr语法中的,那个class的token,改个别的名字。

比如我此处就是把class改为class_line,即把:

class		:	'CLASS' class_value ';' ;

改为:

class_line	:	'CLASS' class_value ';' ;

就可以解决问题了。



发表评论

电子邮件地址不会被公开。 必填项已用*标注

无觅相关文章插件,快速提升流量