语法分析和解析器

发布于 2024-11-29 23:09:44 字数 2373 浏览 5 评论 0原文

我想解析类似的内容:

path.to.variable

“path”和“to”是名为“Instance”的对象,变量引用是双精度。

我有以下语法:

expr                ::= instancePath:i INSTANCE_SEPARATOR SHORTCUT:s
                    {:
                        RESULT = getDouble(s);
                    :}
                ;



instancePath        ::= instanceSubPath:p
                    {:
                        RESULT = p;
                    :}
                ;


instanceSubPath     ::= instanceSubPath:i1 INSTANCE_SEPARATOR instanceSubPath:i2
                    {:
                        RESULT = i2;
                    :}
                | SHORTCUT:s
                    {:
                        RESULT = pushInstance(s);
                    :}
                ;

在此语法中:

  • INSTANCE_SEPARATOR 是“.”。字符。
  • SHORTCUT 是一个仅包含“path”、“to”或“variable”等字母的名称。
  • expr 必须返回通过调用函数 getDouble 获得的双精度值,该函数采用名称(此处为“变量”)。该函数使用当前选定的实例。一个实例包含一个哈希表,该哈希表包含 double 或其他实例。
  • PushInstance 是一个设置当前实例的函数,

例如我们可以有:

  • 一个实例“path”,其中包含一个哈希表,其中:“to”=>链接到实例“to”
  • 一个实例“to”,其中包含一个哈希表,该哈希表是: "variable"=>10
  • 路径 "path.to.variable" 必须返回 10。

这不会运行,因为语法抱怨空值。这是因为解析器这样做

expr(
  instancePath(
    instanceSubPath(SHORTCUT("path"))
    INSTANCE_SEPARATOR 
    instanceSubPath(SHORTCUT("to")) 
    INSTANCE_SEPARATOR 
    instanceSubPath(SHORTCUT("variable"))
  )
  INSTANCE_SEPARATOR
  !NULL!

:)

而不是这样做

expr(
 instancePath(
    instanceSubPath(SHORTCUT("path"))
    INSTANCE_SEPARATOR 
    instanceSubPath(SHORTCUT("to")) 
 )
 INSTANCE_SEPARATOR 
 SHORTCUT("variable")
)

为什么?是否存在优先级问题?

最后,如果我删除 instancePath 规则,则所有规则都会运行:

expr                ::= instanceSubPath:i INSTANCE_SEPARATOR SHORTCUT:s
                    {:
                        RESULT = getDouble(s);
                    :}
                ;


instanceSubPath     ::= instanceSubPath:i1 INSTANCE_SEPARATOR instanceSubPath:i2
                    {:
                        RESULT = i2;
                    :}
                | SHORTCUT:s
                    {:
                        RESULT = pushInstance(s);
                    :}
                ;

我无法删除这个额外的规则,因为我已经简化了示例,但实际上它要复杂得多。

我不明白为什么删除这个额外的规则可以解决我的问题......

I want to parse something like that :

path.to.variable

"path" and "to" are object named "Instance" and variable reference a double.

I've got the following grammar :

expr                ::= instancePath:i INSTANCE_SEPARATOR SHORTCUT:s
                    {:
                        RESULT = getDouble(s);
                    :}
                ;



instancePath        ::= instanceSubPath:p
                    {:
                        RESULT = p;
                    :}
                ;


instanceSubPath     ::= instanceSubPath:i1 INSTANCE_SEPARATOR instanceSubPath:i2
                    {:
                        RESULT = i2;
                    :}
                | SHORTCUT:s
                    {:
                        RESULT = pushInstance(s);
                    :}
                ;

In this grammar :

  • INSTANCE_SEPARATOR is the "." char.
  • SHORTCUT is a named with only letters like "path", "to" or "variable".
  • expr must return a double value obtained by the call of the function getDouble which takes a name (here "variable"). This function use the current selected instance. An instance contains a hashtable which contains double or other instance.
  • pushInstance is a function which set the current instance

for example we could have :

  • an instance "path" which contains a hashtable which is : "to"=>link to instance "to"
  • an instance "to" which contains a hashtable which is : "variable"=>10
  • the path "path.to.variable" must return 10.

This does not run because the grammar complains a null value. This is due to the fact the parser does this :

expr(
  instancePath(
    instanceSubPath(SHORTCUT("path"))
    INSTANCE_SEPARATOR 
    instanceSubPath(SHORTCUT("to")) 
    INSTANCE_SEPARATOR 
    instanceSubPath(SHORTCUT("variable"))
  )
  INSTANCE_SEPARATOR
  !NULL!

)

instead of doing

expr(
 instancePath(
    instanceSubPath(SHORTCUT("path"))
    INSTANCE_SEPARATOR 
    instanceSubPath(SHORTCUT("to")) 
 )
 INSTANCE_SEPARATOR 
 SHORTCUT("variable")
)

Why ? is there precedence problems ?

To finish, if I remove the instancePath rule, all runs :

expr                ::= instanceSubPath:i INSTANCE_SEPARATOR SHORTCUT:s
                    {:
                        RESULT = getDouble(s);
                    :}
                ;


instanceSubPath     ::= instanceSubPath:i1 INSTANCE_SEPARATOR instanceSubPath:i2
                    {:
                        RESULT = i2;
                    :}
                | SHORTCUT:s
                    {:
                        RESULT = pushInstance(s);
                    :}
                ;

I can't remove this extra rules because I've simplified the example but it's quite more complex in reality.

I don't understand why deleting this extra rule solve my problem...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文