Question

If I debug this grammar:

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$')    
    ;

With just this input:

M:divide

the debugger does simply not start saying

  • "Cannot launch the debuggerTab. Time-out waiting to connect to the remote parser".

But using this grammar here:

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 ) ? ; 

parsing an Input like

int main()
{ 
  return 0;
}

works just fine!

The internet has a lot of suggestions regarding this issue but none of them seem to work. The thing is that the debugger DOES work. Assuming that not the input is the problem here, the grammar has to be it. But if there is a problem with the grammar why would the Interpreter work for both examples?

Any ideas?

Edit:

I have noticed that for some reason in __Test__.java just contains:

M:divide
F:G0

I also get this output while Interpreting 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 );])

(even thought the tree is correct)

Was it helpful?

Solution

AFAIK, the debugger only works with the Java target. Since you have C# specific code in your first grammar:

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

there are no .java classes generated (or at least, none that will compile), and the debugger hangs (and times out).

EDIT

I see you're using fragment rules in your parser rules: you can't. Fragment rules will never become a token on their own, they're only there for other lexer rules.

I've tested the grammar without the C# code in ANTLRWorks 1.4.3, and had no issues.

You could try the following:

  • restarting ANTLRWorks
  • changing the port the debugger listens on (perhaps the port is used by another service, or another debug-run of ANTLRWorks)
  • use the most recent version of ANTLRWorks
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top