Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Eclipse 如何使用antlr显示句子中的所有代词及其人称_Eclipse_Parsing_Antlr_Antlr3 - Fatal编程技术网

Eclipse 如何使用antlr显示句子中的所有代词及其人称

Eclipse 如何使用antlr显示句子中的所有代词及其人称,eclipse,parsing,antlr,antlr3,Eclipse,Parsing,Antlr,Antlr3,根据WayneH的语法编辑 这是我语法文件里的东西 grammar pfinder; options { language = Java; } sentence : ((words | pronoun) SPACE)* ((words | pronoun) ('.' | '?')) ; words : WORDS {System.out.println($text);}; pronoun returns [String value] : sfir

根据WayneH的语法编辑

这是我语法文件里的东西

grammar pfinder;

options {
  language = Java;
}
sentence
    : ((words | pronoun) SPACE)* ((words | pronoun) ('.' | '?'))
    ;

words 
    :   WORDS {System.out.println($text);};

pronoun returns [String value] 
    : sfirst {$value = $sfirst.value; System.out.println($sfirst.text + '(' + $sfirst.value + ')');}
    | ssecond {$value = $ssecond.value; System.out.println($ssecond.text + '(' + $ssecond.value + ')');}
    | sthird {$value = $sthird.value; System.out.println($sthird.text + '(' + $sthird.value + ')');}
    | pfirst {$value = $pfirst.value; System.out.println($pfirst.text + '(' + $pfirst.value + ')');}
    | psecond {$value = $psecond.value; System.out.println($psecond.text + '(' + $psecond.value + ')');}
    | pthird{$value = $pthird.value; System.out.println($pthird.text + '(' + $pthird.value + ')');};

sfirst returns [String value] :  ('i'   | 'me'  | 'my'   | 'mine') {$value = "s1";};
ssecond returns [String value] : ('you' | 'your'| 'yours'| 'yourself') {$value = "s2";};
sthird returns [String value] :  ('he'  | 'she' | 'it'   | 'his' | 'hers' | 'its' | 'him' | 'her' | 'himself' | 'herself') {$value = "s3";};
pfirst returns [String value] :  ('we'  | 'us'  | 'our'  | 'ours') {$value = "p1";};
psecond returns [String value] : ('yourselves') {$value = "p2";};
pthird returns [String value] :  ('they'| 'them'| 'their'| 'theirs' | 'themselves') {$value = "p3";};

WORDS : LETTER*;// {$channel=HIDDEN;}; 
SPACE : (' ')?;
fragment LETTER :  ('a'..'z' | 'A'..'Z');
下面是关于java测试类的内容

import java.util.Scanner;
import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
import java.util.List;

public class test2 {
    public static void main(String[] args) throws RecognitionException {
        String s;
        Scanner input = new Scanner(System.in);
        System.out.println("Eter a Sentence: ");
        s=input.nextLine().toLowerCase();
        ANTLRStringStream in = new ANTLRStringStream(s);
        pfinderLexer lexer = new pfinderLexer(in);
        TokenStream tokenStream = new CommonTokenStream(lexer);
        pfinderParser parser = new pfinderParser(tokenStream); 
        parser.pronoun(); 
    }
}

我需要在测试文件中放入什么,以便它显示一个句子中的所有代词及其各自的值(s1,s2,…)

片段不会创建标记,并且将它们放在解析器规则中不会给出理想的结果

在我的测试箱上,这产生了(我想!)期望的结果:

program :
        PRONOUN+
    ;

PRONOUN :
        'i'   | 'me'  | 'my'   | 'mine'
    |   'you' | 'your'| 'yours'| 'yourself'
    |   'he'  | 'she' | 'it'   | 'his' | 'hers' | 'its' | 'him' | 'her' | 'himself' | 'herself'
    |   'we'  | 'us'  | 'our'  | 'ours'
    |   'yourselves'
    |   'they'| 'them'| 'their'| 'theirs' | 'themselves'
    ;

WS  :   ' ' { $channel = HIDDEN; };

WORD    :   ('A'..'Z'|'a'..'z')+ { $channel = HIDDEN; };
在AntlWorks中,一个示例“我踢了你”返回了树结构:
program->[i,you]

