2009-08-05 33 views
0

OKですので、こちらをご覧ください。私の言語でLexとYaccで入力文字列全体を取得する方法は?

私はいくつかのコマンドを持って、私の質問はどのようにすることができ、ある

start : commands 
    ; 

commands : command 
     | command EOL commands 
    ; 

    command : xyz 
      | ggb 
      | hdh 
    ; 

    xyz : XYZ NUMBER NUMBER { /* Do something with the numbers */ } 
     ; 

    etc. etc. etc. etc. 

私のyaccファイルで

XYZ { return XYZ; } 
GGB { return GGB; } 
HDH { return HDH; } 
[0-9]+ { yylval.ival = atoi(yytext); return NUMBER; } 
\n { return EOL; } 

ファイル

XYZ 3 5 
GGB 8 9 
HDH 8783 33 

そして、私のレックスで言いますテキスト全体を取得する

XYZ 3 5 
GGB 8 9 
HDH 8783 33 

NUMBERを返す間にコマンドを入力してもよろしいですか?私のレックスは、STRING [0-9A-ZA-Z] +を返し、私はそれの長さに検証を行いたい。また

、私は

rule: STRING STRING { if (strlen($1) < 5) /* Do some shit else error */ } 

のようにそれを行うか、実際にトークン内を持っている必要があります長さによって異なるトークンを返す私のLex?

答えて

1

私が正しくあなたの最初の質問を理解している場合、あなたが望むようにコマンドの値を構築することができます

{ $$ = makeXYZ($2, $3); } 

のようなセマンティックアクションを持つことができます。

2番目の質問では、語彙分析と文法分析の境界、文法分析と意味分析の境界は困難ではなく、よく固定されています。それらを動かすことは、記述の容易さ、エラーメッセージの明確さ、およびエラーの存在の頑健性のような要素の間のトレードオフである。文字列の長さの検証を考慮すると、エラーが発生する可能性は非常に高く、異なる端末を異なる長さに返すことによってエラーメッセージが処理されると、エラーメッセージはおそらく明確ではありません。したがって、文法に依存する可能性がある場合は、意味解析段階でそれを処理します。ここでは、メッセージを簡単に調整できます。

0

あなたはすでにこのように、あなたのYACCのソースにivalフィールドとunionを持ってyylval.ival使用したよう:だから今あなたができる

%token <ival> NUMBER 

を:今、あなたはこのように、トークンタイプを指定

%union { 
    int ival; 
} 

のように、NUMBERトークンの場合は ivalフィールドには $1と表示されますあなたの2番目の質問については

私はこのような労働組合を定義したい:

%union { 
    char* strval; 
    int  ival; 
} 

、あなたにLEXのソースは、トークンタイプ

%token <strval> STRING; 
%token <ival> NUMBER; 

を指定だから今、あなたは

foo : STRING NUMBER { printf("%s (len %d) %d", $1, strlen($1), $2); } 
のようなものを行うことができます
+0

これは、stringとの一致でsegfaultを指定します。 – schwiz

1

字句解析ツール(yylex())が文字列全体を変数に格納するように手配した場合、コードそれにアクセスすることができます。パーサー固有の通信は通常のメカニズムで行われますが、解読される前に入力ライン全体を格納する別の変数(潜在的にはファイル静的変数ですが、マルチスレッドには注意してください)を持つことはできません。

+0

は、私はその明確ではなかったかもしれないと思いますが、私は HEADER BLOCK1 STUFF BLOCK1END BLOCK2 STUFF BLOCK1とBLOCK2は同じルールに一致 BLOCK2END のようなものを持っています。私が必要とするのは、BLOCK1と一致する時点でBLOCK1の全文です。 XYZ番号number {:、最も簡単な、しかし、迷惑な方法は、ちょうど私が XYZを入れなければならないすべてのルールの後のルールのすべての文字列の値を持つ、すなわち私の例から %タイプ XYZ を持つことです$$ = "XYZ" + $ 2 + $ 3; } 残業は非常に迷惑になることがあります。 – DevDevDev

関連する問題