3

Linuxカーネルの構成オプションを生成するために使用されるKconfig言語のPLYを使用して、pythonパーサーを実装しようとしています。

包含を実行する source というキーワードがあるので、レクサーがこのキーワードに遭遇すると、レクサーの状態を変更して、ソースファイルをレクシングする新しいレクサーを作成します。

def t_begin_source(t):
    r'source '
    t.lexer.begin('source')

def t_source_path(t):
    r'[^\n]+\n+'
    t.lexer.begin('INITIAL') 
    global path
    source_lexer = lex.lex(errorlog=lex.NullLogger())
    source_file_name = (path +  t.value.strip(' \"\n')) 
    sourced_file = file(path + t.value.strip(' \"\n')).read()

    source_lexer.input(sourced_file)

    while True:
        tok = source_lexer.token()
        if not tok:
            break

他のどこかにこの行があります

lexer = lex.lex(errorlog=lex.NullLogger()) 

これは、パーサーによって呼び出される「メイン」または「ルート」レクサーです。

私の問題は、パーサーに別のレクサーを使用するように指示する方法や、「source_lexer」に何かを返すように指示する方法がわからないことです...

たぶん、クローン機能を使用する必要があります...

ありがとう

4

3 に答える 3

2

興味深い偶然の一致により、この質問につながったのと同じ Google 検索からのリンクで、PLY パーサー用に独自のレクサーを作成する方法が説明されています。投稿では簡単かつ適切に説明されていますが、4 つのインスタンス変数と 1 つのtokenメソッドの問題です。

于 2009-12-04T00:03:50.197 に答える
2

PLY の詳細についてはわかりませんが、私が構築したこのような他のシステムでは、インクルード ファイルのスタックを管理する単一のレクサーを使用することが最も理にかなっています。したがって、レクサーはトークンの統一されたストリームを返し、検出されたインクルード ファイルを開いたり閉じたりします。

于 2009-11-11T21:18:11.080 に答える
0

Ok、

だから私がやったことは、実際の解析の前に構築されるすべてのトークンのリストを構築することです。

parse 関数を呼び出すときに tokenfunc パラメータを使用して、パーサーが使用する getToken 関数をオーバーライドできるため、パーサーはレクサーを呼び出さなくなりました。

result = yacc.parse(kconfig,debug=1,tokenfunc=my_function)

そして、次のトークンを取得するために呼び出される関数である私の関数は、以前に構築されたトークンのリストを反復処理します。

字句解析を考慮して、ソース キーワードに遭遇すると、字句解析器を複製し、ファイルを含めるように入力を変更します。

def sourcing_file(source_file_name):
    print "SOURCE FILE NAME " , source_file_name
    sourced_file = file(source_file_name).read()
    source_lexer = lexer.clone()
    source_lexer.input(sourced_file)
    print 'END OF SOURCING FILE'

    while True:
        tok = source_lexer.token()
        if not tok:
            break
        token_list.append(tok)
于 2009-11-13T14:25:47.010 に答える