2017-10-26 4 views
2

次のlexコードでは、山括弧の使用を理解していません。 < newstate> {DEFINITION}構文はどのように機能しますか?lex codeの構文を理解する

 %{ 
    #include<stdio.h> 
    int c=0; 
    %} 
    START "/*" 
    END "*/" 
    SIMPLE [^*] 
    SPACE [ \t\n] 
    COMPLEX "*"[^/] 
    %s newstate 
    %% 
    "//"(.*[ \t]*.*)*[\n]+ {c++; fprintf(yyout," ");} 
    {START}     {yymore();BEGIN newstate;} 
    <newstate>{SIMPLE}  {yymore();BEGIN newstate;} 
    <newstate>{COMPLEX}  {yymore();BEGIN newstate;} 
    <newstate>{SPACE}  {yymore();BEGIN newstate;} 
    <newstate>{END} {c++;fprintf(yyout," ");BEGIN 0;} 
    %% 
    main() 
    {//program to remove comment lines 
    yyin=fopen("file4","r"); 
    yyout=fopen("fileout4","w");system("cat file4"); 
    yylex();system("cat fileout4"); 
    printf("no.of comments=%d",c); 
    fclose(yyin); 
    fclose(yyout); 
    } 
    ` 
+1

有限状態機械のオートマトン理論について知っているかどうかは分かりません。この場合、答えは簡単です。BEGINは、通常の状態遷移のように特定の状態を設定します。角括弧構文は "現在の状態がこの状態であるときこれらを認識する"を意味します。初期状態は0なので、 'BEGIN 0'に戻ります。 https://stackoverflow.com/q/15540944/1256452も参照してください。 – torek

答えて

4

"%s newstate"では、開始条件名を宣言しています。名前は "newstate"です。 %s、%Sまたは%Startを使用して開始条件を宣言できます。

条件は、<>角括弧でルールの先頭で参照できます。

例えば:最初の規則のためのあなたの開始条件として参照NewStateに:

   <newstate> {SIMPLE}  { yymore(); BEGIN newstate; } 

レックスは「NewStateに」という名前の開始条件のときにあなたの上記のルールにのみ認識されます。 、私は3つの開始条件各1が表す何か、AN =動物を使用しますが、この例では :あなたは、アクション文

      BEGIN newstate; 

私はその使用を理解するためにあなたのサンプル例を挙げてみましょう

を実行して、この開始条件を入力していますPT =惑星、BR =鳥。

このflexの例は、あなたが入力した名前の後ろに「is?」というカテゴリを示すのに役立ちます。属する。動物、惑星、鳥類の3つのカテゴリがあります。 (私は猿、馬、木星、白鳥だけを扱うことが簡単です)。

     %{ 
        #include<stdio.h> 
        %} 

        %START AN PT BR 

        %% 
        ^monkey    {ECHO; BEGIN AN;} 
        ^horse    {ECHO; BEGIN AN;} 
        ^Jupiter   {ECHO; BEGIN PT ;} 
        ^swan    {ECHO; BEGIN BR;} 
        \n     {ECHO; BEGIN 0;} 
        <AN>is?    printf(" is an Animal.!"); 
        <PT>is?   printf(" is a Planet in our solar system.!"); 
        <BR>is?   printf(" is a Bird.!"); 
        . ; 
        %% 

        main() 
        { 
        yylex(); 
        } 

次の入力については、「is?」を置き換えます。プレフィックスに基づいて:

    input ->   monkey is ? 
       output ->   monkey is an Animal.! 

ここでは「is?」を置き換えます。 「動物である!」とLexical Analyzerを "AN"開始条件にリダイレクトすることにより、関連するルール "is?printf(" Animal!! ");"が実行されます。

    input ->   swan is ? 
       output ->   swan is Bird.! 

ここでは「is?」を置き換えます。 「鳥です!」レキシカルアナライザを "BR"開始条件にリダイレクトすることによって、関連ルール "is?printf("はバードです! ");"が実行されます。ここでは、交換する

    input ->   horse is ? 
       output ->   horse is an Animal.! 

は "?" 「動物である!」とLexical Analyzerを "AN"開始条件にリダイレクトすることにより、関連するルール "is?printf(" Animal!! ");"が実行されます。

    input ->   Jupiter is ? 
       output ->   Jupiter is a Planet in our solar system.! 

ここでは「is?」を置き換えます。 「私たちの太陽系の惑星です!」レキシカルアナライザを "PT"開始条件にリダイレクトして、それに関連するルール "is?printf("は太陽系内の惑星です! ");"が実行されます。

この例では、「is?」を置き換えていることがわかります。接頭辞に基づいて接頭辞がJupiterの場合、「Jupiter」をエコーし​​、Lexical Analyzerを「PT」開始条件にリダイレクトします。したがって、関連するルールが実行されます。

私はこれがあなたの理解に役立つことを願っています。説明に問題がある場合は教えてください!