1

ply lexer ルールを特殊なケースにする方法はありますか?

t_IDENT     = r'[a-zA-Z_][0-9a-zA-Z_]*'
t_OPERATOR  = r'[<>=/*+-]+'
t_DEFINE    = r'='
t_PRODUCES  = r'=>'

リストされた文字の任意の組み合わせとして演算子を定義したいと思います=が、=>独自の特殊なケースがあります。例えば:

a + b
# IDENT('a') OPERATOR('+') IDENT('b') 

a ++=--> b
# IDENT('a') OPERATOR('++=-->') IDENT('b') 

a == b
# IDENT('a') OPERATOR('==-->') IDENT('b') 

a => b
# IDENT('a') PRODUCES('=>') IDENT('b') 

a = b
# IDENT('a') DEFINE('=') IDENT('b') 

a >= b
# IDENT('a') OPERATOR('>=') IDENT('b') 

a <=> b
# IDENT('a') OPERATOR('<=>') IDENT('b') 
4

2 に答える 2

2

OPERATORはい、予期されたPRODUCES/の代わりにトークンを取得する理由はDEFINE、PLY lexer のトークン優先規則です。

内部的には、lex.py はreモジュールを使用してそのパターン マッチングを行います。マスター正規表現を作成するとき、ルールは次の順序で追加されます。

  1. 関数によって定義されたすべてのトークンは、レクサー ファイルに表示されるのと同じ順序で追加されます。
  2. 文字列で定義されたトークンは、正規表現の長さの短い順に並べ替えることによって、次に追加されます (長い式が最初に追加されます)。

特定のルールを関数に変換するだけです:

def t_DEFINE(t):
    r'='
    return t

def t_PRODUCES(t):
    r'=>'
    return t
于 2014-07-20T23:16:25.757 に答える
0

t_DEFINE自動化されたルールとルールを削除しt_PRODUCES、予約語の手法を使用して特殊なケースを処理しました。

special_operators = {'=': 'DEFINE',
                     '=>': 'PRODUCES'}

def t_OPERATOR(t):
    r'[<>=/*+-]+'
    t.type = special_operators.get(t.value, t.type)
    return t
于 2014-07-20T23:25:01.973 に答える