4

私は楽しみのために言語解析を学ぼうとしています...

私は、実装したいと思っている単純な言語と一致すると信じているANTLR文法を作成しました。次の構文になります。

<FunctionName> ( <OptionalArguments>+) {
     <OptionalChildFunctions>+
 }

実際の例:

ForEach(in:[1,2,3,4,5] as:"nextNumber") {
   Print(message:{nextNumber})
}

この構成に一致するように文法が正しく機能していると思います。現在、その言語の抽象構文ツリーを構築しようとしています。

まず、この木がどのように見えるか正確にはわからないことを認めなければなりません。第二に、私は私のAntlr文法でこれを行う方法を完全に失っています...私は何時間もあまり成功せずに試みてきました。

これは私がツリーのために行っている現在のアイデアです:

                   FunctionName
                  /          \
           Attributes         \
               / \          /  \ 
            ID    /\    ChildFunctions
           / \   ID etc
          /   \
  Attribute  AttributeValue
        Type

これは私の現在のAntlr文法ファイルです:

grammar Test;

options {output=AST;ASTLabelType=CommonTree;}

program : function ;
function : ID (OPEN_BRACKET (attribute (COMMA? attribute)*)? CLOSE_BRACKET)? (OPEN_BRACE function* CLOSE_BRACE)?;

attribute : ID COLON datatype;

datatype : NUMBER | STRING | BOOLEAN | array | lookup ;
array  :  OPEN_BOX (datatype (COMMA datatype)* )? CLOSE_BOX ;
lookup  : OPEN_BRACE (ID (PERIOD ID)*) CLOSE_BRACE;

NUMBER
 : ('+' | '-')? (INTEGER | FLOAT)
 ;

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

BOOLEAN
 : 'true' | 'TRUE' | 'false' | 'FALSE'
 ;

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

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

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

COLON : ':' ;
COMMA : ',' ;
PERIOD  :  '.' ;

OPEN_BRACKET : '(' ;
CLOSE_BRACKET : ')' ;

OPEN_BRACE : '{' ; 
CLOSE_BRACE : '}' ;

OPEN_BOX : '[' ;
CLOSE_BOX : ']' ;

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

fragment
INTEGER
 : '0'..'9'+
 ;

fragment
FLOAT
 : INTEGER+ '.' INTEGER*
 ;

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

どんな助け/アドバイスも素晴らしいでしょう。私は何十ものチュートリアルを読んでみましたが、AST世代については何も固執していないようです:(

4

1 に答える 1

9

ステップ1は、ツリーを投稿した小さなグラフのように見せることです。現在、ツリー構築演算子がないため、フラットリストになります。

antlr.orgWebサイトのツリー構築を参照してください。

ANTLRWorksを使用して、解析ツリーとASTで何が得られるかを確認できます。ツリー構築演算子の追加を開始し、状況がどのように変化するかを観察します。

編集/追加情報:

これを行う方法の大まかなアイデアを与えるためにあなたが従うことができるプロセスは次のとおりです。

  1. ANTLRWorksをダウンロードして、グラフ作成機能を使用してください。変更を加える前後に、解析ツリーとASTを確認する必要があります。すべてがどのように機能するかを理解したら、任意のIDEまたはエディターを使用できます。
  2. ツリー構築には、2つの基本的な演算子があり!ます。コンパイラにノードをAST内に配置しないように指示する感嘆符と、 ^ANTLRにルートノードにするように指示するcarotです。まず、各非終端規則を確認し、ASTに含める必要のない要素を決定します。たとえば、コンマや括弧は必要ありません。すべての情報を取得したら、すべての情報を提供する構造にデータを入力できます(または独自のAST構造を作成できます)。カンマはもう役に立たないので、カンマに追加!します。例えば:

    function: ID (OPEN_BRACKET! (attribute (COMMA!? attribute)*)? CLOSE_BRACKET!)? (OPEN_BRACE! function* CLOSE_BRACE!)?;

  3. 前後のANTLRWorksのASTを見てください。比較。

  4. 次に、どの要素をルートノードにするかを決定します。IDルートノードになりたいようです。^その後を追加しIDて、ANTLRWorksで比較してください。

これが私があなたが望むと思うものにそれを近づけるいくつかの変更です:

program : function ;
function : ID^ (OPEN_BRACKET! attributeList? CLOSE_BRACKET!)? (OPEN_BRACE! function* CLOSE_BRACE!)?;
attributeList:  (attribute (COMMA!? attribute)*);
attribute : ID COLON! datatype;
datatype : NUMBER | STRING | BOOLEAN | array | lookup ;
array  :  OPEN_BOX! (datatype^ (COMMA! datatype)* )? CLOSE_BOX!;
lookup  : OPEN_BRACE! (ID (PERIOD! ID)*) CLOSE_BRACE!;

それがあなたのベルトの下にあるので、今度はチュートリアルのいくつかを見てください。

于 2010-01-14T00:02:06.933 に答える