0

標準 SQL 構文を指定する javacc 文法ファイル .jj を扱う JSqlParser プロジェクトの文法を変更しようとしています。1 つのセクションを機能させるのに苦労したため、次の非常に単純化された文法に絞り込みました。

基本的に、私は Column : [table ] の定義を持っています。分野

ただし、テーブル自体に「.」を含めることもできます。チャー、混乱を引き起こします。

直観的に、次の文法は次のすべての文を受け入れるはずだと思います。

mytable.myfield を選択

マイフィールドを選択

mydb.mytable.myfield を選択

しかし実際には、上記の 2 番目と 3 番目のみを受け入れます。「.」が表示されるたびに、テーブルの 2 ドット バージョンの要求に進みます (つまり、テーブルの最初の派生規則)。

どうすればこの文法を機能させることができますか?

どうもありがとうヤン

    options{
        IGNORE_CASE=true ;
        STATIC=false;
            DEBUG_PARSER=true;
        DEBUG_LOOKAHEAD=true;
        DEBUG_TOKEN_MANAGER=false;
    //  FORCE_LA_CHECK=true;
        UNICODE_INPUT=true;
    }

    PARSER_BEGIN(TT)

    import java.util.*;

    public class TT {

    }
    PARSER_END(TT)


    ///////////////////////////////////////////// main stuff concerned
    void Statement() :
    { }
    {
    <K_SELECT> Column()
    }

    void Column():
    {
    }
    {
    [LOOKAHEAD(3) Table()  "." ]
    //[ 
    //LOOKAHEAD(2) (
    //      LOOKAHEAD(5) <S_IDENTIFIER> "."  <S_IDENTIFIER>  
    //      |
    //      LOOKAHEAD(3) <S_IDENTIFIER>
    //)
    //
    //
    //
    //]

    Field()
    }

    void Field():
    {}{
       <S_IDENTIFIER>
    }

    void Table():
    {}{
            LOOKAHEAD(5) <S_IDENTIFIER> "."  <S_IDENTIFIER>
            |
            LOOKAHEAD(3) <S_IDENTIFIER>
    }

    ////////////////////////////////////////////////////////



SKIP:
{
    " "
|   "\t"
|   "\r"
|   "\n"
}

TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
{
<K_CREATE: "CREATE">
|
<K_SELECT: "SELECT">
}


TOKEN : /* Numeric Constants */
{
   < S_DOUBLE: ((<S_LONG>)? "." <S_LONG> ( ["e","E"] (["+", "-"])? <S_LONG>)?
                        |
                        <S_LONG> "." (["e","E"] (["+", "-"])? <S_LONG>)?
                        |
                        <S_LONG> ["e","E"] (["+", "-"])? <S_LONG>
                        )>
  |     < S_LONG: ( <DIGIT> )+ >
  |     < #DIGIT: ["0" - "9"] >
}


TOKEN:
{
        < S_IDENTIFIER: ( <LETTER> | <ADDITIONAL_LETTERS> )+ ( <DIGIT> | <LETTER> | <ADDITIONAL_LETTERS> | <SPECIAL_CHARS>)* >
|       < #LETTER: ["a"-"z", "A"-"Z", "_", "$"] >
|   < #SPECIAL_CHARS: "$" | "_" | "#" | "@">
|   < S_CHAR_LITERAL: "'" (~["'"])* "'" ("'" (~["'"])* "'")*>
|   < S_QUOTED_IDENTIFIER: "\"" (~["\n","\r","\""])+ "\"" | ("`" (~["\n","\r","`"])+ "`") | ( "[" ~["0"-"9","]"] (~["\n","\r","]"])* "]" ) >

/*
To deal with database names (columns, tables) using not only latin base characters, one
can expand the following rule to accept additional letters. Here is the addition of german umlauts.

There seems to be no way to recognize letters by an external function to allow
a configurable addition. One must rebuild JSqlParser with this new "Letterset".
*/
|   < #ADDITIONAL_LETTERS: ["ä","ö","ü","Ä","Ö","Ü","ß"] >
}
4

4 に答える 4

1

このように文法を書き直すことができます

Statement --> "select" Column
Column --> Prefix <ID>
Prefix --> (<ID> ".")*

唯一の選択肢は、反復するかどうかです。「。」と仮定します。列をたどることはできません。これは、2 の先読みで簡単に実行できます。

Statement --> "select" Column
Column --> Prefix <ID>
Prefix --> (LOOKAHEAD( <ID> ".") <ID> ".")*
于 2015-05-08T15:33:54.470 に答える
0

Table を独自の非終端記号にする必要がある場合は、表の後にドットが続くかどうかを示すブール値パラメーターを使用してこれを行うことができます。

void Statement():{}{
    "select" Column() | "create" "table" Table(false) }

void Column():{}{
    [LOOKAHEAD(<ID> ".") Table(true) "."] <ID> }

void Table(boolean expectDot):{}{
    <ID> MoreTable(expectDot) }

void MoreTable(boolean expectDot) {
    LOOKAHEAD("." <ID> ".", {expectDot}) "." <ID> MoreTable(expectDot)
|
    LOOKAHEAD(".", {!expectDot}) "." <ID> MoreTable(expectDot)
|
    {}
}

このようにすると、直接的または間接的に、構文の先読み仕様で Table を使用できなくなります。LOOKAHEAD( Table())たとえば、構文の先読みではセマンティック先読みは使用されないため、文法のどこにも置くべきではありません。詳細については、FAQ を参照してください。

于 2015-05-09T14:51:17.527 に答える
0

実際、flex+bison (LR パーサー) の次の文法は正常に機能し、次のすべての文を正しく認識します。

mydb.mytable を作成する mytable を作成する mydb.mytable.myfield を選択する mytable.myfield を選択する myfield を選択する

それは確かにLLパーサーの制限によるものです

%%

statement:
        create_sentence
        |
        select_sentence
        ;

create_sentence:  CREATE table
        ;

select_sentence: SELECT  table '.'  ID
                |
                SELECT ID
                ;

table : table '.' ID
        |
        ID
        ;



%%
于 2015-05-09T00:24:42.877 に答える