9

ANTLRを使用してCSS、または少なくとも基本を解析しようとしています。ただし、レクサールールでいくつかの問題が発生しています。問題は、ID セレクターと 16 進数のカラー値の間のあいまいさにあります。わかりやすくするために簡略化された文法を使用して、次の入力を検討してください。

#bbb {
  color: #fff;
}

および次のパーサー規則:

ruleset : selector '{' property* '}';
selector: '#' ALPHANUM;
property: ALPHANUM ':' value ';' ;
value: COLOR;

およびこれらのレクサー トークン:

ALPHANUM : ('a'..'z' | '0'..'9')+;
COLOR : '#' ('0'..'9' | 'a'..'f')+;

#bbb はセレクターであるはずなのに、COLOR トークンとしてトークン化されているため、これは機能しません。16 進数で始まらないようにセレクターを変更すると、正常に動作します。これを解決する方法がわかりません。特定のトークンが特定の位置にある場合に、特定のトークンを COLOR トークンとしてのみ扱うように ANTLR に指示する方法はありますか? たとえば、それがプロパティ ルール内にある場合、それはカラー トークンであると安全に想定できます。そうでない場合は、セレクターとして扱います。

どんな助けでも大歓迎です!


解決策: 文法でやりすぎたことがわかったので、おそらく AST を使用するコードで対処する必要があります。CSS にはあいまいなトークンが多すぎて、異なるトークンに確実に分割できません。そのため、私が現在使用しているアプローチは、基本的に「#」、「.」、「:」などの特殊文字と中括弧をトークン化し、消費者コード。はるかにうまく機能し、エッジケースへの対処が容易になります。

4

4 に答える 4

8

次のように、lexer ファイルの # を COLOR から独自のものに移動してみてください。

LLETTERS: ( 'a'..'z' )
ULETTERS: ( 'A'..'Z' )
NUMBERS: ( '0'..'9' )
HASH : '#';

次に、パーサー ルールで、次のように実行できます。

color: HASH (LLETTERS | ALPHANUM)+;
selector: HASH (ULETTERS | LLETTERS) (ULETTERS | LLETTERS | NUMBERS)*;

これにより、文法的に違いを指定することができます。文法的には文脈的に大まかに説明できますが、字句的には見た目で大まかに説明できます。場所によって意味が変わる場合、その違いはレクサーではなく文法で指定する必要があります。

color と selector はまったく同じ定義であることに注意してください。レクサーは通常、入力文字列を文法に変換するモジュールとは別の段階であるため、あいまいな辞書を持つことは無効です (指摘されたように、bbb は 16 進数または小文字の文字列である可能性があります)。したがって、データの有効性チェックは別の場所で行う必要があります。

于 2009-08-24T23:32:47.323 に答える
2

Walt が言ったことと同じように、CSS 2.1 の付録 G. Grammar は、 lexHASHに対して、(他のトークンとの相対的な位置に応じて) aHASHを asimple_selectorまたは aとして解析するように言いますhexcolor

レクサーは次のトークンを定義します...

"#"{name}       {return HASH;}

...そして文法には次の規則が含まれています...

hexcolor
  : HASH S*
  ;

simple_selector
  : element_name [ HASH | class | attrib | pseudo ]*
  | [ HASH | class | attrib | pseudo ]+
  ;

これは、文法に基づくパーサーが非 16 進数の hexcolor を許可することを意味します。

後で、lexed+parsed 構文ツリーを分析/解釈するコードで、非 16 進数の hexcolor を検出します。

于 2009-08-24T23:40:15.920 に答える
0

複数の選択肢から決定を下すために、ANTLR には 2 つのオプションがあります。

  • 構文述語
  • セマンティック述語

これは、antlr grammar lib (css2.1 g) からのものです。

シンプルセレクター
    : 要素名
        ((esPred)=>elementSubsequent)*

    | | ((esPred)=>elementSubsequent)+
    ;

esPred
    : ハッシュ | ドット | Lブラケット | 結腸
    ;

elementSubsequent
    : ハッシュ
    | | cssクラス
    | | 属性
    | | 擬似
    ;

cssクラス
    : ドットIDENT
    ;

要素名
    : IDENT
    | | 星
    ;

これは、構文述語に使用されます。

文法へのリンク: http://www.antlr.org/grammar/1240941192304/css21.g

于 2012-07-09T22:32:36.830 に答える