我觉得有必要指出,Antlr从句子中去掉代词太过分了。考虑使用正则表达式。此语法不区分大小写。将单词扩展到除代词词典(如puncuation等)之外的所有内容可能有点乏味。需要对输入进行消毒

---编辑:响应第二个OP:

  • 我修改了原始语法,以便于分析。新语法是:

    grammar pfinder;
    
    options {
        backtrack=true;
        output = AST;
    }
    
    tokens {
        PROGRAM;
    }
    
    program :
            (WORD* p+=PRONOUN+ WORD*)*
            -> ^(PROGRAM $p*)
        ;
    
    
    PRONOUN :
            'i'   | 'me'  | 'my'   | 'mine'
        |   'you' | 'your'| 'yours'| 'yourself'
        |   'he'  | 'she' | 'it'   | 'his' | 'hers' | 'its' | 'him' | 'her' | 'himself' | 'herself'
        |   'we'  | 'us'  | 'our'  | 'ours' | 'yourselves'
        |   'they'| 'them'| 'their'| 'theirs' | 'themselves'
    ;
    
    WS  :   ' ' { $channel = HIDDEN; };
    
    WORD    :   ('A'..'Z'|'a'..'z')+;
    
我将解释这些变化:

  • 现在需要回溯来解决解析器规则程序。也许有一个更好的方式来写它,不需要回溯,但这是第一件突然出现在我脑海中的事情
  • 一个虚构的代词程序已经被定义来对代词进行分组
  • 每个匹配的程序都被添加到Antlr var$p中,并在AST中根据假想规则重写
  • 解释器代码现在可以使用CommonTree来收集匹配的代词
  • 下面是用C#(我不懂Java)编写的,但我编写它的目的是让您能够阅读和理解它

    static object[] ReadTokens( string text )
    {
        ArrayList results = new ArrayList();
        pfinderLexer Lexer = new pfinderLexer(new Antlr.Runtime.ANTLRStringStream(text));
        pfinderParser Parser = new pfinderParser(new CommonTokenStream(Lexer));
        // syntaxTree is imaginary token {PROGRAM},
        // its children are the pronouns collected by $p in grammar.
        CommonTree syntaxTree = Parser.program().Tree as CommonTree;
        if ( syntaxTree == null ) return null;
        foreach ( object pronoun in syntaxTree.Children )
        {
            results.Add(pronoun.ToString());
        }
        return results.ToArray();
    }
    
  • 调用ReadTokens(“我踢了你和他们”)返回数组[“我”、“你”、“他们”]


  • 如果你想对口语/书面语言进行某种程度的分析,你可以考虑使用某种自然语言处理工具。例如,将告诉您哪些元素是代词(以及动词、名词、副词和其他深奥的语法结构)。(THT是我唯一熟悉的这类工具,所以不要认为这是对惊人的特别认可)。

    我认为您需要在ANTLR中了解更多关于lexer规则的信息,lexer规则从大写字母开始,并为解析器将要查看的流生成标记。Lexer片段规则不会为流生成令牌,但会帮助其他Lexer规则生成令牌,请查看Lexer规则单词和字母(字母不是令牌,但会帮助单词创建令牌)

    现在,当文本文本被放入解析器规则(规则名称将以小写字母开头)时,该文本文本文本也是lexer将识别和传递的有效标记(至少当您使用ANTLR时-我没有使用任何其他类似于ANTLR的工具来回答)

    接下来我注意到的是,你的“s”和“代词”规则似乎是一样的。我注释掉了“s”规则,把所有的东西都放进了“代词”规则中

    最后一件事是学习如何把动作放到语法中,你可以在“s”规则中设置返回值。我让代词规则返回一个字符串值,这样,如果您想在“句子”规则中执行操作,就可以轻松完成“-I代词”注释/回答

    现在,因为我不知道你的确切结果是什么,我玩了你的语法,做了一些轻微的修改和重组(将我认为是解析器规则的部分移到顶部,将所有lexer规则保留在底部),并采取了一些行动,我认为这些行动将向你展示你需要的东西。此外,可能有几种不同的方法来实现这一点,我认为我的解决方案对于您可能想要的任何结果都不是完美的,但以下是我在AntlWorks工作时得到的一个语法:

    grammar pfinder;
    
    options {
      language = Java;
    }
    sentence
        : ((words | pronoun) SPACE)* ((words | pronoun) ('.' | '?'))
        ;
    
    words 
        :   WORDS {System.out.println($text);};
    
    pronoun returns [String value] 
        : sfirst {$value = $sfirst.value; System.out.println($sfirst.text + '(' + $sfirst.value + ')');}
        | ssecond {$value = $ssecond.value; System.out.println($ssecond.text + '(' + $ssecond.value + ')');}
        | sthird {$value = $sthird.value; System.out.println($sthird.text + '(' + $sthird.value + ')');}
        | pfirst {$value = $pfirst.value; System.out.println($pfirst.text + '(' + $pfirst.value + ')');}
        | psecond {$value = $psecond.value; System.out.println($psecond.text + '(' + $psecond.value + ')');}
        | pthird{$value = $pthird.value; System.out.println($pthird.text + '(' + $pthird.value + ')');};
    
    //s returns [String value]
    //    :  exp=sfirst  {$value = "s1";}
    //    |  exp=ssecond {$value = "s2";}
    //    |  exp=sthird  {$value = "s3";}
    //    |  exp=pfirst  {$value = "p1";}
    //    |  exp=psecond {$value = "p2";}
    //    |  exp=pthird  {$value = "p3";}
    //    ;
    
    sfirst returns [String value] :  ('i'   | 'me'  | 'my'   | 'mine') {$value = "s1";};
    ssecond returns [String value] : ('you' | 'your'| 'yours'| 'yourself') {$value = "s2";};
    sthird returns [String value] :  ('he'  | 'she' | 'it'   | 'his' | 'hers' | 'its' | 'him' | 'her' | 'himself' | 'herself') {$value = "s3";};
    pfirst returns [String value] :  ('we'  | 'us'  | 'our'  | 'ours') {$value = "p1";};
    psecond returns [String value] : ('yourselves') {$value = "p2";};
    pthird returns [String value] :  ('they'| 'them'| 'their'| 'theirs' | 'themselves') {$value = "p3";};
    
    WORDS : LETTER*;// {$channel=HIDDEN;}; 
    SPACE : (' ')?;
    fragment LETTER :  ('a'..'z' | 'A'..'Z');
    
    我认为最终的结果是,这个语法将告诉你如何完成你正在尝试做的事情,并且无论最终结果是什么,都需要修改

    祝你好运

    我想你只需要在考试课上换一行, parser.define(); 致: 语法分析器。句子()

    您可能还需要更改语法中的其他一些内容: 空间:'';
    句子:(单词|代词)(空格(单词|代词))*(‘.|’?’);//然后你可能需要在句子和单词/代词之间设置一条规则。

    谢谢。我不知道java代码可以在antlr中使用。另一个问题。如果我想展示一切,我能做到吗?因为在上面的代码中,当你输入“我踢了你”时,它会显示“i(s1)”,所以句子的其他部分被忽略。是否有一个循环或其他东西可以显示所有的句子,比如它会输出“i(s1)kicking you(s2)”或只是“i(s1)you(s2)”?如果你只得到第一个单词,那么你的控制程序中就会有一些东西。当我在AntlWorks中输入“我踢了你”时,它会显示:我(s1)踢了你(s2)在调试模式下,我必须一步一步地完成。你能不能给我看一下第二行的代词?我已经编辑了我的测试程序。我不知道为什么它只显示它在java测试类中找到的第一个代词,用parser.define()更改行;到语法分析器。句子();你应该把所有的单词都打印出来,并在代词后面加上“s#”字样。我没有做任何格式化,所以可以随意添加代码(在单独的行上打印每个单词之类的东西)。祝你好运。作为这个问题的结论,我将给你留下一些想法让你记住LEXER规则“每次正确匹配时创建一个令牌。”片段规则不创建任何标记。曾经它们被用作编写更好的词法规则的糖。它们不属于解析器规则。”“解析器规则”用于按特定顺序(“语法”)对标记进行分组,但它们解析为标记的“平面”列表。没有父母