Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7519327
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 30, 20262026-05-30T01:53:03+00:00 2026-05-30T01:53:03+00:00

I have been working on learning ANTLR in order to create a domain specific

  • 0

I have been working on learning ANTLR in order to create a domain specific language. One of the requirements is to translate this DSL into C. I have been able to get a basic grammar that recognizes the DSL, however I am having issues translating this to C. Mainly, my problem comes from trying to translate the DSL if statement into a C if statement. I have tried using print statements in the grammar, to no avail (I am using C#).

Here is the grammar I have been testing with:

**ifTest.g**
grammar ifTest;

options
{
backtrack=true;
output=AST;
language=CSharp2;
}

/*************************
PARSER RULES
*************************/
prog    :   lambda
|   statements EOF;

lambda  :   /* Empty */;

statements
:   statement+;

statement
:   logical
|   assignment
|   NEWLINE;


logical :   IF a=logical_Expr THEN b=statements 
        {
            System.Console.Write("\tif (" + $a.text + ")\n\t{\n\t" + "\t" +     $b.text + "\n\n\t}");   
        }
        ( ELSE c=statements      
       {    
        System.Console.Write("\n\telse {\n\t\t\t" + $c.text + "\n\t}"); 
    } )?
    ENDIF   
    {
        System.Console.Write("\n}");
    }
;

logical_Expr
    :   expr    
    ;

expr    :   (simple_Expr) (op expr)*
    ;

simple_Expr     : MINUS expr
    | identifier
    | number
    ;

identifier  : parameter
    | VARIABLE
    ;

parameter   : norm_parameter
    ;

norm_parameter  : spec_label
    | reserved_parm
    ;

spec_label  : LABEL
                ;

reserved_parm   : RES_PARM
                ;

op  :   PLUS
|   MINUS
|   MULT
|   DIV
|   EQUALS
|   GT
|   LT
|   GE
|   LE
;

number      : INT
    | FLOAT
    | HEX
                ;

assignment  : identifier GETS expr
;

/*************************
    LEXER RULES
*************************/
WS  :       (' '|'\t')+ {$channel=HIDDEN;};

COMMENT :   '/*' (options {greedy=false;}:.)* '*/' {$channel=HIDDEN;}
                ;

LINECOMMENT
    :   '#' ~('\n'|'\r')* NEWLINE {$channel=HIDDEN;}
    ;

NEWLINE :   '\r'?'\n' {$channel=HIDDEN;};

IF  :   I F;
THEN    :   T H E N;
ELSE    :   E L S E;
ENDIF   :   E N D I F;

PLUS    :   '+';
MINUS   :   '-';
MULT    :   '*';
DIV :   '/';
EQUALS  :   '=';
GT  :   '>';
LT  :   '<';
GE  :   '>=';
LE  :   '<=';
ULINE   :   '_';
DOT :   '.';
GETS    :   ':=';

LABEL   :   (LETTER|ULINE)(LETTER|DIGIT|ULINE)*;

INT     :   '-'?DIGIT+;

FLOAT   :   '-'? DIGIT* DOT DIGIT+;

HEX :   ('0x'|'0X')(HEXDIGIT)HEXDIGIT*;

RES_PARM:    DIGIT LABEL;

VARIABLE:    '\$' LABEL;


fragment A:'A'|'a';    fragment B:'B'|'b';    fragment C:'C'|'c';    fragment D:'D'|'d';    
fragment E:'E'|'e';    fragment F:'F'|'f';    fragment G:'G'|'g';    fragment H:'H'|'h';    
fragment I:'I'|'i';    fragment J:'J'|'j';    fragment K:'K'|'k';    fragment L:'L'|'l';
fragment M:'M'|'m';    fragment N:'N'|'n';    fragment O:'O'|'o';    fragment P:'P'|'p';    
fragment Q:'Q'|'q';    fragment R:'R'|'r';    fragment S:'S'|'s';    fragment T:'T'|'t';    
fragment U:'U'|'u';    fragment V:'V'|'v';    fragment W:'W'|'w';    fragment X:'X'|'x';
fragment Y:'Y'|'y';    fragment Z:'Z'|'z';


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

fragment LETTER
:   A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z;

fragment HEXDIGIT   
:   '0..9'|'a..f'|'A'..'F';

When testing this with this C# class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Antlr.Runtime;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string inputString = "if $variable1 = 0 then\n  if $variable2 > 250 then\n   $variable3 := 0\n  endif\n endif";

            Console.WriteLine("Here is the input string:\n " + inputString + "\n");

            ANTLRStringStream input = new ANTLRStringStream(inputString);

            ifTestLexer lexer = new ifTestLexer(input);

            CommonTokenStream tokens = new CommonTokenStream(lexer);

            ifTestParser parser = new ifTestParser(tokens);

            parser.prog();

            Console.Read();
        }
    }
}

