2

json/xml/yaml/異なる文字列エンコーディング/追加の数値タイプなどの新しいリテラルの例をサポートするためにコンパイラを簡単に拡張できる言語はありますか? いつでもコンパイラをフォークしてDSLを書くことができることは理解していますが、それは私が求めていることではありません。smalltalk や lisp などの一部の言語は信じられないほど柔軟であることは理解していますが、1 つのチームでかなり簡単に実行できるものを探しているのではなく、これを言語全体にもたらし、それを一般的な慣行として許可する試みである何かを探しているわけではありません。 . 同様のアイデアに関する研究を共有することもできます。

あるいは、文字列引数 alla を持つオブジェクトの特別なメソッドを介してリテラルをサポートする言語があります (この場合、""" は、Xml.newFromTripleString(String a) に渡される文字列の開始と終了を示します)。

Xml exapmleXml=""" #{name} #{title} """ 多くの言語が XMl exapmleXml= Xml.newFromTripleString(" " + "\n" " + "\n " + " #{name} + "\n" + " #{title} + "\n" + "") しかし、暗黙的な変換のようなものでこれを簡単にしようとする言語はありますか?これらの種類の技術に関する研究はありますか?

言語でより柔軟なリテラルまたはリテラルのようなサポートを導入する方法に関する他のアイデアへのリンクと説明もあればいいでしょう。

4

3 に答える 3

3

イオケ

Ioke では、リテラルのオーバーライドは許可されていますが、新しいリテラルの定義は許可されていません。これが機能する方法は、リテラルが単純にメッセージ送信に変換され、対応するメソッドを他のメソッドと同じようにオーバーライドできることです。

たとえば、これはDict2 つのエントリを持つ a の「リテラル構文」です。1 つは aSymbolを aにマッピングし、もう 1 つは a を aTextにマッピングSymbolNumberます。

{ :name => "Jörg", :age => 31 }

これは、実際には、という名前のメッセージのメッセージ送信に変換されます{}(ところで: リストは同じように機能し、対応するメッセージは です[])。これは、次のものとまったく同じです (必要に応じて、このように書くこともできます)。

{}(:name => "Jörg", :age => 31)

現在、実際には、ほとんどすべてのオブジェクトに対して定義されている演算子であり、キー(最初の要素)がレシーバーであり、値が引数である=>a を返すだけです。Pair現在、オペレーターは単なるメッセージ送信であるため、これは次と同等です。

{}(:name =>("Jörg"), :age =>(31))

:リテラル記号を表すシジルも、メッセージ送信に変換されます。

{}(:("name") =>("Jörg"), :("age") =>(31))

internal:createTextテキスト リテラルは、メッセージの送信に変換されます。

{}(:("name") =>(internal:createText("Jörg")), :("age") =>(31))

[注: 明らかに、ここに書かれている方法は無限再帰につながります。実のところ、 への引数internal:createTextは明らかに IokeTextではなく、プラットフォーム文字列です。つまり、 Iokeikjの JVM 実装の場合は実際には でjava.lang.Stringありikc、CIL 実装の場合はSystem.Stringです。ここでは三重引用符を使用してこれを表現しました。]

{}(:("name") =>(internal:createText("""Jörg""")), :("age") =>(31))

これにより、番号が残ります。これは、ご想像のとおり、送信されたメッセージでもあります。

{}(:("name") =>(internal:createText("""Jörg""")),
   :("age") =>(internal:createNumber("""31""")))

すべてがメッセージ送信であるため、対応するメソッドを実装するだけで、リテラルの動作を自由にカスタマイズできます。iik以下は、インタラクティブな Ioke REPLからの短いトランスクリプトです。

iik> "Hello"
+> "Hello"

iik> internal:createText = method(raw, super(raw) upper)

iik> "Hello"
+> "HELLO"

収束する

Converge は、 DSL ブロックと呼ばれる機能を含む、強力なコンパイル時のメタプログラミングを可能にします。DSL ブロックは、Converge 構文を使用しないコードのブロックです。DSL ブロックは次のようになります。

$<<xml>>:
    <xml>
      <literal>here</literal>
    </xml>

$<<これが機能する方法は、との間の文字列は、コンパイル時>>に呼び出され、DSL ブロック全体を文字列として渡される関数の名前です (行番号、ファイル名などの一部のソース コード メタデータも同様です)。 .) そして、Converge 抽象構文ツリーのフラグメントを返します。したがって、この特定のケースでは、次のような関数があります。

