Amazon Best VPN GoSearch

OnWorksファビコン

peg - クラウドでオンライン

Ubuntu Online、Fedora Online、Windowsオンラインエミュレーター、またはMACOSオンラインエミュレーターを介してOnWorks無料ホスティングプロバイダーでペグを実行します

これは、Ubuntu Online、Fedora Online、Windowsオンラインエミュレーター、MACOSオンラインエミュレーターなどの複数の無料オンラインワークステーションのXNUMXつを使用してOnWorks無料ホスティングプロバイダーで実行できるコマンドペグです。

プログラム:

NAME


ペグ、レッグ-パーサジェネレータ

SYNOPSIS


ペグ [-hvV -o出力] [ファイル名 ...]
[-hvV -o出力] [ファイル名 ...]

DESCRIPTION


ペグ および 再帰下降パーサーを生成するためのツールです:実行するプログラム
テキストのパターンマッチング。 彼らは、Parsing Expression Grammar(PEG)[Ford2004]を次のように処理します。
その文法の合法的な文を認識するプログラムを作成します。 ペグ PEGを処理します
フォードによって記述された元の構文を使用して書かれました。 を使用して書き込まれたPEGを処理します
それを魅力的にすることを目的としたわずかに異なる構文と規則
で構築されたパーサーの代替 LEX(1)と ヤック(1)。 ようではない LEX および ヤック, ペグ および
無制限のバックトラックをサポートし、曖昧性解消の手段として順序付けられた選択肢を提供し、
スキャン(字句解析)と構文解析(構文解析)をXNUMXつに組み合わせることができます
活動。

ペグ 指定された読み取り ファイル名s、またはない場合は標準入力 ファイル名sが与えられます。
生成するパーサーを説明する文法。 ペグ 次に、Cソースファイルを生成します。
関数を定義します yyparse()。 このCソースファイルは、インクルードするか、コンパイルしてからコンパイルすることができます。
クライアントプログラムにリンクされています。 クライアントプログラムが呼び出すたび yyパース()パーサー
の最初のルールから開始して、解析ルールに従って入力テキストを消費します。
文法。 yyパース()は、入力が次のように解析できる場合、ゼロ以外を返します。
文法; 入力を解析できなかった場合はゼロを返します。

接頭辞「yy」または「YY」は、生成されたすべての外部から見えるシンボルの前に付加されます
パーサー。 これは、クライアントプログラムでの名前空間の汚染のリスクを軽減することを目的としています。
(「yy」の選択は歴史的です。を参照してください。 LEX(1)と ヤック(1)たとえば。)

OPTIONS


ペグ および 次のオプションを提供します。

-h 使用可能なオプションの要約を出力してから終了します。

-o出力
生成されたパーサーをファイルに書き込みます 出力 標準出力の代わりに。

-v 作業中に詳細情報を標準エラーに書き込みます。

-V バージョン情報を標準エラーに書き込んでから終了します。

A SIMPLE 実施例


以下 ペグ inputは、単一のルール( 'start'と呼ばれる)を持つ文法を指定します。
入力に文字列「username」が含まれている場合に満たされます。

開始<-"ユーザー名"

(引用符は 一致したテキストの一部。 それらはリテラルを示すのに役立ちます
照合する文字列。)つまり、 yyパース生成されたCソースの()は
入力から読み取られた次のXNUMX文字が「ユーザー名」という単語を綴る場合にのみ、ゼロ以外の値になります。
入力に他のものが含まれている場合、 yyパース()はゼロを返し、入力はありません
消費されます。 (その後の呼び出し yyパース()もゼロを返します。これは、パーサーが
文字列「username」の検索を効果的にブロックしました。)進行状況を確認するために、
「username」の場合、任意のXNUMX文字に一致する「start」ルールの代替句
見つかりません。

開始<-"ユーザー名"
/。

yyパース()は常にゼロ以外を返すようになりました(入力の最後を除く)。 する
ルールにアクションを追加できる便利なもの。 これらのアクションは、
完全一致が(最初のルールから開始して)検出され、
入力に一致するように文法を通過する「パス」。 (言語学者はこのパスを
「フレーズマーカー」。)

start <-"username" {printf( "%s \ n"、getlogin()); }
/ <。 > {putchar(yytext [0]); }

