shift/reduce conflict尝试使用bison为DirectX格式的子集生成语法
我试图为bison中的x格式(实际上是blender python脚本导出的子集的子集)提供语法。但是我得到了一个shift-reduce冲突,bison不会告诉我在哪里,或者“某种程度上”告诉我在哪里,这取决于我的尝试 首先,这里是blender中的一个示例.x文件,我正在测试它:shift/reduce conflict尝试使用bison为DirectX格式的子集生成语法,bison,yacc,context-free-grammar,flex-lexer,Bison,Yacc,Context Free Grammar,Flex Lexer,我试图为bison中的x格式(实际上是blender python脚本导出的子集的子集)提供语法。但是我得到了一个shift-reduce冲突,bison不会告诉我在哪里,或者“某种程度上”告诉我在哪里,这取决于我的尝试 首先,这里是blender中的一个示例.x文件,我正在测试它: xof 0303txt 0032 Frame Root { FrameTransformMatrix { 1.000000, 0.000000, 0.000000, 0.000000, 0
xof 0303txt 0032
Frame Root {
FrameTransformMatrix {
1.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 1.000000, 0.000000,
0.000000, 1.000000,-0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 1.000000;;
}
Frame Cube {
FrameTransformMatrix {
1.000000, 0.000000, 0.000000, 0.000000,
0.000000, 1.000000, 0.000000, 0.000000,
0.000000, 0.000000, 1.000000, 0.000000,
0.000000, 0.000000, 0.000000, 1.000000;;
}
Mesh { //Cube_002 Mesh
36;
-1.000000;-1.000000;-1.000000;,
1.000000;-1.000000;-1.000000;,
1.000000; 1.000000;-1.000000;,
0.999999;-1.000001; 1.000000;,
-1.000000; 1.000000; 1.000000;,
1.000000; 0.999999; 1.000000;,
1.000000;-1.000000;-1.000000;,
1.000000; 0.999999; 1.000000;,
1.000000; 1.000000;-1.000000;,
-1.000000;-1.000000;-1.000000;,
0.999999;-1.000001; 1.000000;,
1.000000;-1.000000;-1.000000;,
-1.000000; 1.000000; 1.000000;,
-1.000000;-1.000000; 1.000000;,
-1.000000;-1.000000;-1.000000;,
-1.000000; 1.000000;-1.000000;,
1.000000; 1.000000;-1.000000;,
1.000000; 0.999999; 1.000000;,
-1.000000;-1.000000;-1.000000;,
1.000000; 1.000000;-1.000000;,
-1.000000; 1.000000;-1.000000;,
0.999999;-1.000001; 1.000000;,
-1.000000;-1.000000; 1.000000;,
-1.000000; 1.000000; 1.000000;,
1.000000;-1.000000;-1.000000;,
0.999999;-1.000001; 1.000000;,
1.000000; 0.999999; 1.000000;,
-1.000000;-1.000000;-1.000000;,
-1.000000;-1.000000; 1.000000;,
0.999999;-1.000001; 1.000000;,
-1.000000; 1.000000; 1.000000;,
-1.000000;-1.000000;-1.000000;,
-1.000000; 1.000000;-1.000000;,
-1.000000; 1.000000;-1.000000;,
1.000000; 0.999999; 1.000000;,
-1.000000; 1.000000; 1.000000;;
12;
3;0;1;2;,
3;3;4;5;,
3;6;7;8;,
3;9;10;11;,
3;12;13;14;,
3;15;16;17;,
3;18;19;20;,
3;21;22;23;,
3;24;25;26;,
3;27;28;29;,
3;30;31;32;,
3;33;34;35;;
MeshNormals { //Cube_002 Normals
36;
0.000000; 0.000000;-1.000000;,
0.000000; 0.000000;-1.000000;,
0.000000; 0.000000;-1.000000;,
-0.000000;-0.000000; 1.000000;,
-0.000000;-0.000000; 1.000000;,
-0.000000;-0.000000; 1.000000;,
1.000000; 0.000000;-0.000000;,
1.000000; 0.000000;-0.000000;,
1.000000; 0.000000;-0.000000;,
-0.000000;-1.000000;-0.000000;,
-0.000000;-1.000000;-0.000000;,
-0.000000;-1.000000;-0.000000;,
-1.000000; 0.000000;-0.000000;,
-1.000000; 0.000000;-0.000000;,
-1.000000; 0.000000;-0.000000;,
0.000000; 1.000000; 0.000000;,
0.000000; 1.000000; 0.000000;,
0.000000; 1.000000; 0.000000;,
0.000000; 0.000000;-1.000000;,
0.000000; 0.000000;-1.000000;,
0.000000; 0.000000;-1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
1.000000;-0.000001; 0.000000;,
1.000000;-0.000001; 0.000000;,
1.000000;-0.000001; 0.000000;,
-0.000000;-1.000000; 0.000000;,
-0.000000;-1.000000; 0.000000;,
-0.000000;-1.000000; 0.000000;,
-1.000000; 0.000000;-0.000000;,
-1.000000; 0.000000;-0.000000;,
-1.000000; 0.000000;-0.000000;,
0.000000; 1.000000; 0.000000;,
0.000000; 1.000000; 0.000000;,
0.000000; 1.000000; 0.000000;;
12;
3;0;1;2;,
3;3;4;5;,
3;6;7;8;,
3;9;10;11;,
3;12;13;14;,
3;15;16;17;,
3;18;19;20;,
3;21;22;23;,
3;24;25;26;,
3;27;28;29;,
3;30;31;32;,
3;33;34;35;;
} //End of Cube_002 Normals
MeshMaterialList { //Cube_002 Material List
1;
12;
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0;;
Material Material {
0.640000; 0.640000; 0.640000; 1.000000;;
96.078431;
0.500000; 0.500000; 0.500000;;
0.000000; 0.000000; 0.000000;;
}
} //End of Cube_002 Material List
} //End of Cube_002 Mesh
} //End of Cube
} //End of Root Frame
这里有两次尝试捕捉语法:
通过这个,我得到:。/XGrammar.y:冲突:1移位/减少
//----------------------------------------------------
Start
: KEYWORD ID '{' EntityDeclaration '}' END
;
//----------------------------------------------------
EntityDeclaration
: KEYWORD ID '{'AttributeDeclaration'}' EntityDeclaration
| KEYWORD ID '{'AttributeDeclaration'}'
;
//----------------------------------------------------
AttributeDeclaration
: KEYWORD '{' Statement AttributeDeclaration '}' AttributeDeclaration
| KEYWORD '{' Statement '}' AttributeDeclaration
| KEYWORD '{' Statement AttributeDeclaration '}'
| KEYWORD '{' Statement '}'
;
//----------------------------------------------------
Statement
: ExpressionList ';'
| ExpressionList ';' Statement
;
//----------------------------------------------------
ExpressionList
: Expression
| Expression ',' ExpressionList
;
//----------------------------------------------------
Expression
: INTEGER
| REAL
| VecFType
;
//----------------------------------------------------
VecFType
: Vec3FType
| Vec4FType
;
//----------------------------------------------------
Vec3FType
: REAL ';' REAL ';' REAL ';'
;
//----------------------------------------------------
Vec4FType
: REAL ';' REAL ';' REAL ';' REAL ';'
;
接下来,我得到:
../XGrammar.y: conflicts: 1 shift/reduce, 2 reduce/reduce
../XGrammar.y:56.3-9: warning: rule never reduced because of conflicts: Expression: Element
//----------------------------------------------------
Start
: KEYWORD ID '{' EntityDeclaration '}' END
;
//----------------------------------------------------
EntityDeclaration
: KEYWORD ID '{'AttributeDeclaration'}' EntityDeclaration
| KEYWORD ID '{'AttributeDeclaration'}'
;
//----------------------------------------------------
AttributeDeclaration
: KEYWORD '{' Statement AttributeDeclaration '}' AttributeDeclaration
| KEYWORD '{' Statement '}' AttributeDeclaration
| KEYWORD '{' Statement AttributeDeclaration '}'
| KEYWORD '{' Statement '}'
;
//----------------------------------------------------
Statement
: Expression ';'
| Expression ';' Statement
;
//----------------------------------------------------
Expression
: Container
| Element
;
//----------------------------------------------------
Container
: VecFType
| ArrayType
;
//----------------------------------------------------
ArrayType
: ';'
| Element ArrayElement
;
//----------------------------------------------------
ArrayElement
: ArrayType
| ','Element ArrayElement
;
//----------------------------------------------------
Element
: INTEGER
| REAL
;
//----------------------------------------------------
VecFType
: ';'
| Element VecElement
;
VecElement
: VecFType
| ';'Element VecElement
;
我对语法非常生疏(从大学开始已经有一段时间了),但我怀疑这与微软决定放弃“容器”概念并将其与逗号和分号混合在一起的奇妙方式有关:
他们说,基本上,容器是一种“隐式”容器,容器的结尾用分号标记。这也恰好是它们标记数组结尾的方式,也恰好是在数组上下文中标记(显然)隐含容器的单个元素的方式…:所以整件事都是狗屎
首先,这个x格式不是LR(1)
然而,在第二次阅读微软的文档之后,我认为整个向量与数组的关系是bs。。。(我通过语法来解释这些类型之间的差异)。所以我想,我只需要为“Container”创建一个产品。大致如下:在带括号的部分中有两种类型的声明,独立的/inscope/local/whathaveyou声明和包含的声明。包含的类型与另一个类型相同,只是在末尾加了一个分号,以便“关闭”容器。但是如果你看看微软的文档,你会发现它不一定是这样的
第三种方法,我得到:
../XGrammar.y: conflicts: 4 shift/reduce, 1 reduce/reduce
../XGrammar.y:61.3-29: warning: rule never reduced because of conflicts: ContainerType: ',' Statement ContainerType
//----------------------------------------------------
Start
: KEYWORD ID '{' Entity '}' END
;
//----------------------------------------------------
Entity
: KEYWORD ID '{'Attribute'}' Entity
| KEYWORD ID '{'Attribute'}'
;
//----------------------------------------------------
Attribute
: KEYWORD '{' Statement Attribute '}' Attribute
| KEYWORD '{' Statement '}' Attribute
| KEYWORD '{' Statement Attribute '}'
| KEYWORD '{' Statement '}'
;
//----------------------------------------------------
Statement
: Declaration ';'
| Declaration ';' Statement
;
Declaration
: ElementType
| ContainerType
;
ContainerType
: Statement ',' Statement
| ',' Statement ContainerType
;
//----------------------------------------------------
ElementType
: INTEGER
| REAL
;
//----------------------------------------------------
所以我迷路了。感谢您的帮助。完全随机的方式,
这些文件中使用了code>和,
,这会导致我试图通过忽略来解析它们代码>/,
一起--类似于:
input: input item | item ;
item: NUMBER | idlist '{' input '}' ;
idlist: idlist ID | ID ;
然后根据前面的关键字将每个{}
-封闭块的内容拆分。如果它是一个WhateverMatrix,那么它应该是16个数字。网格
看起来是一个计数,后跟3*计数坐标,后跟
理解事物将完全取决于理解所有关键词的含义。根据Chris Dodd的含蓄回答,我得出结论,关键问题在于,正如前面所述,X格式无法在上下文无关的语言中捕获。这是因为分号的用法很奇怪(对不起,是任意的)(以一种非互斥的方式)
- 声明
- 在本地作用域中声明数组时结束数组
- 数组中的元素(如果元素属于隐含模板)
- 隐含模板中的任何单个元素
只是让它成为一个无法提出上下文无关的生产规则的地方
底线:从声明的角度解析所有内容,并在完成派生时根据当前标记值分配语义。
我的新“语法”是:
请注意,我仍然找到了一种方法,将逗号与一个lambda结果保持在一起,以便提出“列表”的半纵火概念(这对于我给出的被解析数据的最终语义很有用)。同时。。。我从大学时代拿出一本教科书,正在复习LL(k)/LR(k)语言和语法、左因式分解、消除左递归、最右/最左派生、自底向上解析、屎/还原等。。。非常有趣。。。我的基本疑问是,是我弄乱了派生词,还是x格式确实是一个模棱两可的语法。如果是,最快的方法是修改PythonX导出脚本以添加显式容器和数组终端符号。
//----------------------------------------------------
Start
: DeclarationList END
;
//----------------------------------------------------
DeclarationList
: Declaration DeclarationList
| Declaration
;
//----------------------------------------------------
Declaration
: Object
| Element
| ElementList
;
//----------------------------------------------------
Object
: KEYWORD ID '{' DeclarationList '}'
| KEYWORD '{' DeclarationList '}'
;
//----------------------------------------------------
ElementList
: Element ',' Element Ep
;
//----------------------------------------------------
Ep
: ',' Element Ep
|
;
//----------------------------------------------------
Element
: STRING
| INTEGER
| REAL
;