标签: grammar

学习树顶

我正在尝试自学Ruby的Treetop语法生成器.我发现,不仅文档中的"最佳"文档非常稀疏,而且它似乎并不像我希望的那样直观.

在高层次上,我真的很喜欢比现场文档或视频更好的教程,如果有的话.

在较低的层次上,这是一个我根本无法工作的语法:

grammar SimpleTest

  rule num
    (float / integer)
  end

  rule float
   (
    (( '+' / '-')? plain_digits '.' plain_digits) /
    (( '+' / '-')? plain_digits ('E' / 'e') plain_digits ) /
    (( '+' / '-')? plain_digits '.') / 
    (( '+' / '-')? '.' plain_digits) 
   ) {
      def eval
        text_value.to_f
      end
   }
  end

  rule integer
    (( '+' / '-' )? plain_digits) {
      def eval
        text_value.to_i
      end
    }
  end

  rule plain_digits
    [0-9] [0-9]*      
  end

end
Run Code Online (Sandbox Code Playgroud)

当我加载它并在一个非常简单的测试对象中运行一些断言时,我发现:

assert_equal @parser.parse('3.14').eval,3.14
Run Code Online (Sandbox Code Playgroud)

工作正常,而

assert_equal …
Run Code Online (Sandbox Code Playgroud)

ruby grammar parsing treetop

18
推荐指数
2
解决办法
1万
查看次数

高效的无上下文语法解析器,最好是Python友好的

我需要为我的一个项目解析一小部分英语,描述为具有(1级)特征结构的无上下文语法(示例),我需要有效地完成它.

现在我正在使用NLTK的解析器,它产生正确的输出,但速度非常慢.对于我的约450个相当模糊的非词典规则和50万个词条的语法,解析简单的句子可能需要2到30秒,这取决于所得到的树的数量.词条对性能几乎没有影响.

另一个问题是在开始时加载(25MB)语法+词典可能需要一分钟.

从我在文献中可以找到的,用于解析这种语法(Earley或CKY)的算法的运行时间应该与语法的大小呈线性关系,并且应该与输入令牌列表的大小相关.我对NLTK的体验表明,歧义是最能伤害表现的,而不是语法的绝对大小.

所以现在我正在寻找一个CFG解析器来取代NLTK.我一直在考虑PLY,但我不知道它是否支持CFG中的特征结构,这在我的情况下是必需的,我看到的例子似乎是在进行大量的过程解析,而不仅仅是指定语法.有人能告诉我一个PLY的例子,它既支持功能结构又使用声明性语法?

对于能够有效地完成我需要的任何其他解析器,我也没问题.Python接口是首选,但不是绝对必要的.

python grammar parsing nlp nltk

18
推荐指数
2
解决办法
2万
查看次数

我在哪里可以找到Perl编程语言的正式语法?

我理解Perl语法是模糊的,它的消歧是非平凡的(有时涉及在编译阶段执行代码).无论如何,Perl是否具有正式语法(尽管模棱两可和/或上下文敏感)?

perl grammar parsing

18
推荐指数
3
解决办法
5272
查看次数

Haskell Precedence:Lambda和运算符

我发现优先级和关联性是一个很大的障碍,让我理解语法乍看之下对haskell代码的表达.

例如,

blockyPlain :: Monad m => m t -> m t1 -> m (t, t1)
blockyPlain xs ys = xs >>= \x -> ys >>= \y -> return (x, y)
Run Code Online (Sandbox Code Playgroud)

通过实验,我终于明白了,

blockyPlain xs ys = xs >>= (\x -> (ys >>= (\y -> return (x, y))))
Run Code Online (Sandbox Code Playgroud)

代替

blockyPlain xs ys = xs >>= (\x -> ys) >>= (\y -> return (x, y))
Run Code Online (Sandbox Code Playgroud)

其作用如下:

*Main> blockyPlain [1,2,3] [4,5,6]
[(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)]
Run Code Online (Sandbox Code Playgroud)

我可以从ghci获取信息(>> =)作为运算符,(infixl 1 >> =).

但是没有信息 - >因为它不是运营商.

你们中的某些人可以提供一些参考来使这个语法更容易掌握吗?

grammar haskell operator-precedence

18
推荐指数
2
解决办法
1359
查看次数

为什么LL语法不能左递归?

龙书中,LL语法定义如下:

语法是LL,当且仅当适用于任何生产时A -> a|b,以下两个条件适用.

  1. FIRST(a)并且FIRST(b)是不相交的.这意味着它们不能同时衍生出来EMPTY

  2. 如果b能够获得EMPTY,则a不能推导开头的任何字符串FOLLOW(A),就是FIRST(a)FOLLOW(A)必须是不相交的.

我知道LL语法不能保持递归,但正式的原因是什么?我猜左递归语法会违反规则2,对吧?例如,我写了以下语法:

S->SA|empty
A->a
Run Code Online (Sandbox Code Playgroud)

由于FIRST(SA) = {a, empty}FOLLOW(S) ={$, a},然后FIRST(SA)FOLLOW(S)不脱节,所以这个语法不是LL.但我不知道这是左递归FIRST(SA)FOLLOW(S)不是不相交,还是有其他原因?换句话说,每个左递归语法都会产生违反LL语法条件2的情况吗?