最初の行は、パーサーが表示されたときにユーザーのログイン名を出力するように指示します。
入力の「username」。 その一致が失敗した場合、XNUMX行目はパーサーにエコーするように指示します
入力の次の文字は標準出力です。 私たちのパーサーは現在、有用なパフォーマンスを示しています
動作:入力を出力にコピーし、出現するすべての「username」を次のように置き換えます。
ユーザーのアカウント名。

XNUMX番目の選択肢に追加された山かっこ( '<'および '>')に注意してください。 これらは
ルールの意味には影響しませんが、利用できるようになったテキストを区切るのに役立ちます
変数内の次のアクション yyテキスト.

上記の文法がファイルに配置されている場合 ユーザー名.peg、コマンドを実行する

ペグ -o ユーザー名.c ユーザー名.ペグ

対応するパーサーをファイルに保存します ユーザー名.c。 完全なプログラムを作成するには
このパーサーは、次のようにCプログラムに含めることができます。

#含む/ * printf()、putchar()* /
#含む/ * getlogin()* /

#include "username.c" / * yyparse()* /

int main()
{
while(yyparse())/ * EOFまで繰り返す* /
;
0リターン;
}

PEG 文法


文法は、名前付きルールのセットで構成されています。

名前<-パターン

この パターン 次の要素のXNUMXつ以上が含まれています。

要素は、指定されたルールのパターン全体を表します .

"文字"
二重引用符で囲まれた文字または文字列は、文字通り一致します。 ANSI C
エスケープシーケンスは、 文字.

'文字'
上記のように、一重引用符で囲まれた文字または文字列は文字通り一致します。

[文字]
角かっこで囲まれた文字のセットは、
上記のように認識されたエスケープ文字を含むセット。 セットがで始まる場合
上矢印(^)の場合、セットは無効になります(要素は任意の文字と一致します) 会場は
セットする)。 ダッシュ(-)で区切られた文字のペアは、
最初からXNUMX番目までの文字。 単一の英字
またはアンダースコアは、次のセットと一致します。

[a-zA-Z_]

同様に、以下は数字以外の任意のXNUMX文字に一致します。

[^ 0-9]

. ドットは任意の文字に一致します。 これが失敗するのは最後にあることに注意してください
一致する文字がないファイル。

( パターン )
括弧はグループ化に使用されます(演算子の優先順位を変更します)
以下で説明します)。

{ アクション }
中括弧はアクションを囲みます。 アクションは任意のCソースコードです
マッチングの最後に実行されます。 アクション内の中括弧は適切に配置する必要があります
ネストされています。 アクションの前に一致し、角度で区切られた入力テキスト
ブラケット(以下を参照)は、アクション内でコンテンツとして使用可能になります。
文字配列 yyテキスト。 (の文字数)の長さ yyテキスト is
変数で利用可能 イレン。 (これらの変数名は履歴です。を参照してください。
LEX(1)。)

< 開き山かっこは常に一致し(入力を消費しない)、パーサーを引き起こします
一致したテキストの蓄積を開始します。 このテキストは、のアクションで利用できるようになります
変数 yyテキスト.

> 閉じ角ブラケットは常に一致し(入力を消費しない)、パーサーを引き起こします
のテキストの蓄積を停止するには yyテキスト.

上記 素子■次の接尾辞を使用して、オプションおよび/または繰り返し可能にすることができます。

素子 ?
この要素はオプションです。 入力に存在する場合、それは消費され、一致します
成功します。 入力に存在しない場合、テキストは消費されず、一致は成功します
とにかく。

素子 +
要素は繰り返し可能です。 入力に存在する場合、XNUMXつ以上のオカレンス
素子 消費され、試合は成功します。 の発生がない場合 素子  
入力に存在する場合、一致は失敗します。

素子 *
この要素はオプションであり、繰り返し可能です。 入力に存在する場合、XNUMXつ以上
の発生 素子 消費され、試合は成功します。 の発生がない場合
素子 入力に存在する場合、とにかく一致は成功します。

上記の要素と接尾辞は、述語(任意に一致する)に変換できます
テキストを入力し、その後成功または失敗 無し その入力を消費する)
次のプレフィックス:

& 素子
述語は、次の場合にのみ成功します 素子 一致させることができます。 中にスキャンされた入力テキスト
マッチング 素子 入力から消費されず、
その後のマッチング。

