4

個人的な理由で設計している C/C++/C#/Java/D に似たプログラミング言語用のスキャナーを作成しようとしています。このタスクでは、Ragel を使用してスキャナーを生成しています。多くのオペレーターがアクションをトリガーするタイミングを正確に理解するのに苦労しています。おそらく、私の学者は理論よりも実践的な知識に焦点を当てていたためであり、この非決定論的/決定論的な有限オートマトン ビジネスの多くが私の頭の中にあります。ドキュメントが不足しているか、それについての私の理解が不足していると思います。私は後者を想定しています。

いずれにせよ、私は基本から上に向かって取り組んでいます。最初の繰り返しで、いくつかのキーワードと特殊文字を特定しました。今、すべてのキーワードが識別子としてスキャンされているという問題に遭遇しました。すべてのキーワードにスキャナー演算子を使用しています。これにより、文字列がandキーワードreturnsの両方としてスキャンされるという問題が解決されました。returnreturns

識別子を正しくスキャンするにはどうすればよいですか? identifierこれを決定論的にするには、他のトークンのパターンと一致しない場合にのみ語彙素が になることを効果的に指定する必要があることを理解しています。私の知識不足をお許しください。

Ragel スクリプト:

%%{
    Identifier = (alpha | '_') . (alnum | '_')*;
    action IdentifierAction
    {
        std::cout << "identifier(\"";
        std::cout.write(ts, te - ts);
        std::cout << "\")";
    }
}%%

%%{
    main :=
    |*
        Interface => InterfaceAction;
        Class => ClassAction;
        Property => PropertyAction;
        Function => FunctionAction;
        TypeQualifier => TypeQualifierAction;
        OpenParenthesis => OpenParenthesisAction;
        CloseParenthesis => CloseParenthesisAction;
        OpenBracket => OpenBracketAction;
        CloseBracket => CloseBracketAction;
        OpenBrace => OpenBraceAction;
        CloseBrace => CloseBraceAction;
        Semicolon => SemicolonAction;
        Returns => ReturnsAction;
        Return => ReturnAction;
        Identifier => IdentifierAction;
        space+;
    *|;
}%%
4

1 に答える 1

6

Ragelに精通していませんが、いくつかのカスタムパーサーとスキャナーを実行しました。

あなたの質問は、一般的な識別子を検出するよりも、キーワードを検出することに関連しているようです。

コードが数字、「return」キーワード、セミコロン、「returns」キーワード、識別子などであるセクションを検出するようにRagelに指示するルールがあります。Altought、キーワードごとにルールを作成することは可能ですが、お勧めしません。

私が経験から学んだことは、すべてのキーワードを識別子として明示的に読み取り(一般的な「識別子」トークンを割り当てる)、C /C++コードの一部でどの識別子が「キーワード」であるかを検出する方がよいということです。

言い換えると。Ragelは識別子のみを検出します。「myvar」、「return」、「returns」はすべて「識別子」としてマークされます。後で、セマンティックアクションのコード(RagelではなくC / C ++)で、各識別子をチェックし、がC /C++のキーワードであるかどうかを検出します。これは通常、キーワードのリストを作成することによって行われます。

私はそれが次のようなものになると思います:

%%{
Identifier = (alpha | '_') . (alnum | '_')*;
action IdentifierAction
{
    String Keywords[] = 
    (
       "return",
       "if",
       "else"
    ); 

    String MyIdentifier = te - ts;
    if (SearchKeywordCode(Keywords, MyIdentifier)) {
      std::cout << "keyword(\"";
      std::cout.write(ts, te - ts);
      std::cout << "\")";
    }
    else {
      std::cout << "identifier(\"";
      std::cout.write(ts, te - ts);
      std::cout << "\")";
    }
}
}%%

したがって、「返品」または「返品」ルールはなく、「識別子」だけがあります。

于 2011-03-14T17:59:02.000 に答える