3

私はParseKitのC文法を書きましたが、これは完全に機能しますが、私を夢中にさせるのはプリプロセッサステートメントです。プリプロセッサステートメントの正しいシンボル定義は何ですか?

これが私が試したことの短い例です...

@reportsCommentTokens = YES;
@commentState = '/';
@singleLineComments = '//';
@multiLineComments = '/*' '*/';
@commentState.fallbackState = delimitState;
@delimitState.fallbackState = symbolState;

@start = Empty | comments | preprocessor;

comments = comment*;
comment = Comment;

@symbols = '#include';

preprocessor = preprocessorIncludes;

preprocessorIncludes = preprocessorIncludeStatement*;
preprocessorIncludeStatement = preprocessorInclude quotedFileName*;

preprocessorInclude = '#include';
quotedFileName = QuotedString;

...しかしそれは機能しません。コメントをキャッチし、引用符付きのステートメントを含めるための簡略化された文法例として取り上げます(<>ではありません)。私はこの単純なファイルでこの文法を試しました...

/*
 * Cryptographic API.
 *
 * RIPEMD-256 - RACE Integrity Primitives Evaluation Message Digest.
 *
 * Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC
 *
 * Copyright (c) 2008 Adrian-Ken Rueegsegger <ken@codelabs.ch>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 */

// Here's one line comment

/* One line multiline comment */

#include "ripemd.h"

/* 2nd one line multiline comment */

...そしてそれは/*1行の複数行コメント*/で終わり、コメントトークンとして報告し、その後サイレントに失敗します。

そこで、「#include」記号を...に分離しようとしました。

@symbolState = '#' '#';
@symbol = '#';
numSymbol = '#';

preprocessorInclude = numSymbol 'include';

...しかし、それでも役に立ちません。

Toddが役立つかもしれませんが、「#include」のような「シンボル」を処理する正しい方法は何ですか?

4

1 に答える 1

2

ParseKitの開発者はこちら。

ロバート、あなたの文法は非常に似ていますが、ネストされた*(0 個以上の) 修飾子の使用が文法の失敗を引き起こしていることがわかりました。

問題は、あなたの@start文法プロダクションがすでにEmptyトップレベルのオプション(他の2つのプロダクションと一緒に編集)として持っていることだと思いますが、両方|のサブプロダクションには(ゼロ以上)修飾子を持つプロダクションが含まれています。これらの s は、実際には(1 つ以上の) 修飾子である必要があります。これは、トップレベルの 0 ケースを既に考慮しているためです。commentspreprocessor**+Empty

完全にはわかりませんが、これは ParseKit に固有の問題ではないと思いますが、むしろ、文法に問題があり、この問題はそのような文法ツールキットで見られた可能性があると思われます。(間違っているかもしれません)

それを念頭に置いて、文法にいくつかの小さな調整を加えて修正しました。小さな調整を加えて編集した文法を次に示します。

@reportsCommentTokens = YES;
@commentState = '/';
@singleLineComments = '//';
@multiLineComments = '/*' '*/';
@commentState.fallbackState = delimitState;
@delimitState.fallbackState = symbolState;

@start = (comments | preprocessor)*;

comments = comment+;
comment = Comment;

@symbols = '#include';

preprocessor = preprocessorIncludes;

preprocessorIncludes = preprocessorIncludeStatement+;
preprocessorIncludeStatement = preprocessorInclude quotedFileName;

preprocessorInclude = '#include';
quotedFileName = QuotedString;

Emptyトップレベルの を に置き換えたことに注目してください*。そして、ネストされた*s を+s に交換します。

この編集された文法を使用すると、目的の出力が得られます (わかりやすくするために少し切り捨てられています)。

[/*
 * Cryptographic API.
...
 */, // Here's one line comment, /* One line multiline comment */, #include, "ripemd.h", /* 2nd one line multiline comment */]/*
 * Cryptographic API.
...
 *//// Here's one line comment//* One line multiline comment *//#include/"ripemd.h"//* 2nd one line multiline comment */^

また、問題を見つけるために、文法をより単純になるように書き直しました。その方が問題を見つけやすくなりました。次に、見つけたものを元の文法に再適用しました。興味がある場合に備えて、私が思いついた簡略化された文法を次に示します。これは、この特定の文法について私の心の中でどのように考えるかです。

@reportsCommentTokens = YES;
@commentState = '/';
@singleLineComments = '//';
@multiLineComments = '/*' '*/';

@start = (comment | macro)*;

comment = Comment;

macro = include; // to support other macros, add: ` | define | ifdef` etc.

include = '#' 'include' QuotedString;
于 2012-07-16T18:19:31.000 に答える