OK、私はこの Bison 文法を 3 回書き直そうとしましたが、shift/reduce および reduce/reduce の競合が発生し続けています。解析しようとしている構文は次のとおりです。{...} 内の項目は、どちらか一方のためのものです。[...] 内の項目はオプションです。
CONSTANT constant-name constant-class
constant-class = { EQUALS expression numeric-options }
{ EQUALS STRING string string-options }
numeric-options = [ PREFIX prefix-string ]
[ TAG tag-string ]
[ COUNTER #local-name ]
[ TYPENAME type-name ] ;
string-options = [ PREFIX prefix-string ]
[ TAG tag-string ] ;
CONSTANT (constant-name,...) EQUALS expression
[ INCREMENT expression ]
[ PREFIX prefix-string ]
[ TAG tag-string ]
[ COUNTER #local-name ]
[ TYPENAME type-name ];
CONSTANT constant-name EQUALS expression,
.
.
.
;
CONSTANT (constant-name,...) EQUALS expression,
.
.
.
;
最後の 3 つをすべて機能させるのに問題があります。それらのいずれかを機能させることはできますが、4 つすべてを機能させることはできません。現在、1 つのシフト/リデュースと 1 つのリデュース/リデュースの競合があります。私が持っている文法は次のとおりです。
constant
: SDL_K_CONSTANT constant_style ';'
;
constant_style
: constant_name constant_class
| constant_list
| constant_set
;
constant_name
: sdl_name
;
constant_class
: SDL_K_EQUALS sdl_decimal
| SDL_K_EQUALS SDL_K_STRING sdl_string
;
constant_names
: constant_name
| constant_names ',' constant_name
| '(' constant_names ')'
;
names_equal
: constant_names SDL_K_EQUALS sdl_decimal
;
constant_list
: names_equal
;
constant_set
: names_equal
| constant_set ',' names_equal
;
名前は自己文書化されていると思います(少なくともタイプを理解できるはずです)。どんな助けでも大歓迎です。単純化しすぎているか、不十分であると感じています。
注: 投稿を編集する方法を見つけて、オプションを削除し、SDL_K_COMMA と SDL_K_SEMI をそれぞれ ',' と ';' に変更しました。
ありがとう。
解析する必要があるいくつかの例を次に示します。
CONSTANT block_node_size EQUALS 24;
CONSTANT Strcon EQUALS STRING "This is a string constant" PREFIX Jg$
#block_size = 24;
CONSTANT block_node_size EQUALS #block_size;
CONSTANT
xyz EQUALS 10,
alpha EQUALS 0,
noname EQUALS 63;
CONSTANT
(zyx, nameless) EQUALS 10,
(beta) EQUALS 1,
gamma EQUALS 42;
CONSTANT (
bits,
bytes,
words,
longs,
quads,
octas
) EQUALS 0 INCREMENT 1 PREFIX ctx$;
CONSTANT
(bad_block,bad_data,,,,
overlay,rewrite) EQUALS 0 INCREMENT 4;
CONSTANT (pli,c,bliss,macro)
EQUALS 4 INCREMENT 4 PREFIX lang$
COUNTER #lang;
CONSTANT (basic,pascal,fortran)
EQUALS #lang + 4 INCREMENT 4 PREFIX lang$;
これが役立つことを願っています。
ところで:これはこれのためのEBNF(一種)です:
/*
* Define the CONSTANT construct (Left out Expression).
*/
Str ::= "\"" Printable* "\""
Name ::= "$" | "_" | [A-Za-z] ("$" | "_" | [A-Z0-9a-z])*
Names ::= Name | ("(" Name ("," Name )* ")")
Constant_class ::= "EQUALS" (Expression Numeric_options | "STRING" Str
String_options)
String_options ::= Prefix? Tag?
Numeric_options ::= String_options Counter? Typename? Radix?
Increment_options ::= Increment? Numeric_options
Constant_list ::= Names "EQUALS" Expression Increment_options
Constant_set ::= Names Equals Expression
("," Names "EQUALS" Expression)*
Constant ::= "CONSTANT" (Name Constant_class | Constant_list |
Constant_set) ";"?
Prefix ::= "PREFIX" Str
Tag ::= "TAG" Str
Radix ::= "RADIX" ("DEC" | "OCT" | "HEX")
Counter ::= "COUNTER" Variable
Increment ::= "INCREMENT" Expression
Typename ::= "TYPENAME" Name
それくらいだと思います。