レシピの材料に関連するパーサーを生成しようとしています。パーサーがトークンを処理する順序が、EBNF 文法で定義されているものに対して、jison ファイル内のトークンの行項目の順序に従っているように見えることに気付きました。
たとえば、解析すると次のように6 tablespoons unsalted butter, cut into 1-inch pieces
なります。
Error: Parse error on line 1:
6 tablespoons unsalted
--^
Expecting 'UNIT_NAME', 'NUMBER', 'SLASH', got 'WORD'
私は、文法が a を食べる前にUNIT_NAME
どれが. ここで正しい文法アプローチは何ですか? 私はインタラクティブな Jison パーサーを使用して文法の状態を検証してきましたが、これまでのところ問題はありませんでした。tablespoons
WORD
ジソン・グラマー
%lex
%options flex case-insensitive
UnitName [teaspoons|teaspoon|tablespoons|tablespoon|fluid ounces|fluid ounce|ounces|ounce|cups|cup|pints|pint|quarts|quart|gallons|gallon|pounds|pound|milliliters|milliliter|deciliters|deciliter|liters|liter]\b
Word \w+\b
NUMBER [1-9][0-9]+|[0-9]
CHAR [a-zA-Z0-9_-]
%%
\s+ /* skip whitespace */
{NUMBER} return 'NUMBER'
{UnitName} return "UNIT_NAME";
{Word} return 'WORD'
{CHAR} return 'CHAR'
"/" return "SLASH";
"-" return "HYPHEN"
"," return "COMMA";
<<EOF>> return 'EOF';
/lex
/* enable EBNF grammar syntax */
%ebnf
/* language grammar */
%start ingredient
%%
ingredient
: ingredient_format
{ return $1; }
;
ingredient_format
: unit_count UNIT_NAME ingredient_name COMMA ingredient_info EOF
{ $$ = {'count': $1, 'unit': $2, 'item': $3, info: $5}; }
| unit_count UNIT_NAME ingredient_name EOF
{ $$ = {'count': $1, 'unit': $2, 'item': $3, info: null}; }
;
unit_count
: NUMBER
{ $$ = parseInt($1); }
| NUMBER SLASH NUMBER
{ $$ = parseInt($1) / parseInt($3); }
| NUMBER NUMBER SLASH NUMBER
{ $$ = parseInt($1) + (parseInt($2) / parseInt($4)); }
;
ingredient_name
: WORD+
{ $$ = $1; }
;
ingredient_info
: ""
{ $$ = ''; }
| WORD+
{ $$ = $1; }
;
要旨
テストするテキスト文字列と単純なパーサーを使用して作成しました: https://gist.github.com/aphexddb/ddc83d57c7f1c1b96458