- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我是语法推理领域的初学者。在我的研究过程中,我发现了一个名为基于对齐学习(ABL)的实现。我已经了解此实现中正在做什么(对齐 -> 聚类 -> 选择)但我不知道下一步该怎么做才能达到我的目标,即语法诱导。
我的问题是:完成这3步算法后,接下来应该做什么来得到归纳文法,怎么做?
这是 ABL 实现的链接(适用于 linux):
最佳答案
包装中有一个pdf手册,另外我写信给Zaanen博士(他介绍了ABL),这是他的回答:
I have written a small Perl script some years ago that does something like this. I'm not sure the conversion of left recursive rules to right recursive rules works well, though.
Zaanen
这是他的代码(我没查过)
#!/usr/bin/perl -w
use strict;
use vars qw($opt_h $opt_i $opt_o $opt_l $opt_d);
use Getopt::Std;
$opt_i ="-"; # default value
$opt_o ="-"; # default value
getopts('hi:o:ld');
$opt_h ||=0; # default value
$opt_d ||=0; # default value
$opt_l ||=0; # default value
my $usage =
"Usage: $0 [OPTION]\.\.\.
This program converts an ABL file into a Nuance GSL file\.
-i FILE Name of input file (default: $opt_i)
-o FILE Name of output file (default: $opt_o)
-l Convert left recurive rules to right recursive (default: off)
-d Debug (default: off)
-h Show this help and exit
";
die $usage if $opt_h;
die $usage if $opt_i eq "";
open(INPUT, "<$opt_i")
|| die "Couldn't open input file: $!\n";
die $usage if $opt_o eq "";
open(OUTPUT, ">$opt_o")
|| die "Couldn't open outputfile: $!\n";
my %grammar;
my $start_nonterm;
my %first;
sub read_line() {
my $line=<INPUT>;
while (defined($line) and ($line=~/^#/)) {
$line=<INPUT>;
}
return $line;
}
sub extract_structure {
my $structure=$_[0];
my %structure;
my $constituent;
while ($structure=~/\(\s*(\d+)\s*,\s*(\d+)\s*,\s*\[([^\]]+)\]\s*\)\s*/g) {
my $b=$1;
my $e=$2;
my $n=$3;
if ($n!~/^\d+$/) {
die "Incorrect nonterminal format: $n";
}
if ($b!=$e) {
$structure{$b}{$e}=$n;
}
}
return %structure;
}
sub find_rhs {
my @sentence=@{$_[0]};
my %structure=%{$_[1]};
my $begin=$_[2];
my $end=$_[3];
my @result;
my $counter=$begin;
while ($counter!=$end) {
if (defined($structure{$counter})) {
# handle non-term
my @keys=sort { $a < $b } keys %{$structure{$counter}};
if ($keys[0]>$end) {
die "Found overlapping constituent: ($counter,$keys[0],[${$structure{$counter}}{$keys[0]}])";
}
my $nonterm=translate_nonterm(${$structure{$counter}}{$keys[0]});
push (@result, $nonterm);
find_grammar(\@sentence, \%structure, $counter, $keys[0]);
$counter=$keys[0];
}
else {
# handle term
push (@result, $sentence[$counter]);
++$counter;
}
}
return join(" ", @result);
}
sub find_grammar {
my @sentence=@{$_[0]};
my %structure=%{$_[1]};
my $begin=$_[2];
my $end=$_[3];
my $top_level=$_[4];
my $lhs="";
if (defined($structure{$begin}) and
defined(${$structure{$begin}}{$end})) {
$lhs=${$structure{$begin}}{$end};
delete ${$structure{$begin}}{$end};
if (scalar(keys %{$structure{$begin}})==0) {
delete $structure{$begin};
}
}
if ($lhs eq "") {
die "missing start symbol";
}
my $rhs=find_rhs(\@sentence, \%structure, $begin, $end);
$lhs=translate_nonterm($lhs);
if ($top_level) {
$start_nonterm=$lhs;
}
${$grammar{$lhs}}{$rhs}++;
}
sub translate_nonterm {
my $in=$_[0];
if ($in==0) {
return "A";
}
my $result;
while ($in!=0) {
my $digit=$in%10;
$in=($in-($in%10))/10;
$result.=chr(ord("A")+$digit);
}
return $result;
}
sub remove_direct_left_recursion {
my $Ai=$_[0];
my @rhss=keys %{$grammar{$Ai}};
my %recursive;
my %nonrecursive;
foreach my $rhs (@rhss) {
if ($rhs=~/^$Ai\s*(.*)$/) {
my $alpha=$1;
$recursive{$alpha}++;
}
else {
$nonrecursive{$rhs}++;
}
}
if (scalar(keys %recursive)>0) {
delete $grammar{$Ai}; # remove
delete $first{$Ai};
foreach my $rhs (keys %nonrecursive) {
if ($rhs=~/^([A-Z]+)\s*(.*)$/) {
$first{$Ai}{$1}=1;
}
$grammar{$Ai}{$rhs}++;
$grammar{$Ai}{$rhs." $Ai'"}++;
}
foreach my $rest (keys %recursive) {
if ($rest=~/^([A-Z]+)\s*(.*)$/) {
$first{$Ai}{$1}=1;
}
$grammar{"$Ai'"}{$rest}++;
$grammar{"$Ai'"}{$rest." $Ai'"}++;
}
}
}
sub remove_left_recursion {
my $nonterm=$_[0];
print "handling $nonterm\n";
if (defined($first{$nonterm})) { # already done
print "already done\n";
return;
}
# find left nonterms in first
my @rhs=keys %{$grammar{$nonterm}};
foreach my $rhs (@rhs) {
if ($rhs=~/^([A-Z]+)\s*.*$/) {
my $left_nonterm=$1;
$first{$nonterm}{$left_nonterm}=1;
}
}
print "first level:".join(" ", (keys %{$first{$nonterm}}))."\n";
# find first of nonterms in first
foreach my $left_nonterm (keys %{$first{$nonterm}}) {
remove_left_recursion($left_nonterm);
foreach my $n (keys %{$first{$left_nonterm}}) {
$first{$nonterm}{$n}=1;
}
}
if (defined($first{$nonterm}{$nonterm})) {
my @chain=keys %{$first{$nonterm}};
foreach my $a (keys %first) {
print "$a:".join(" ", (keys %{$first{$a}}))."\n";
}
print "Identified chain $nonterm=".join(" ", @chain)."\n";
remove_left_recursion_chain(\@chain);
@chain=keys %{$first{$nonterm}};
foreach my $a (keys %first) {
print "$a:".join(" ", (keys %{$first{$a}}))."\n";
}
print "rest of chain: $nonterm=".join(" ", @chain)."\n";
}
}
sub remove_left_recursion_chain {
my @lhs=@{$_[0]};
my $nr_lhs=scalar(@lhs)-1;
for my $i (0 .. $nr_lhs) {
my $Ai=$lhs[$i];
my @rhs_Ai=keys %{$grammar{$Ai}};
if ($opt_d) {
print STDERR "Removing recursion of $Ai: ";
print STDERR "$i of $nr_lhs (".scalar(@rhs_Ai).")\n";
}
for my $j (0 .. $i-1) {
my $Aj=$lhs[$j];
foreach my $rhs (@rhs_Ai) {
if ($rhs=~/^$Aj\s*(.*)$/) {
my $alpha=$1;
delete ${$grammar{$Ai}}{$rhs};
foreach my $beta (keys %{$grammar{$Aj}}) {
${$grammar{$Ai}}{"$beta $alpha"}++;
if ($rhs=~/^([A-Z]+)\s*(.*)$/) {
$first{$Ai}{$1}=1;
}
}
delete $first{$Ai}{$Aj};
}
}
}
# transform direct left recursion
remove_direct_left_recursion($Ai);
}
}
sub remove_unreachable_rules {
my %used_tokens;
$used_tokens{$start_nonterm}++; # start is always reachable
foreach my $lhs (keys %grammar) {
foreach my $rhs (keys %{$grammar{$lhs}}) {
foreach my $token (split(/\s+/, $rhs)) {
$used_tokens{$token}++;
}
}
}
my @lhss=keys %grammar;
foreach my $lhs (@lhss) {
if (!defined($used_tokens{$lhs})) {
delete $grammar{$lhs};
}
}
}
sub print_grammar {
foreach my $lhs (sort keys %grammar) {
my %rhss=%{$grammar{$lhs}};
my @rhss;
foreach my $rhs (keys %rhss) {
if ($rhs=~/\s/) {
push (@rhss, "($rhs)");
}
else {
push (@rhss, "$rhs");
}
}
if ($lhs eq $start_nonterm) {
$lhs=".$lhs";
}
if (scalar(@rhss)>1) {
print OUTPUT "$lhs [".join(" ", @rhss)."]\n";
}
else {
print OUTPUT "$lhs ".join(" ", @rhss)."\n";
}
}
}
my $nr_lines;
my $line=read_line();
while (defined($line)) {
$nr_lines++;
chomp ($line);
if ($line!~/^(.*)@@@(.*)$/) {
die "Incorrect input: $line";
}
my @sentence=split(/\s+/, $1);
my $structure=$2;
my %structure=extract_structure($structure);
# do top level
find_grammar(\@sentence, \%structure, 0, scalar(@sentence), 1);
$line=read_line();
}
if ($opt_d) {
print STDERR "$nr_lines lines\n";
print STDERR scalar(keys %grammar)." nonterminals\n";
my $nr_rules;
foreach my $nonterm (keys %grammar) {
$nr_rules+=scalar(keys %{$grammar{$nonterm}});
}
print STDERR "$nr_rules rules\n";
}
if ($opt_l) {
remove_left_recursion($start_nonterm);
# remove_left_recursion();
# remove_unreachable_rules();
if ($opt_d) {
print STDERR scalar(keys %grammar)." non left recursive nonterminals\n";
my $nr_rules;
foreach my $nonterm (keys %grammar) {
$nr_rules+=scalar(keys %{$grammar{$nonterm}});
}
print STDERR "$nr_rules non left recursive rules\n";
}
}
print_grammar();
close(INPUT);
close(OUTPUT);
关于algorithm - 语法推理 : How can the algorithm Alignment Based Learning help us infering a grammar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29470509/
在此处回答的另一个问题中,我发现了以下 JavaScript代码: function _dom_trackActiveElement(evt) { if (evt && evt.target)
if (A == 0) OR (B == 0) 怎么说? 最佳答案 只是为了讽刺: if (A === 0 || B === 0) 关于语法,我们在Stack Overflow上找到一个类似的问题:
var ret = [] ,xresult = document.evaluate(exp, rootEl, null, X
我一直在寻找一些类似于下例的 JavaScript。有人可以解释一下吗,因为我以前从未见过这样编写的 JavaScript。 “SomethingHere”和冒号代表什么?我习惯于看到函数 myFun
这是我的程序: delimiter // drop procedure if exists migContactToActor; create procedure migContactToActor(
我遇到了一个问题。我一直在使用 gcc 编译/汇编我的 C 代码一段时间,并且习惯了阅读 Intel 汇编语法。我在生成程序集文件时使用了 -masm=intel 标志。 但是最近因为公司迁移,拿到了
自上而下和自下而上语法有什么区别?举个例子就太好了。 最佳答案 首先,语法本身不是自上而下或自下而上的,解析器是(尽管有些语法可以被其中一个解析,但不能被另一个解析)。 从实践的角度来看,主要区别在于
我知道这是草率的代码,但它是: display dialog ("Start Screensaver. Please type: matrix, coffee, waffles, star, wate
这个问题已经有答案了: Giving name to a loop (6 个回答) 已关闭 8 年前。 我见过这个字符在 C# 中使用,就像 Java 中的扩展一样,但最近我在代码中发现了这个 loo
我正在尝试编写一个函数来检查字符串是否为回文,但我认为在使用字符串指针时存在一些错误。这段代码有什么问题? #include #include #define MAX 1000 int IsPalin
所以在this question我询问了一些 Javascript 是如何被压缩的。问题已得到解答,但以下片段让我非常困惑,以至于我不得不问另一个问题。在这里: for (Y = 0; $ = 'zx
假设我有一个接受这些参数的函数。 int create(Ptr * p,void * (*insert)(void *, void *)) { //return something later } 结
这个问题已经有答案了: Bitwise '&' operator (6 个回答) 已关闭 5 年前。 我在代码中找到了这个,但我从未遇到过像 & 这样的事情,仅 && if ((code & 1) =
我在处理继承类及其中的构造函数和方法的语法时遇到了问题。 我想实现一个类日期和一个子类 date_ISO,它们将按特定顺序设置给定的日、月、年,并通过一种方法将其写入字符串。我觉得我的基类日期工作正常
我正在尝试通过存储过程填充表,如下所示: SET @resultsCount = (SELECT COUNT(*) FROM tableA); SET @i = 0; WHILE @i THEN
谁能解释一下下面代码中的“<<”? mysql test<
刚刚开始学习 MySQL,这是一个菜鸟问题,也是我在 StackOverflow 上的第一个问题。 假设我有 12 个订单状态,我想从其中的 5 个中选择总计。我会使用: SELECT SUM(tot
我的编程背景是在学校学过一点Java。由于某些原因,JavaScript 语法往往让我感到困惑。下面的 JavaScript 代码是一种我不知道如何构成的语法模式: foo.ready = funct
我正在阅读 javascript 源代码,并且我以前没有编写过 javascript。我对它的一些语法感到困惑。 $(function () { window.onload=function
我什至不知道如何命名我想要的东西。那么让我举个例子来解释一下。 虽然火狐使用textContent,但其他浏览器支持innerText属性。顺便说一句,如果我使用了错误的术语,请纠正我。无论如何,到目
我是一名优秀的程序员,十分优秀!