1

私は pyparsing を使って pig という言語を解析しています。入力テキストに「\t」が含まれているときに関数「lineno」を使用すると、予期しない結果が見つかりました。

質問しやすいように、問題に対処するためにコードを単純化しました。

#/usr/bin/env python
from pyparsing import *

ident = Word(alphas)
statement1 = ident + Literal('=')+ Keyword('GENERATE', caseless = True) + SkipTo(Literal(';'),ignore = nestedExpr())+ Literal(';').suppress()
statement2 = Keyword('STORE',caseless = True) + ident + Literal(';').suppress()
statement = statement1|statement2

text = """
fact = GENERATE
('Exp' :(a
                )
)  ;

STORE fact ;


"""

all_statements = statement.scanString(text)
for tokens,startloc,endloc in all_statements:
        print 'startloc:' + str(startloc) , 'lineno:' + str(lineno(startloc,text))
        print 'endloc:' + str(endloc), 'lineno:' + str(lineno(endloc,text))
        print tokens

入力テキストでは、3 行目の先頭に 3 つ以上の '\t' があることに注意してください。これを実行すると、出力は次のようになります。

startloc:1 lineno:2
endloc:66 lineno:10
['fact', '=', 'GENERATE', "('Exp' :(a\n                                )\n)  "]
startloc:68 lineno:10
endloc:80 lineno:10
['STORE', 'fact']

全部で 9 行あるので、これは間違っているはずです。最初のステートメントは 2 行目から 10 行目までです。これらの '\t' を削除すると、入力テキストは :

text = """
fact = GENERATE
('Exp' :(a
)
)  ;

STORE fact ;


"""

もう一度実行すると、結果は次のようになります。

startloc:1 lineno:2
endloc:34 lineno:5
['fact', '=', 'GENERATE', "('Exp' :(a\n)\n)  "]
startloc:36 lineno:7
endloc:48 lineno:7
['STORE', 'fact']

そして、この結果は正しいようです。最初のステートメントは 2 行目から 5 行目までであり、2 番目のステートメントは 7 行目から 7 行目までです。これは私が期待したものです。

したがって、lineno() 関数または scanString に問題がある可能性があります。または、私のコードに何か問題があるのでしょうか?

4

1 に答える 1

1

を呼び出す前にparseWithTabsを使用してくださいscanString

于 2013-06-14T05:49:17.947 に答える