! 素子
述語は、次の場合にのみ成功します 素子 一致させることはできません。 中にスキャンされた入力テキスト
マッチング 素子 入力から消費されず、
その後のマッチング。 人気のイディオムは

!.

これは、入力の最後の文字がすでに入力された後、ファイルの終わりに一致します
消費されました。

'&'述語の特別な形式が提供されます:

&{ 表現 }
この述語では、単純なC 表現 ( ステートメント)はすぐに評価されます
パーサーが述語に到達したとき。 の場合 表現 ゼロ以外(true)を生成します
'match'は成功し、パーサーはパターン内の次の要素を続行します。
Status 表現 ゼロ(false)を生成します。「一致」は失敗し、パーサーはにバックアップします。
入力の代替解析を探します。

いくつかの要素(接頭辞と接尾辞の有無にかかわらず)を組み合わせて、 シーケンス
それらを次々に書くことによって。 シーケンス全体が一致するのは、各個人が
その中の要素は、左から右に一致します。

シーケンスは、交互演算子 '/'によって互いに素な選択肢に分けることができます。

シーケンス-1 / シーケンス-2 / ... / シーケンス-N
各シーケンスは、そのうちのXNUMXつが一致するまで順番に試行され、一致する時点で一致します。
全体的なパターンが成功するため。 いずれのシーケンスも一致しない場合は、一致します
全体的なパターンの失敗します。

