2017-04-11 4 views
12

申し訳ありません。この質問はパーザーや文法の練習に慣れていた人にはほとんど馬鹿に思えるかもしれませんが、これらは私にとっては外国の話題です。「シンプルな」文法の解析

私はこのように見ているシングル「特殊な構造」が含まれ、次の「言語」、のためのパーサを書きたいと思います:

\command[ options ]{ contents } 

内容は、ネストされたコマンドを含む何でも、することができ、および含まれていてもよいです括弧またはエスケープされた括弧\{ \} \\。私は「何か」は具体的ではないことを認識していますが、理想的には、可能であれば括弧(エスケープされたものを除く)で決める必要があります。

オプションは、name = valueとして代入式のコンマ区切りのリストであるべきであるが、値は=又は,文字を含む引用符で囲まれた文字列であってもよいです。最後に、前のnameとは、正規表現\w[\w\d\._-+*]*を検証する必要があります。つまり、最初の文字は文字で、残りの文字は文字、数字、または. _ - + *のいずれかです。

正規表現でこれを書くのはあまりにも複雑です(たとえば、値には代入や名前/値のペアを区切る、引用符付きの文字, =が含まれる可能性があるため)。だから私はここで最も適切なツールは文法だと思うが、表面的な読みにもかかわらず、それを書く方法(BNF、PEGなど)、パーサーの種類(LR、再帰的なものなど)実用的なプログラムで解析出力をどのように使用することができるかを示します。

私はタグを説明しているPythonの回答が好きですが、もちろん、必要に応じてツールの組み合わせが完全に満足しています。


注:これはLaTeXの話ではありません。私はもちろん類似点を認識していますが、LaTeXは以前の言語よりもはるかに複雑です。たとえば、文脈によって文字コードが異なります。私は単なる実用的な例を求めているだけであり、私は日々の仕事の中で既に役に立つと思っています。

+0

これは(La)TeXですか? –

+0

いいえ:) LaTeXは、文字コード、 '@'文などではるかに複雑です。これはLaTeXの非常に強い制限です。私は主に、職場ですでに役に立つことができるケースについて学びたいと思っているので、私は主張しています。 – Sheljohn

+3

タイトルを解析して質問を読むことができます。実際には解析しています。 –

答えて

6

あなたが好む表記で、より正式にあなたの文法を表現することから始めます。例えば、あなたの説明から、EBNFは次のようになり:

program := element+ 
element := command | literal 
literal := (not '\')+ 

command := '\'identifier options? '{' program '}' 
options := option | options ',' option 
option := identifier '=' value 
value := number | string 

string := '"' (escape | not '\' or '"')* '"' 
escape : = '\' char 

そしてパーサジェネレータ(pyParsing、pyYACC、ANTLR)にこれを供給または手でパーサを書くのいずれか。後者の場合、トップダウンは最も簡単なオプションです:文法の先頭から始め、各ルールを解析されたASTノードを返す関数に変換し、入力を消費するか、何も返さないかスローします。例:

next_symは(EOFまたは None)入力から次のシンボルを返す
def program(): 
    elements = [] 
    while next_sym(): 
     elements.append(element()) 
    return {'type': 'program', 'children': elements} 

def element(): 
    return command() or literal() 

def command(): 
    if next_sym() == '\\': 
     get_sym() 
     ...parse command here 
     return {'type': 'command', 'children': ...} 
    return None 

get_symシンボルを消費し、入力バッファを進めます。

+0

ありがとうございました。この例では 'identifier、number&char'プリミティブですが、残りを定義したときにそれらを定義する必要がありますか? 'string 'の定義に関しては、' \ 'や' ''ではない部分がブラックスラッシュと二重引用符を強制的にエスケープするように強制されますか? – Sheljohn

+0

あなたが使っている方法によっては、そうでなければ、正規表現を使ってそれらを定義しなければなりません。 – georg

+0

エスケープに関しては、これは正しいです。 – georg

関連する問題