【问题标题】:ANTLRWorks v1.4.3 Debugger random behaviour (Can't connect to debugger)ANTLRWorks v1.4.3 调试器随机行为(无法连接到调试器)
【发布时间】:2014-04-24 11:28:54
【问题描述】:

如果我调试这个语法:

grammar CDBFile;

options {
    language=Java;
    TokenLabelType=CommonToken;
    output=AST;
    k=1;
    ASTLabelType=CommonTree;
}

tokens {
    IMAG_COMPILE_UNIT;
    MODULE;
}

//@lexer::namespace{Parser}
//@parser::namespace{Parser}

@lexer::header {
}

@lexer::members {
}

@parser::header {
}

@parser::members {
}


/*
 * Lexer Rules
 */
 
fragment LETTER :
    'a'..'z'
  | 'A'..'Z';
  
MODULE_NAME
    :
    (LETTER)*   
    ;

COLON   
    :   
    ':'
    ;


/*
 * Parser Rules
 */

public
compileUnit
        :   
          (basic_record)* EOF 
        ;

basic_record 
    :
    (
    
      'M' COLON   module_record
    | 'F' COLON function_record
    
    ) ('\n')?
    ;

module_record
    :   
    MODULE_NAME 
    ;

function_record
    :
    function_scope MODULE_NAME '$'
    ;

function_scope
    :
    ('G$' | 'F$' | 'L$')    
    ;

只有这个输入:

M:divide

调试器根本不开始说

  • 无法启动 debuggerTab。等待连接到远程解析器超时”。

但是在这里使用这个语法:

grammar Calculator;

options {
//DO NOT CHANGE THESE!
backtrack    = false;
k            = 1;
output       = AST;
ASTLabelType = CommonTree;
//SERIOUSLY, DO NOT CHANGE THESE!
}

tokens {
  // Imaginary tokens
  
  // Root
  PROGRAM;
  
  // function top level
  FUNCTION_DECLARATION;
  FUNCTION_HEAD;
  FUNCTION_BODY;
  
  DECL;
  FUN;
  // if-else-statement
  IF_STATEMENT;
  IF_CONDITION;
  IF_BODY;
  ELSE_BODY;
  
  // for-loop
  FOR_STATEMENT;
  FOR_INITIALIZE;
  FOR_CONDITION;
  FOR_INCREMENT;
  FOR_BODY;
  
  // Non-imaginary tokens
}

@lexer::header {
package at.tugraz.ist.cc;
}

@lexer::members {
}

@parser::header {
package at.tugraz.ist.cc;
}

@parser::members {
}



  //Lexer rules
ASSIGNOP :
  '=';

OR :
  '||';

AND :
  '&&';

RELOP :
  '<'
  | '<='
  | '>'
  | '>='
  | '=='
  | '!=';

SIGN :
  '+'
  | '-';

MULOP :
  '*'
  | '/'
  | '%';

NOT :
  '!';

fragment OPERATORS :
  '<'
  | '>'
  | '='
  | '+'
  | '-'
  | '/'
  | '%'
  | '*'
  | '|'
  | '&';

INT :
  '0'
  | DIGIT DIGIT0*;

fragment DIGIT :
  '1'..'9';

fragment DIGIT0 :
  '0'..'9';

BOOLEAN :
  'true'
  | 'false';

ID :
  LETTER
  (
    LETTER
    | DIGIT0
    | '_'
  )*;

fragment LETTER :
  'a'..'z'
  | 'A'..'Z';

PUNCT :
  '.'
  | ','
  | ';'
  | ':'
  | '!';

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

LITERAL :
  '"'
  (
    LETTER
    | DIGIT
    | '_'
    | '\\'
    | OPERATORS
    | PUNCT
    | WS
  )*
  '"';
  




// parse rules

program :
  functions -> ^(PROGRAM functions)
  ;
  
functions :  
  (function_declaration functions)?
  ;
  
function_declaration :
  head=function_head  '{' declarations optional_stmt return_stmt rc='}' -> ^(FUNCTION_DECLARATION[$head.start, $head.text] function_head ^( FUNCTION_BODY[rc,"FUNCTION_BODY"] declarations optional_stmt? return_stmt))
  ;

function_head :
  typeInfo=type ID arguments -> ^(FUNCTION_HEAD[$typeInfo.start, "FUNCTION_HEAD"] type ID arguments?) 
  ; 

type : 
  
    'int'
    | 'boolean'
    | 'String'
  ;
 
arguments : 
  '(' ! argument_optional ')' !;
  
argument_optional : 
  parameter_list ? -> ^(DECL parameter_list)?  ;
  
parameter_list : 
  type  ID parameter_list2 -> ^(type ID) parameter_list2
  ;

parameter_list2 : 
  (','  type  ID)*  -> ^(type ID)*; 
  

declarations :
  (   type idlist ';' )*  ->  ^(DECL ( ^(type  idlist))*) ;
  
idlist : 
  ( ID idlist2 );
   
idlist2 : 
  ( ',' ! idlist ) ?;
  
optional_stmt :
  ( stmt_list ) ?;

stmt_list : 
  statement statement2;

statement2 : 
  stmt_list ?;

return_stmt : 
   'return' ^  expression ';' ! ;

statement :
  (
    compound_stmt
    | ifThenElse
    | forLoop
    | assignment ';' !
  ) ;
  
ifThenElse :
  (
  'if' '('  ifCondition=expression ')' ifBody=statement 'else' elseBody=statement -> ^(IF_STATEMENT ^(IF_CONDITION $ifCondition) ^(IF_BODY $ifBody) ^(ELSE_BODY $elseBody)) 
  )
;

forLoop :
  (
    'for' '(' forInitialization=assignment ';' forCondition=expression ';' forIncrement=assignment ')' forBody=statement -> 
    ^(FOR_STATEMENT ^(FOR_INITIALIZE $forInitialization) ^(FOR_CONDITION $forCondition) ^(FOR_INCREMENT $forIncrement) ^(FOR_BODY $forBody))
  )
;

compound_stmt :
  '{'! optional_stmt '}' !;

assignment :
  ID ASSIGNOP ^ expression;

expression: andExpression (OR ^ andExpression)*;
andExpression: relOPExpression (AND ^ relOPExpression)*;
relOPExpression: signExpression (RELOP ^ signExpression)*;
signExpression : mulExpression (SIGN  ^ mulExpression)*;
mulExpression : factor (MULOP ^ factor)*;
  
factor :
  (
    factorID
    | INT
    | BOOLEAN
    | LITERAL
    | NOT ^ factor
    | SIGN ^ factor
    | '('! expression ')' !
  );

factorID:    ID 
    ( function_call ->  ^(FUN ID function_call)  
        |   ->  ID
    )
    ;
  
function_call :
  '('! function_call_opt ')' !;
  
function_call_opt :
  extend_assign_expr_list  ? ;
  
extend_assign_expr_list :
  (
    expression
     extend_assign_expr_list1
  ) ;
  
extend_assign_expr_list1 :
  ( ',' ! extend_assign_expr_list ) ? ; 

像这样解析输入

int main()
{ 
  return 0;
}

效果很好!

互联网上有很多关于这个问题的建议,但似乎没有一个有效。问题是调试器确实可以工作。假设这里的问题不是输入,语法必须是它。但是,如果语法有问题,为什么解释器对这两个示例都有效?

有什么想法吗?

编辑:

我注意到由于某种原因在__Test__.java 中只包含:

M:divide
F:G0

我在解释M:asd时也得到了这个输出:

[13:47:52] Interpreting...
[13:47:52] problem matching token at 1:3 NoViableAltException('a'@[1:1: Tokens : ( T__8 | T__9 | T__10 | T__11 | T__12 | T__13 | T__14 | COLON );])
[13:47:52] problem matching token at 1:4 NoViableAltException('s'@[1:1: Tokens : ( T__8 | T__9 | T__10 | T__11 | T__12 | T__13 | T__14 | COLON );])
[13:47:52] problem matching token at 1:5 NoViableAltException('d'@[1:1: Tokens : ( T__8 | T__9 | T__10 | T__11 | T__12 | T__13 | T__14 | COLON );])

(即使认为树是正确的)

【问题讨论】:

    标签: debugging antlr


    【解决方案1】:

    AFAIK,调试器仅适用于 Java 目标。由于您的第一个语法中有 C# 特定代码:

    @lexer::namespace{Parser}
    @parser::namespace{Parser}
    

    没有生成.java 类(或者至少没有可以编译的类),并且调试器挂起(并且超时)。

    编辑

    我看到您在解析器规则中使用fragment 规则:您不能。片段规则永远不会单独成为标记,它们仅用于其他词法分析器规则。

    我在 ANTLRWorks 1.4.3 中测试了没有 C# 代码的语法,没有任何问题。

    您可以尝试以下方法:

    • 重启 ANTLRWorks
    • 更改调试器侦听的端口(可能该端口已被其他服务或 ANTLRWorks 的另一个调试运行所使用)
    • 使用最新版本的 ANTLRWorks

    【讨论】:

    • 感谢您的提示。我已将其更改为@lexer::header {} @lexer::members {},但它仍然无法正常工作。我还注意到__Text__.java 包含输入而不是预期的Java 代码..
    • @StefanR.Falk,检查我的编辑
    • 我已经用我的更改更新了我的问题。它仍然做同样的事情。我为fragment LETTER: ... 引入了一条规则,上面写着MODULE_NAME:(LETTER)*;,它应该等同于我发布的其他语法的ID。我重新启动了 ANTLRWorks 并检查了 netstat -aon | find /i "49100",它未被任何其他应用程序使用。我使用v1.4.3 来避免我在v1.5.2 中遇到的另一个错误(不记得那是什么了)。
    • 在您的最新编辑中,MODULE_NAME 匹配一个空字符串:词法分析器规则绝不能这样做,因为您的输入中有无限数量的空字符串。也许删除所有生成的文件(或整个output 文件夹)并重试。除此之外,我的想法很新鲜。
    • 天哪,我发现它为什么不起作用了。我认为“TestRig”可以包含输入数据。相反,它必须是有效的Java 类..(或空)
    猜你喜欢
    • 1970-01-01
    • 2018-07-01
    • 2017-03-06
    • 2015-01-19
    • 2017-04-15
    • 2021-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多