2017-09-10 9 views
0

私はlex(flex)でコンテキスト/モードまたは "スタックのスタック"をエミュレートする方法を見つけようとしています。Lexモードやコンテキストのスタックをエミュレートする方法

特に、式yのコンテキストに戻すことができる文字列リテラルの概念を持つパーサーを作成したいと思います。

私は構文'...'を使用して生の文字列リテラルをサポートする簡単な文法を持っており、見つかったら文字列を出力します。

しかし、文字列トークンは、無制限の長さを持ちます(生成されたCソースでマクロで定義されているlexの最大バッファサイズまで)。

begin_stringトークン'end_stringトークン'と、文字列内で文字を読み取るための別個のトークンを定義します。

これを実現するには、「現在は文字列になっています」というコンテキストの概念を持ち、どのトークン化ルールが「アクティブ」であるかに影響を与えます。

ここでは、文脈のためのナイーブな文法があります。

%{ 

#include <stdio.h> 

%} 

%option noyywrap 

%% 

'[^']*' { printf("found string literal ((%s))\n", yytext); } 

\n { /* do nothing */ } 
. { /* do nothing */ } 

%% 

int main() 
{ 
    yylex(); 
    return 0; 
} 
+1

[開始条件](http://westes.github.io/flex/manual/Start-Conditions.html)を見ましたか?私があなたの質問を理解していれば、それはあなたが探しているものです(あなたのニーズを完全に理解していない可能性もありますが)。 flexを使用している場合、トークンには恣意的な制限はありません。 mallocがより多くのスペースを提供することを拒否するまで、バッファは展開されます。 – rici

答えて

1

あなたのニーズが正しく理解されている場合、その機能はstart conditionsで提供されています。マニュアルで説明されているように、開始条件は一種の状態であり、一連の作品を有効または無効にするために使用できます。

%option nodefault 
%x IN_STRING 

%% 
/* Other patterns for regular tokens */ 
"'"    { BEGIN(IN_STRING); return BEGIN_STRING; } 
<IN_STRING>"'" { BEGIN(INITIAL); return END_STRING; } 
<IN_STRING>.|\n {     return STRING_CHAR; } 

Flexは、必要に応じて、あなたがプッシュし、スタック上に現在の開始条件をポップすることを可能にする機能を有効にしますが、必要ありません。この単純なケースでは:

はたとえば、あなたが持っているかもしれません。これを行う必要がある場合は、プロローグに%option stackを追加し、上にリンクされた開始条件の章の最後にAPIの説明をお読みください。

関連する問題