grammar ll-grammar left-recursion

18
推荐指数
3
解决办法
9681
查看次数

ANTLR:如何解释识别Java代码后缀的语法行为?

一周前,我开始了以下项目:一种识别Java代码后缀的语法.

我使用ANTLRJava(Java.g4)的官方语法作为基线并开始添加一些规则.但是,这些新规则还引入了左递归,我也不得不处理.

经过几天的工作,我得到了以下代码.当我开始测试时,我注意到一些不寻常的东西,我仍然无法解释.当给出输入时{ },解析器告诉我no viable alternative at input '<EOF>',但当我在规则的右侧切换终端的顺序时s2,特别是如果我们将右手侧v2_1 | v2_2 | v2_3 ...改为v2_36 | v2_1 | v2_2 ...(终端v2_36移动到第一个位置),顺序{ }被接受.

我的第一个想法是Antlr没有回溯,因为我注意到在输入{ }时,解析器的第一个版本开始遵循规则v2_3,只是报告没有找到任何东西,并且没有尝试考虑其他选项(这是我的想法,但也许不是真的)这样的确v2_36给出了肯定的答案.

但是,经过一些研究,我发现ANTLR实际上是回溯,但只有在其他一切都失败的情况下.至少对于v3.3来说也是如此(在官方ANTLR文件中阅读),但我想这也是如此v4.现在我有点困惑.在这个项目上花了这么多个小时后,如果我不能让它工作,我会觉得非常糟糕.有人可以提供某种提示吗?非常感谢,谢谢.

编辑

管理将问题隔离到

grammar Java;
@parser::members {String ruleName; }

start : compilationUnitSuf EOF;

compilationUnitSuf
    :   {ruleName = "typeDeclarationSuf"; } s2
    ;

s2: '{' '}' …
Run Code Online (Sandbox Code Playgroud)

java grammar antlr

18
推荐指数
1
解决办法
836
查看次数

编程语言语法中尾随逗号的历史

许多编程语言允许在列表中的最后一项之后的语法中使用尾随逗号.据说这是为了简化自动代码生成,这是可以理解的.

例如,以下是Java中完全合法的数组初始化(JLS 10.6数组初始化器):

int[] a = { 1, 2, 3, };
Run Code Online (Sandbox Code Playgroud)

我很好奇是否有人知道哪种语言首先允许使用这些尾随逗号.显然C 早在1985年便有它.

此外,如果有人知道现代编程语言的其他语法"特性",我也会非常有兴趣听到这些语言.我读到例如Perl和Python在语法的其他部分允许使用尾随逗号更加自由.

language-agnostic syntax grammar language-design

17
推荐指数
1
解决办法
5354
查看次数

PHP的EBNF语法定义?

我想知道是否有人在某处为PHP编译了EBNF.我找到了这个网站这个网站.但两者似乎都不完整.这个问题非常相似,但已经有一年了.我想知道是否取得了任何进展.

php grammar ebnf

17
推荐指数
2
解决办法
8599
查看次数

如果R中的语句只能有一行?

我用if语句尝试了一个很小的代码,尽管它非常简单,但我真的很困惑的是代码

n<-857
while(n!=1){
if(n<=0)
 print("please input a positive integer")
else if(n%%2==0)
 n<-n/2
 print(n)
else
 n<-3*n+1
 print(n)
  }
Run Code Online (Sandbox Code Playgroud)

正如我们在上面看到的,当在R中运行此代码时,会出现错误,但是如果我更改if语句就像这样

if(n<=0)
     print("please input a positive integer")
    else if(n%%2==0)
     n<-n/2
    else
     n<-3*n+1
Run Code Online (Sandbox Code Playgroud)

没关系,我的问题是我们每次判断只能写一行吗?如果我想在每个评判后做更多的事情,我该怎么做,就像这个案例一样,我想改变n的值,但也想要显示它,我该怎么办?非常感谢你

grammar if-statement r

17
推荐指数
3
解决办法
4万
查看次数

如何从正式语法生成句子?

从语法中生成句子的常用方法是什么?

我想要一种与解析器相反的算法.也就是说,给定一个正式的无上下文语法(比如LL),我想生成一个符合该语法的任意句子.我在这里使用句子来表示任何有效的文本体,因此它实际上可以是一个完整的程序(即使它没有任何意义 - 只要它的语法正确).

示例语法:

program   : <imports> NEWLINE? <namespace>
imports   : ("import" <identifier> NEWLINE)* 
namespace : "namespace " <identifier> NEWLINE "{" <classes> "}" 
identifier: (A-Za-z_) (A-Za-z0-9_)*
...
Run Code Online (Sandbox Code Playgroud)

生成的程序示例:

import jkhbhhuob
import aaaaa888_

namespace u8nFGubgykb
{ class ui0op_np { ... }
}
Run Code Online (Sandbox Code Playgroud)

compiler-construction grammar parsing computer-science

16
推荐指数
2
解决办法
6778
查看次数