4

こんにちは私はこのような文法で単純な言語のパーサーを実装しようとしています。

program ::= "program" declarations "begin" statements "end"
declaration ::= "var" ident "as" type
type ::= "string" | "int"

最初の2つは完了しましたが、タイプ文法をどのように記述しますか?

program( prog( DECLS, STATS ) ) -->
[ 'program' ], declarations( DECLS ),
[ 'begin' ], statements( STATS ), [ 'end' ].

declaration( decl( IDENT, TYPE ) ) -->
[ 'var' ], ident( IDENT ), [ 'as' ], type( TYPE ).
4

3 に答える 3

2

文法が不十分である可能性があります。実際、キーワードが識別子などの他のトークンからどのように分離されるかを定義していません。キーワードを識別子から分離する必要のないプログラミング言語があります。また、空白やレイアウト文字が必要な他のプログラミング言語もあります。

あなたの場合、「varaasint」は有効な宣言ですか? あなたの文法はそれを示唆しています。それとも、「var a as int」と書く必要がありますか。

詳細については、この回答を調べてください。

于 2012-11-02T15:46:52.320 に答える
1

statementsあなたはルールを逃します!

とにかく、DCG ルールは Prolog の単純な構文シュガーにすぎないので、好きな Prolog 機能を使用できます。文法をコンパクトに保つ​​必要がある場合:

type(type(T)) --> [T], {memberchk(T, [int, string])}.

中括弧を使用すると、一般的な Prolog と文法規則を混在させることができます。

@false が指摘したように、文法は、入力を分割して空白を破棄するトークナイザーがある場合にのみ役立ちます。または、このスキーマを使用して、より直接的に処理することもできます (テストされていないコードに注意してください)。

program( prog( DECLS, STATS ) ) -->
   s, "program", s, declarations( DECLS ),
   s, "begin", s, statements( STATS ), s, "end", s.

declaration( decl( IDENT, TYPE ) ) -->
   "var", s, ident( IDENT ), s, "as", s, type( TYPE ).

declarations([D|Ds]) --> declaration(D), declarations(Ds).
declarations([]) --> [].

type(type(int)) --> "int".
type(type(string)) --> "string".

% skip 1 or more whitespace
s --> (" " ; "\n"), (s ; []).
于 2012-11-02T19:25:48.130 に答える
1
type(string) --> ['string'].
type(int) --> ['int'].

(実際'には必要ありません)

|orを使用できます;が、見つかった型を返す方法が複雑になります。

于 2012-11-02T15:48:07.880 に答える