私は y.output を避けようとしますが、時にはそれが役立つこともあります。私はそれが生成したファイルを見て見ました。
state 1
2 Expression: THIS. [$end, '.']
3 | THIS . '.' VARNAME
'.' shift, and go to state 4
'.' [reduce using rule 2 (Expression)]
$default reduce using rule 2 (Expression)
基本的には、「。」が表示されると言っています。減らすことも、シフトすることもできます。リデュースは、細かくするのが難しいため、時々私をアンルグにします。シフトはルール 3 であり、明らかです (ただし、出力ではルール # について言及されていません)。「.」が表示される場所を減らします。この場合、行は
| Expression '.' TYPENAME
Expression に移動すると、次の文字 (「.」) を見て入力します。THIS |
そのステートメントの最後に到達すると、「.」が期待されます。それが去ったとき、またはエラー。ただし、この「。」が表示されます。これと「。」の間 (したがって、出力ファイルのドット)、ルールを減らすことができるため、パスの競合が発生します。を使用%glr-parser
して両方を試すことができると思いますが、競合が多いほど、予期しない出力またはあいまいなエラーが発生する可能性が高くなります。過去にあいまいなエラーがありました。特に、どのルールが原因または影響したかを覚えていない場合は、対処するのが面倒です。競合を避けることをお勧めします。
バイソンを使用する前に、この本を強くお勧めします。
「素晴らしい」解決策は考えられませんが、これにより競合は発生しません
start:
ExpressionLoop
;
ExpressionLoop:
Expression
| ExpressionLoop ';' Expression
;
Expression:
rval
| rval '.' TYPENAME
| THIS //trick is moving this AWAY so it doesnt reduce
rval:
THIS '.' VARNAME
別の方法として、ルールにさらに追加してすぐに縮小しないようにするか、後または前にトークンを追加して、どのパスを使用するか失敗するかを明確にすることで、後で縮小することができます (すべてのパスを縮小する前に知っておく必要があります)。
start:
ExpressionLoop
;
ExpressionLoop:
Expression
| ExpressionLoop ';' Expression
;
Expression:
rval
| rval '.' TYPENAME
rval:
THIS '@'
| THIS '.' VARNAME
%%
- 編集- レクサー関数による型は Var (A-Za-z09_) と型であるためfunc param
、やりたいことができない場合は注意してください。type varname
param と varname は両方とも var であるため、reduce/reduce の競合が発生します。これをそのままでは書けません。見た目だけです。そのため、書くときはそのことを念頭に置いてください。2 つを区別するトークンを記述するか、2 つのうちの 1 つとして記述する必要がありますが、追加のロジックをコード (ルールの右側の { } にある部分) に記述して、それが funcname であるかどうかを確認する必要があります。タイプと両方のケースを処理します。