shift/reduce conflict尝试使用bison为DirectX格式的子集生成语法

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

我试图为bison中的x格式(实际上是blender python脚本导出的子集的子集)提供语法。但是我得到了一个shift-reduce冲突,bison不会告诉我在哪里,或者“某种程度上”告诉我在哪里,这取决于我的尝试

首先,这里是blender中的一个示例.x文件,我正在测试它:

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
;
//----------------------------------------------------

所以我迷路了。感谢您的帮助。

完全随机的方式,
,这会导致我试图通过忽略
来解析它们/
一起--类似于:

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
;