func xml(dsl_block, src_infos):
    // implement an XML parser here ...
    return ast

要素

Factor では、同じスコープ内の他の単語が解析される方法に影響を与える単語である解析単語の定義が可能です。実際には、Factor にはXML ライブラリの実装があり、解析語を使用して Scala の XML リテラルに非常によく似た構文を取得しますが、通常の Factor コードです。

: feed>xml ( feed -- xml )
    [ title>> ]
    [ url>> present ]
    [ entries>> [ entry>xml ] map ] tri
    <XML
        <feed xmlns="http://www.w3.org/2005/Atom">
            <title><-></title>
            <link href=<-> />
            <->
        </feed> 
    XML> ;

[Factor の簡単な紹介::新しい単語を定義します。つまり、最初の行では、 feed>xml1 つの引数を取り、1 つの結果を生成するという名前の単語を定義します。単語の最初の 3 行は、フィード オブジェクトからタイトル、URI、およびエントリを抽出し、それらをスタックに配置します。は、XML モードをオンにして再びオフに<XMLする構文解析語です。XML>XML コード内で<->、スタックから値を取得し、それを XML に挿入します。]

Common Lisp

Common Lisp Reader Macrosを使用すると、読み取りステージ、つまり、文字列を取得してネストされたリストを生成し、それらをコンパイラ/評価器に渡すステージにフックできます。一意の 1 文字または 2 文字のプレフィックスを選択する必要があり、それらはグローバルです。最初のものはそれほど問題ではありません。<文字をプレフィックスとして選択するだけで、自然に見えるようにすることができるからです。

パール6

Perl 6 では、プログラムの実行中に構文を変更できるはずです。Perl 6 には動的可変文法があります。つまり、コードは実行中に解析され、文法を変更して、ファイル内の他のコードが新しい文法を使用して解析されるようにすることができます。

OMeta/COLA

Ian Piumarta の COLA システム上で動作するAlessandro Warth の OMeta 言語は、彼らが「気分固有の言語」と呼ぶものを可能にします。つまり、仕様と実装が非常に軽量であるため、プログラムの途中で 1 行だけ使用して、別の構文に再び切り替えることができる言語です。

これは、Alan Kay's Viewpoint Research InstituteのInventing Fundamental New Computing Technologiesで使用されています。使用例の 1 つは、IETF RfC で使用される ASCII アート図と同じ構文を持つ言語と、ネットワーク プロトコルのステート マシンを記述するための別の言語を設計することにより、わずか 200 行のコードで TCP/IP ネットワーク スタック全体を実装することです。次に、ネットワーク スタックの実装は、RfC から ASCII ダイアグラムをコピー & ペーストし、RfC から英語のステート マシン記述をステート マシン言語に変換するだけです。

(ご参考までに、200 行は ASCII ダイアグラムとステート マシンだけではありません。2 つの言語のパーサーとコンパイラも含まれています。)

π

π プログラミング言語もおそらく興味深いものです。

于 2010-06-29T17:41:01.747 に答える
2

C++ 0x (警告: 大きな PDF)のユーザー定義リテラル (§2.14.8) は、探しているものにかなり近い (または正確に) ようです。

于 2010-06-29T03:57:34.517 に答える
1

D プログラミング言語には、コンパイル時に、JSONを含む文字列リテラルを対応する object/struct/arraysに変換するために必要な構造があります。コンパイル時に外部ファイルから文字列をロードすることもできます。それを行うコードは知りませんが、書くのは特に難しくありません。

実行時に同じことが必要な場合、D には連想配列動的配列、およびOO 機能の標準セットがあるため、遺伝的な JSON DOM モデルの構築は難しくありません。

他のエンコーディングについては知りませんが、JSON よりも問題があるとしたら驚きです。

簡単な答え: D はネイティブでサポートしていませんが、機能させるのはまったく難しくありません。

于 2010-06-29T05:27:20.423 に答える