[antlr-interest] nested parsing (BSDL)

Harald M. Müller harald_m_mueller at gmx.de
Tue Jan 1 08:03:48 PST 2008


Me ... a last time ... 

Of course, you can merge my Inner and Outer grammars into one grammar; and
yet fire up a new parser for the strings. You'd end up with a single
combined grammar then!
As the example in the main program (end of email) shows, expression now
allows to write a "spec" inside a string as well as outside - the AST will
always be the same!
Is that acceptable to you?

... still, I more and more find this a very weird language definition; I
don't think that such an "constructs inside as well as outside strings" does
occur anywhere else (on the other hand, I have seen languages that were even
weirder than that - combining free-format and fixed-column format, e.g.
...).

Regards
Harald

-----------------

grammar StringNestedLanguage;

options {
	language=CSharp;
	ASTLabelType=CommonTree;
	output=AST;
}

@parser::members {
    private CommonTree CreateAST(string input) {
		// Console.Out.WriteLine("INNER: " + input);
        ICharStream cs = new ANTLRStringStream(input);
        StringNestedLanguageLexer lexer = new StringNestedLanguageLexer(cs);
        CommonTokenStream ts = new CommonTokenStream(lexer);
        StringNestedLanguageParser parser = new
StringNestedLanguageParser(ts);
        return (CommonTree) parser.specInSTRING().Tree;
    }
}

// Standard entry point for single file.
top : definition*
    ;

definition
    : ATTRIBUTE^ ID OF! ID COLON! ENTITY! IS! expression SEMI!
    ;
    
expression
    : NUMBER
    | // if spec is in string.
      STRING                    -> { CreateAST($STRING.text) }
    | // if spec is written directly.
      spec
    ;

// Additional entry point for in-STRING parsing.
specInSTRING
    : spec 
      EOF!
    ;

spec
    : thing 
      ( COMMA! 
        thing
      )* 
    ;
    
thing
    : ls^
      LPAR!
      param
      ( COMMA! param
      )*
      RPAR!
    ;
    
ls  : ID (LBRCKT^ NUMBER RBRCKT!)?
    | NUMBER
    ;
    
param
    : ID
    | NUMBER
    | ASTERISK
    | thing
    ;

// ------

STRING @init { string t = ""; }
    : s0=SIMPLE_STRING		{ t += $s0.text.Trim('\"'); }
      IGNORE 
      ( '&' 
        IGNORE 
        s1=SIMPLE_STRING	{ t += $s1.text.Trim('\"'); }
        IGNORE
      )*
							{ $text = t; }
    ;

fragment
SIMPLE_STRING
    : '"'! ~('"')* '"'!
    ;

fragment
IGNORE
    : ( IWS
      | INL
      | ICOMMENT
      )*
    ;

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

NL   : INL						{ $channel = HIDDEN;
}
	;
	
fragment
ICOMMENT
    : '--' ~('\r'|'\n')* INL             
    ;
    
COMMENT   : ICOMMENT                       { $channel = HIDDEN; }
	;
	
ATTRIBUTE
    : 'attribute'
    ;

ENTITY
    : 'entity'
    ;
    
IS  : 'is'
    ;
    
OF  : 'of'
    ;

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

SEMI
    : ';'
    ;
    
LPAR
    : '('
    ;
    
RPAR
    : ')'
    ;
        
LBRCKT
    : '['
    ;

RBRCKT
    : ']'
    ;
    
COMMA
    : ','
    ;
    
ASTERISK
    : '*'
    ;
    
COLON
    : ':'
    ;

==============================================

using System;
using Antlr.Runtime;
using Antlr.Runtime.Tree;

namespace Interpreter {
    class Program {
        static void Main() {
            ParseAndInterpret(@"
attribute BLA of ttl74bct8374 : entity is 3;

attribute BLI of ttl74bct8374 : entity is ""BYPASS (11111111, 10001000,
00000101, 10000100, 00000001)"";

attribute BLI of ttl74bct8374 : entity is BYPASS (11111111, 10001000,
00000101, 10000100, 00000001);

attribute INSTRUCTION_OPCODE of ttl74bct8374 : entity is
        ""BYPASS (11111111, 10001000, 00000101, 10000100, 00000001),""   &
        ""EXTEST (00000000, 10000000),""  &
        ""TRIBYP (00000110, 10000110),""  &     -- Boundary Hi-Z
        ""SETBYP (00000111, 10000111),""  &     -- Boundary 1/0
        ""SCANCT (00001111, 10001111)"";        -- BCR Scan test

attribute INSTRUCTION_OPCODE of ttl74bct8374 : entity is
        BYPASS (11111111, 10001000, 00000101, 10000100, 00000001),
        EXTEST (00000000, 10000000),
        TRIBYP (00000110, 10000110),     -- Boundary Hi-Z
        SETBYP (00000111, 10000111),     -- Boundary 1/0
        SCANCT (00001111, 10001111);        -- BCR Scan test

attribute BOUNDARY_REGISTER of ttl74bct8374 : entity is
       -- num cell  port   function safe [ccell disval rslt]
         ""17 (BC_1, CLK,    input,   X),""  &
         ""16 (BC_1, OC_NEG, input,   X),""  &  -- Merged Input/Control
         ""16 (BC_1, *,      control, 1),""  &  -- Merged Input/Control
         ""15 (BC_1, D(1),   input,   X),""  &
         ""8  (BC_1, D(8),   input,   X),""  &
         ""7  (BC_1, Q(1),   output3, X,  16, 1, Z),"" &  -- cell 16 @ 1 ->
Hi-Z.
         ""0  (BC_1, Q(8),   output3, X,  16, 1, Z)"";

attribute BOUNDARY_REGISTER of ttl74bct8374 : entity is
       -- num cell  port   function safe [ccell disval rslt]
         17 (BC_1, CLK,    input,   X),
         16 (BC_1, OC_NEG, input,   X),  -- Merged Input/Control
         16 (BC_1, *,      control, 1),  -- Merged Input/Control
         15 (BC_1, D(1),   input,   X),
         8  (BC_1, D(8),   input,   X),
         7  (BC_1, Q(1),   output3, X,  16, 1, Z),  -- cell 16 @ 1 -> Hi-Z.
         0  (BC_1, Q(8),   output3, X,  16, 1, Z);
");
       }

        private static void ParseAndInterpret(string input) {
            // Setup lexer and parser
            ICharStream cs = new ANTLRStringStream(input);
            StringNestedLanguageLexer lexer = new
StringNestedLanguageLexer(cs);
            CommonTokenStream ts = new CommonTokenStream(lexer);
            StringNestedLanguageParser parser = new
StringNestedLanguageParser(ts);

            // Create the AST
            CommonTree tree = (CommonTree) parser.top().Tree;
            Console.Out.WriteLine(tree.ToStringTree());
        }
    }
}



More information about the antlr-interest mailing list