The output is not quite how I imagined.

**Output**
if ($variable2 > 250)
    {
            $variable3 := 0

    }
}       if ($variable1 = 0)
    {
            if $variable2 > 250 then
           $variable3 := 0
           endif

    }
}

The problem seems to be that the second if statement is printing twice, but not in the order I was hoping. I assume it has to do with me simply trying to emit the statements block within the print statements, but I am not quite sure how to go about getting this to work properly. I have been reading up on StringTemplate, or creating an AST and using a Tree Walker to walk it, but is there anyway to fix the above output to look something like this?

if ($variable1 = 0)
{
    if ($variable2 > 250)
    {
         $variable3 := 0
    }
}

Any help on which direction I should be taking would be greatly appreciated. Would it be better for me to take the leap to StringTemplate, or is there some way for me to do this with basic action code? If I left any information out, please feel free to ask.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-30T01:53:04+00:00Added an answer on May 30, 2026 at 1:53 am

    If you remove the backtracking, which is easily done in your case, you can let the parser build the C code immediately.

    Note that parser rules can take parameters (the indentation level in my example below) and can return custom objects (Strings in the example):

    Here’s your grammar without backtracking and outputting to C code (I’m not too good at C#, so the demo is in Java):

    grammar ifTest;
    
    prog    
     : statements[""] EOF {System.out.println($statements.str);}
     ;
    
    statements[String indent] returns [String str]
    @init{$str = "";}
     : (statement[indent] {$str += indent + $statement.str + "\n";})*
     ;
    
    statement[String indent] returns [String str]
     : if_statement[indent] {$str = $if_statement.str;}
     | assignment           {$str = $assignment.str;}
     ;
    
    if_statement[String indent] returns [String str]
     : IF expr THEN s1=statements[indent + "  "] {$str = "if (" + $expr.str + ")\n" + indent + "{\n" + $s1.str;}
       (ELSE s2=statements[indent + "  "]        {$str += indent + "}\n" + indent + "else\n" + indent + "{\n" + $s2.str;} )? 
       ENDIF                                     {$str += indent + "}";}
     ;
    
    assignment returns [String str]
     : identifier GETS expr {$str = $identifier.str + " = " + $expr.str + ";";}
     ;
    
    expr returns [String str]
     : rel_expr {$str = $rel_expr.str;}
     ;
    
    rel_expr returns [String str]
     : e1=eq_expr {$str = $e1.str;} ( LT e2=eq_expr {$str += " < "  + $e2.str;}
                                    | GT e2=eq_expr {$str += " > "  + $e2.str;}
                                    | LE e2=eq_expr {$str += " <= " + $e2.str;}
                                    | GE e2=eq_expr {$str += " >= " + $e2.str;}
                                    )?
     ;
    
    eq_expr returns [String str]
     : e1=add_expr {$str = $e1.str;} (EQUALS e2=add_expr {$str += " == " + $e2.str;})?
     ;
    
    add_expr returns [String str]
     : e1=mult_expr {$str = $e1.str;} ( PLUS  e2=mult_expr {$str += " + " + $e2.str;}
                                      | MINUS e2=mult_expr {$str += " - " + $e2.str;}
                                      )*
     ;
    
    mult_expr returns [String str]
     : e1=unary_expr {$str = $e1.str;} ( MULT e2=unary_expr {$str += " * " + $e2.str;}
                                       | DIV  e2=unary_expr {$str += " / " + $e2.str;}
                                       )*
     ;
    
    unary_expr returns [String str]
     : MINUS term {$str = "-" + $term.str;}
     | term       {$str = $term.str;}
     ;
    
    term returns [String str]
     : identifier {$str = $identifier.str;}
     | number     {$str = $number.text;}
     ;
    
    identifier returns [String str]
     : LABEL    {$str = $LABEL.text;}
     | RES_PARM {$str = $RES_PARM.text;}
     | VARIABLE {$str = $VARIABLE.text.substring(1);}
     ;
    
    number
     : INT   
     | FLOAT
     | HEX
     ;
    
    WS          : (' '|'\t')+ {$channel=HIDDEN;};
    COMMENT     : '/*' .* '*/' {$channel=HIDDEN;};
    LINECOMMENT : '#' ~('\n'|'\r')* NEWLINE {$channel=HIDDEN;};
    NEWLINE     : '\r'?'\n' {$channel=HIDDEN;};
    IF          : I F;
    THEN        : T H E N;
    ELSE        : E L S E;
    ENDIF       : E N D I F;
    PLUS        : '+';
    MINUS       : '-';
    MULT        : '*';
    DIV         : '/';
    EQUALS      : '=';
    GT          : '>';
    LT          : '<';
    GE          : '>=';
    LE          : '<=';
    ULINE       : '_';
    DOT         : '.';
    GETS        : ':=';
    LABEL       : (LETTER | ULINE) (LETTER | DIGIT | ULINE)*;
    INT         : DIGIT+;            // no '-' here, unary_expr handles this
    FLOAT       : DIGIT* DOT DIGIT+; // no '-' here, unary_expr handles this
    HEX         : '0' ('x'|'X') HEXDIGIT+;
    RES_PARM    : DIGIT LABEL;
    VARIABLE    : '$' LABEL;
    
    fragment A:'A'|'a';    fragment B:'B'|'b';    fragment C:'C'|'c';    fragment D:'D'|'d';    
    fragment E:'E'|'e';    fragment F:'F'|'f';    fragment G:'G'|'g';    fragment H:'H'|'h';    
    fragment I:'I'|'i';    fragment J:'J'|'j';    fragment K:'K'|'k';    fragment L:'L'|'l';
    fragment M:'M'|'m';    fragment N:'N'|'n';    fragment O:'O'|'o';    fragment P:'P'|'p';    
    fragment Q:'Q'|'q';    fragment R:'R'|'r';    fragment S:'S'|'s';    fragment T:'T'|'t';    
    fragment U:'U'|'u';    fragment V:'V'|'v';    fragment W:'W'|'w';    fragment X:'X'|'x';
    fragment Y:'Y'|'y';    fragment Z:'Z'|'z';
    
    fragment HEXDIGIT : DIGIT |'a..f'|'A'..'F';
    fragment DIGIT    : '0'..'9';
    fragment LETTER   : A | B | C | D | E | F | G | H | I | J | K | L | M 
                      | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
                      ;
    

    If you now test your parser with the input:

    if $variable1 = 0 then
      if $variable2 > 250 then
        $variable3 := 0
      else
        $variable3 := 42
      endif
    endif
    

    the following is printed to the console:

    if (variable1 == 0)
    {
      if (variable2 > 250)
      {
        variable3 = 0;
      }
      else
      {
        variable3 = 42;
      }
    }
    

    If other parts of your grammar rely (heavily) on predicates (backtracking), the same strategy as above could just as easily be applied but then in a tree grammar (so after the backtracking-parser did its job and produced an AST).

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have begun learning ANTLR in order to implement a domain-specific language (DSL) in
I'm learning mysql and have been trying to get this working, but an error
I have been working on learning C++ and Qt4 recently, but I have hit
I'm currently learning PHP and MySQL and I have been working from a basic
So I've been working on learning LINQ, and I think I'm doing this correctly,
I have been learning Objective-C as my first language and understand Classes, Objects, instances,
I have been working on a little MVC project to assist in my self-learning
I just started learning Backbone.js, and have been working on (what else) a simple
I have been working on my own library/framework for the learning experience for a
I am learning Android and have been working on an application that will need

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.