最後に、ポンド記号(#)は、最後まで続くコメント(破棄)を導入します
ラインの。

上記を要約すると、パーサーは入力テキストをパターンと照合しようとします
リテラル、名前(他のルールを表す)、およびさまざまな演算子(
接頭辞、接尾辞、順序付けのための並置、および中置交替演算子)
パターン内の要素の一致方法を変更します。 試合は左から
右、「降順」で名前付きサブルールに遭遇します。 マッチングプロセスの場合
失敗した場合、パーサーは「バックトラック」(プロセスで入力を適切に「巻き戻し」)します。
文法を通して最も近い代替の「パス」を見つけます。 言い換えれば、パーサー
一致に成功した最初のパスに対して、深さ優先の左から右への検索を実行します
ルールを通して。 見つかった場合、成功したパスに沿ったアクションが実行されます(
それらが遭遇した順序)。

述語が評価されることに注意してください 直ちに 成功した一致の検索中に、
検索の成功または失敗に寄与するためです。 ただし、アクションは
成功した一致が見つかった後にのみ評価されます。

PEG 文法 FOR PEG 文法


の文法 ペグ 文法を以下に示します。 これは、説明と形式化の両方を行います
上記の説明。

文法<-間隔の定義+ EndOfFile

定義<-識別子LEFTARROW式
式<-シーケンス(SLASHシーケンス)*
シーケンス<-プレフィックス*
プレフィックス<-ANDアクション
/(AND | NOT)? サフィックス
サフィックス<-プライマリ(QUERY / STAR / PLUS)?
プライマリ<-識別子!LEFTARROW
/ OPEN式CLOSE
/リテラル
/ クラス
/ドット
/ アクション
/ 始める
/ 終わり

識別子<-<IdentStartIdentCont *>間隔
IdentStart <-[a-zA-Z_]
IdentCont <-IdentStart / [0-9]
リテラル<-['] <(!['] Char)*> [']間隔
/ ["] <(!["] Char)*> ["]間隔
クラス<-'[' <(! ']'範囲)*> ']'間隔
範囲<-Char'- 'Char / Char
Char <-'\\' [abefnrtv '"\ [\] \\]
/ '\\' [0-3][0-7][0-7]
/ '\\' [0-7] [0-7]?
/ '\\' '-'
/! '\\'。
左矢印<-'<-'間隔
SLASH <-'/'間隔
AND <-'&'間隔
<-'!'ではありません間隔
QUERY <-'?' 間隔
STAR <-'*'間隔
PLUS <-'+'間隔
OPEN <-'('間隔
CLOSE <-')'間隔
ドット<-'。' 間隔
間隔<-(スペース/コメント)*
コメント<-'#'(!EndOfLine。)* EndOfLine
スペース<-'' / '\ t' / EndOfLine
EndOfLine <-'\ r \ n' / '\ n' / '\ r'
EndOfFile <-!。
アクション<-'{' <[^}] *> '}'間隔
BEGIN <-'<'間隔
END <-'>'間隔

LEG 文法


の変形です ペグ のいくつかの機能を追加します LEX(1)と ヤック(1)。 とは異なります
ペグ 次のように。

%{ 文章... %}
宣言セクションは、ルール定義が期待される場所であればどこにでも表示できます。 ザ
클라우드 기반 AI/ML및 고성능 컴퓨팅을 통한 디지털 트윈의 기초 – Edward Hsu, Rescale CPO 많은 엔지니어링 중심 기업에게 클라우드는 R&D디지털 전환의 첫 단계일 뿐입니다. 클라우드 자원을 활용해 엔지니어링 팀의 제약을 해결하는 단계를 넘어, 시뮬레이션 운영을 통합하고 최적화하며, 궁극적으로는 모델 기반의 협업과 의사 결정을 지원하여 신제품을 결정할 때 데이터 기반 엔지니어링을 적용하고자 합니다. Rescale은 이러한 혁신을 돕기 위해 컴퓨팅 추천 엔진, 통합 데이터 패브릭, 메타데이터 관리 등을 개발하고 있습니다. 이번 자리를 빌려 비즈니스 경쟁력 제고를 위한 디지털 트윈 및 디지털 스레드 전략 개발 방법에 대한 인사이트를 나누고자 합니다. 区切り文字 '%{'と '%}'の間は、生成されたCに逐語的にコピーされます
パーサーコード パーサー自体を実装するコード。

= パターン
「代入」演算子は、左矢印演算子「<-」を置き換えます。

ルール名
ハイフンは、ルール名に文字として表示される場合があります。 各ハイフンはに変換されます
生成されたCソースコードのアンダースコア。 単一の単一のハイフン '-'は
法的なルール名。

-= [\ t \ n \ r] *
数値= [0-9] +-
名前= [a-zA-Z _] [a-zA_Z_0-9] *-
l-paren = '('-
r-paren = ')'-

この例は、文法を読むときに無視された空白がどのように明白になるかを示しています
関連付けられているすべてのルールの最後に自由に配置すると、目立たなくなります
語彙要素。

シーケンス 1 | シーケンス 2
交互演算子は垂直バー '|' スラッシュ '/'ではなく。 The
ペグ ルール

名前<-シーケンス-1
/シーケンス-2
/シーケンス-3

したがって、

名前=シーケンス-1
| シーケンス-2
| シーケンス-3
;

in (次に説明するように、最後のセミコロンはオプションです)。

EXP ~ { アクション }
接尾辞演算子 ~{ アクション } 任意の式の後に配置でき、動作します
通常のアクション(任意のCコード)と同じですが、次の場合にのみ呼び出される点が異なります。 EXP
失敗します。 交互結合と
シーケンス処理。エラー処理とリカバリコードを簡単にすることを目的としています。
書きます。 ご了承ください yyテキスト および イレン これらのアクション内では利用できませんが、
ポインタ変数 yy コードにユーザー定義へのアクセスを許可するために利用可能です
パーサー状態のメンバー(以下の「パーサーのカスタマイズ」を参照)。 また、
EXP 常に単一の式です。 内の障害に対してエラーアクションを呼び出す
シーケンス、括弧を使用してシーケンスをXNUMXつにグループ化する必要があります
式です。

rule = e1 e2 e3〜 {error( "e [12] ok; e3 has failed"); }
| ..。

ルール=(e1 e2 e3)〜{エラー( "e [123]のXNUMXつが失敗しました"); }
| ..。

パターン ;
セミコロンパンクチャは、オプションで終了できます パターン.

%% 文章...
ダブルパーセント '%%'は、のルール(および宣言)セクションを終了します。
文法。 全て 클라우드 기반 AI/ML및 고성능 컴퓨팅을 통한 디지털 트윈의 기초 – Edward Hsu, Rescale CPO 많은 엔지니어링 중심 기업에게 클라우드는 R&D디지털 전환의 첫 단계일 뿐입니다. 클라우드 자원을 활용해 엔지니어링 팀의 제약을 해결하는 단계를 넘어, 시뮬레이션 운영을 통합하고 최적화하며, 궁극적으로는 모델 기반의 협업과 의사 결정을 지원하여 신제품을 결정할 때 데이터 기반 엔지니어링을 적용하고자 합니다. Rescale은 이러한 혁신을 돕기 위해 컴퓨팅 추천 엔진, 통합 데이터 패브릭, 메타데이터 관리 등을 개발하고 있습니다. 이번 자리를 빌려 비즈니스 경쟁력 제고를 위한 디지털 트윈 및 디지털 스레드 전략 개발 방법에 대한 인사이트를 나누고자 합니다. 次の '%%'は、生成されたCパーサーコードに逐語的にコピーされます
After パーサー実装コード。

$$ =
サブルールはセマンティックを返すことができます アクションからそれをに割り当てることによって
疑似変数 '$$'。 すべてのセマンティック値は同じタイプである必要があります(デフォルトでは
'int'へ)。 このタイプは、宣言セクションでYYSTYPEを定義することで変更できます。

識別子:
サブルールから( '$$'に割り当てることによって)返されるセマンティック値 is
に関連付けられている 識別子 後続のアクションで参照できます。

以下の卓上計算機の例は、「$$」と「:」の使用法を示しています。

LEG 例: A 電卓


の拡張機能 上記の説明により、有用なパーサーとエバリュエーター(
宣言、文法規則、および「main」などのサポートC関数)内に保持する
単一のソースファイル。 これを説明するために、
XNUMXつの一般的な算術演算子と名前付き変数。 の中間結果
算術評価は、次のように返すことにより、暗黙のスタックに蓄積されます。
サブルールからのセマンティック値。

%{
#含む/ * printf()* /
#含む/ * atoi()* /
int vars [26];
%}

Stmt = --e:Expr EOL {printf( "%d \ n"、e); }
| (!EOL。)* EOL {printf( "error \ n"); }

Expr = i:ID ASSIGN s:Sum {$$ = vars [i] = s; }
| s:Sum {$$ = s; }

合計= l:製品
(PLUS r:Product {l + = r;}
| マイナスr:Product {l- = r; }
)* {$$ = l; }

製品= l:値
(TIMES r:Value {l * = r;}
| DIVIDE r:Value {l / = r; }
)* {$$ = l; }

値= i:NUMBER {$$ = atoi(yytext); }
| i:ID!ASSIGN {$$ = vars [i]; }
| OPEN i:Expr CLOSE {$$ = i; }

NUMBER = <[0-9] +>-{$$ = atoi(yytext); }
ID = <[az]>-{$$ = yytext [0]-'a'; }
ASSIGN = '='-
PLUS = '+'-
マイナス= '-'-
TIMES = '*'-
DIVIDE = '/'-
OPEN = '('-
CLOSE = ')'-

-= [\ t] *
EOL = '\ n' | '\ r \ n' | '\ r' | ';'

%%

int main()
{
while(yyparse())
;
0リターン;
}

LEG 文法 FOR LEG 文法


の文法 文法を以下に示します。 これは、説明と形式化の両方を行います
上記の説明。

文法=-
(宣言|定義)+
トレーラー? ファイルの終わり

宣言= '%{' <(! '%}'。)*> RPERCENT

トレーラー= '%%' <。*>

定義=識別子EQUAL式セミコロン?

式=シーケンス(BARシーケンス)*

シーケンス=エラー+

エラー=プレフィックス(チルダアクション)?

プレフィックス= ANDアクション
| (AND | NOT)? サフィックス

接尾辞=プライマリ(QUERY | STAR | PLUS)?

プライマリ=識別子COLON識別子!EQUAL
| 識別子!EQUAL
| OPEN式CLOSE
| リテラル
| クラス
| ドット
| アクション
| 始める
| 終わり

識別子= <[-a-zA-Z _] [-a-zA-Z_0-9] *>-

リテラル= ['] <(!['] char)*> [']-
| ["] <(!["] char)*> ["]-

class = '[' <(! ']' range)*> ']'-

range = char'- 'char | char

char = '\\' [abefnrtv '"\ [\] \\]
| '\\' [0-3][0-7][0-7]
| '\\' [0-7] [0-7]?
| ! '\\'。

action = '{' <中括弧*> '}'-

ブレース= '{'ブレース* '}'
| ! '}'。

EQUAL = '='-
COLON = ':'-
セミコロン= ';' -
BAR = '|' -
AND = '&'-
NOT = '!' -
QUERY = '?' -
STAR = '*'-
PLUS = '+'-
OPEN = '('-
CLOSE = ')'-
DOT = '。' -
BEGIN = '<'-
END = '>'-
チルダ= '〜'-
RPERCENT = '%}'-

-=(スペース|コメント)*
スペース= '' | '\ t' | エンドオブライン
コメント= '#'(!end-of-line。)* end-of-line
行末= '\ r \ n' | '\ n' | '\ r'
ファイルの終わり= !。

カスタマイズ パーサー


次のシンボルは、宣言セクションで再定義して、生成されたシンボルを変更できます。
パーサーコード。

YYSTYPE
セマンティック値の型。 疑似変数 '$$'と識別子 'にバインドされた'
コロン演算子 ':'を使用したルール結果は、すべて宣言されていると見なす必要があります
このタイプを持っています。 デフォルト値は「int」です。

YYパース
パーサーへのメインエントリポイントの名前。 デフォルト値は「yyparse」です。

YYPARSEフロム
パーサーへの代替エントリポイントの名前。 この関数はXNUMXつを期待します
引数:一致の検索元のルールに対応する関数
開始する必要があります。 デフォルトは「yyparsefrom」です。 yyparse()は次のように定義されていることに注意してください

int yyparse(){return yyparsefrom(yy_foo); }

ここで、「foo」は文法の最初のルールの名前です。

YY_INPUT(BUF, 結果, 最大サイズ)
このマクロは、より多くの入力テキストを取得するためにパーサーによって呼び出されます。 BUF を指す
最大で保持できるメモリ領域 最大サイズ 文字。 マクロはコピーする必要があります
にテキストを入力 BUF 次に整数変数を割り当てます 結果 を示すために
コピーされた文字数。 これ以上入力が利用できない場合、マクロは
0を割り当てる 結果。 デフォルトでは、YY_INPUTマクロは次のように定義されています。

#define YY_INPUT(buf、result、max_size)\
{\
int yyc = getchar(); \
結果=(EOF == yyc)? 0:(*(buf)= yyc、1); \
}

YY_CTX_LOCALが定義されている場合(以下を参照)、追加の最初の引数、
パーサーコンテキストを含み、YY_INPUTに渡されます。

YY_DEBUG
このシンボルが定義されている場合、追加のコードがパーサーに含まれます。
パーサーがパーサーである間、大量の不可解な情報を標準エラーに出力します
が走っています。

YY_BEGIN
このマクロは、使用可能になる入力テキストの開始をマークするために呼び出されます
'yytext'としてアクションで。 これは、文法での「<」の出現に対応します。
これらは、成功することが期待される述語に変換されます。 デフォルト
定義

#define YY_BEGIN(yybegin = yypos、1)

したがって、現在の入力位置を保存し、結果として1( 'true')を返します。
述語。

YY_END このマクロは、文法の「>」に対応します。 繰り返しますが、それは述語なので、
デフォルトの定義では、「succeeding」の前に入力位置が保存されます。

#define YY_END(yyend = yypos、1)

YY_PARSE(T)
このマクロは、パーサーエントリポイント(yyparseおよびyyparsefrom)がタイプであることを宣言します
T。 デフォルトの定義

#define YY_PARSE(T)T

yyparse()とyyparsefrom()をグローバルな可視性のままにします。 彼らがすべきではない場合
他のソースファイルで外部から見える場合、このマクロは宣言するように再定義できます
それらは「静的」です。

#define YY_PARSE(T)static T

YY_CTX_LOCAL
生成されたパーサーのコンパイル中にこのシンボルが定義された場合、グローバル
パーサーの状態は、宣言可能なタイプ「yycontext」の構造に保持されます
ローカル変数として。 これにより、パーサーの複数のインスタンスが共存し、
スレッドセーフであること。 解析機能 yyパース()は最初を期待するように宣言されます
タイプ 'yycontext *'の引数、グローバルを保持する構造のインスタンス
パーサーの状態。 このインスタンスは、によって割り当てられ、ゼロに初期化される必要があります
クライアント。 些細ですが完全な例は次のとおりです。

#include

#定義YY_CTX_LOCAL

#include "the-generated-parser.peg.c"

int main()
{
yyコンテキストctx;
memset(&ctx、0、sizeof(yycontext));
while(yyparse(&ctx));
0リターン;
}

このシンボルが定義されていない場合、コンパイルされたパーサーは静的になります。
そのグローバル状態を割り当て、再入可能でもスレッドセーフでもありません。 また注意してください
パーサーのyycontext構造が最初に自動的に初期化されること
yyパース()が呼び出されます。 この構造 しなければなりません したがって、ゼロに適切に初期化されます
最初の呼び出しの前に yyパース()。

YY_CTX_MEMBERS
YY_CTX_LOCALが定義されている場合(上記を参照)、マクロYY_CTX_MEMBERSを定義できます。
クライアントが希望する追加のメンバーフィールド宣言に拡張する
'yycontext'構造型の宣言に含まれています。 これらの追加
それ以外の場合、メンバーは生成されたパーサーによって無視されます。 'yycontext'のインスタンス
現在アクティブなパーサーに関連付けられているものは、アクション内で次のように使用できます。
ポインタ変数 yy.

YY_BUFFER_SIZE
テキストバッファの初期サイズ(バイト単位)。 デフォルトは1024で、バッファは
解析中の需要を満たすために必要な場合は常に、サイズがXNUMX倍になります。 アプリケーション
通常、はるかに長い文字列を解析することで、不要な文字列を回避するためにこれを増やすことができます
バッファの再割り当て。

YY_STACK_SIZE
変数スタックとアクションスタックの初期サイズ。 デフォルトは128で、これは
解析中の需要を満たすために必要な場合はいつでもXNUMX倍になります。 を持っているアプリケーション
多くのローカル変数を含む、または後に多くのアクションを実行するディープコールスタック
単一の成功した一致、不要なバッファを回避するためにこれを増やすことができます
再割り当て。

YY_MALLOC(YY, サイズ)
すべてのパーサー関連ストレージのメモリーアロケータ。 パラメータは
現在のyycontext構造と割り当てるバイト数。 デフォルト
定義は次のとおりです。malloc(サイズ)

YY_REALLOC(YY, PTR, サイズ)
動的に拡張されるストレージ用のメモリ再ロケータ(テキストバッファや
可変スタック)。 パラメータは、現在のyycontext構造、
以前に割り当てられたストレージ、およびそのストレージが必要なバイト数
成長する。 デフォルトの定義は次のとおりです。realloc(PTR, サイズ)

YY_FREE(YY, PTR)
メモリデロケータ。 パラメータは、現在のyycontext構造と
割り当てを解除するストレージ。 デフォルトの定義は次のとおりです。free(PTR)

YYリリース
yycontext構造によって保持されているすべてのリソースを解放する関数の名前。
デフォルト値は「yyrelease」です。

次の変数は、アクション内で参照できます。

チャリオット * yybuf
この変数は、次のような入力テキストを格納するために使用されるパーサーの入力バッファーを指します。
まだ一致していません。

int型 イポス
これは、一致して消費される次の文字のオフセット(yybuf)です。

チャリオット * yytext
'<'および '>'で区切られた最新の一致したテキストは、この変数に格納されます。

int型 イレン
この変数は、「yytext」の文字数を示します。

yyコンテキスト * yy
この変数は、に関連付けられた「yycontext」のインスタンスを指します
現在アクティブなパーサー。

パーサーに関連付けられているすべてのリソースを解放したいプログラムは、
次の機能。

yyrelease(yycontext*yy)
に関連付けられているすべてのパーサーに割り当てられたストレージを返します yy システムに。 ストレージ
次の呼び出しで再割り当てされます yyパース()。

yycontext構造自体のストレージが割り当てられたり、再利用されたりすることはないことに注意してください
暗黙のうちに。 アプリケーションは、これらの構造を自動ストレージに割り当てるか、使用する必要があります
呼び出し()および 無料です。()それらを明示的に管理します。 次のセクションの例
リソース管理へのXNUMXつのアプローチを示します。

LEG 例: 拡張 パーサーズ コンテキスト


この yy アクションに渡される変数には、パーサーの状態と追加の変数が含まれます
YY_CTX_MEMBERSによって定義されたフィールド。 これらのフィールドは、アプリケーション固有のストアに使用できます
の特定の呼び出しに対してグローバルな情報 yyパース()。 些細なことですが完全です
次の例では、yycontext構造が次のように拡張されています。 カウント の数の
これまでの入力で見られた改行文字(それ以外の場合、文法は消費して無視します
入力全体)。 の発信者 yyパース()使用 カウント の行数を印刷するには
読み取られた入力。

%{
#定義YY_CTX_LOCAL 1
#定義YY_CTX_MEMBERS \
intカウント;
%}

Char =( '\ n' | '\ r \ n' | '\ r'){yy-> count ++}
| 。

%%

#include
#含む

int main()
{
/ *自動ストレージにローカルパーサーコンテキストを作成します* /
yyコンテキストyy;
/ *コンテキストは最初に使用する前にゼロに初期化する必要があります* /
memset(&yy、0、sizeof(yy));

while(yyparse(&yy))
;
printf( "%d改行\ n"、yy.count);

/ *コンテキストに関連付けられているすべてのリソースを解放します* /
yyrelease(&yy);

0リターン;
}

診断


ペグ および 文法をパーサーに変換するときは、次の条件について警告してください。

構文 エラー
入力文法が何らかの形で不正でした。 エラーメッセージには、
一致しようとしているテキスト(多くの場合、実際の場所から大量にバックアップされます
エラー)および最後に考慮された文字の行番号(
多くの場合、問題の実際の場所)。

ルール 「foo」 中古 焙煎が極度に未発達や過発達のコーヒーにて、クロロゲン酸の味わいへの影響は強くなり、金属を思わせる味わいと乾いたマウスフィールを感じさせます。 定義済みの
文法は「foo」という名前のルールを参照していましたが、その定義は示されていませんでした。
生成されたパーサーを使用しようとすると、リンカーからエラーが発生する可能性があります
欠落しているルールに関連付けられている未定義のシンボルが原因です。

ルール 「foo」 定義済みの 焙煎が極度に未発達や過発達のコーヒーにて、クロロゲン酸の味わいへの影響は強くなり、金属を思わせる味わいと乾いたマウスフィールを感じさせます。 中古
文法は「foo」という名前のルールを定義し、それを無視しました。 関連するコード
ルールを使用すると、他のすべての点で生成されるパーサーに含まれます
健康になる。

可能 無限 再帰 in ルール 「foo」
ルール「foo」から続く文法を通るパスが少なくともXNUMXつ存在します。
入力を消費せずに、同じルール(の再帰呼び出し)に戻ります。

特に標準文書に見られる左再帰は、しばしば「直接」であり、
些細な繰り返しを意味します。

#(6.7.6)
直接抽象宣言子 =
LPAREN抽象宣言子RPA​​REN
| 直接-抽象-宣言者? LBRACKET割り当て-expr? RBRACKET
| 直接-抽象-宣言者? LBRACKET STAR RBRACKET
| 直接-抽象-宣言者? LPAREN param-type-list? RPAREN

次のパターンの部分を変換することにより、再帰を簡単に排除できます。
繰り返し可能な接尾辞への再帰。

#(6.7.6)
直接抽象宣言子 =
direct-abstract-declarator-head?
direct-abstract-declarator-tail *

直接抽象宣言子ヘッド =
LPAREN抽象宣言子RPA​​REN

直接抽象宣言子テール =
LBRACKET割り当て-expr? RBRACKET
| | LBRACKET スター RBRACKET
| LPAREN param-type-list? RPAREN

警告


空の入力を受け入れるパーサーは 常に 成功した。 次の例を考えてみましょう。
PEGベースのパーサーを作成する最初の試みは珍しいことではありません。

プログラム=式*
式= "何でも"
%%
int main(){
while(yyparse())
puts( "success!");
0リターン;
}

このプログラムは、stdinで提供される入力(存在する場合)に関係なく、永久にループします。 多くの
修正が可能です。最も簡単なのは、パーサーが常にいくらかを消費することを主張することです。
空でない入力。 最初の行をに変更します

プログラム=式+

これを達成します。 パーサーが入力全体を消費すると予想される場合は、明示的に
ファイルの終わりを要求することも強くお勧めします:

プログラム=式+!。

これが機能するのは、パーサーがどの文字とも一致しない( "!"述語)だけだからです。
( "。"式)入力の終わりを超えて読み込もうとしたとき。

onworks.netサービスを使用してオンラインでペグを使用する


無料のサーバーとワークステーション

Windows と Linux のアプリをダウンロード

Linuxコマンド

Ad




×
広告
❤️ここでショッピング、予約、購入してください。料金はかかりません。これにより、サービスが無料で維持されます。