gpt4 book ai didi

ANTLR - 允许关键字之间的任何字符

转载 作者:行者123 更新时间:2023-12-03 15:11:37 25 4
gpt4 key购买 nike

我想为一种简单的语言定义一个语法。

该语言允许进行某种分配。

例子

keyworda: this is the 1 keyword-A
keywordb: this is the second keywordb
...

问题是,在关键字和 ':' 之后任何字符都应该是可能的(关键字也是)

我已经尝试了很多东西,但我认为我仍然不喜欢词法分析器和解析器的想法......

我的最后一个想法失败了:
rule 
: 'keyworda' ':' anychar* 'keywordb' ':' anychar* EOF
;

anychar
: .
;

NEWLINE
: ('\r'? '\n') {$channel=HIDDEN;}
;

编辑

首先:感谢您的回答!

我通读了手册并查看了 scott stanchfield 的教程。

问题是,我没有得到“anychar”的东西!

你是对的,我上面postet的语法是错误的,因为我很着急。

更好的尝试是在前面。问题仍然是,Tokenizer 识别例如定义中的关键字 ala
keyworda : this is keyworda.
keywordb : this is another key!
...

语法:
rule
: KEYA ':' STRING_LITERAL* NEWLINE
keybdefinition*
EOF
;

keybdefinition
: KEYB ':' STRING_LITERAL* NEWLINE
;


KEYA: 'keyworda';
KEYB:'keywordb';
STRING_LITERAL: 'a'..'z' | 'A'..'Z' | '0'..'9' | ':' | '.' | '&' | '/' | '\\' | ';';

NEWLINE: '\r'? | '\n';
SPACE: (' ' | '\t') {$channel=HIDDEN;};

编辑二

哦,我的上帝,按照你解释的方式做这件事很明显。不知道为什么我自己没有得到它!非常感谢蒂姆的解释!

我只剩下一个问题了:
如果我为词法分析器定义标记,为解析器定义语法。这是在树解析器或解析器本身中检查语义的常用方法吗?

例如,假设我定义了与您发布的相同的语法。
keyworda : ab
keywordb : xy
keyworda : ab1
keywordb : xy1
...

现在我想检查是否在每个关键字a定义之后定义了一个关键字b。
后来我确实想检查值是否正确。
假设我们确实有一个关键字 extends : 'keyword value',我需要检查是否已经定义了 'keyword value'。

我可以通过两种方式做到这一点:首先,更改解析器的语法规则并在那里添加用于检查的 Java 代码。其次,语法保持原样,我定义了一个树解析器语法来检查这些条件。

我真的不知道哪种方式更好,优点或缺点是什么......

非常感谢你的帮助

最佳答案

.在词法分析器规则和解析器规则中具有不同的含义。在词法分析器规则中,它匹配范围内的任何字符 \u000 ... \uFFFF .在解析器规则中,.匹配任何 token 。

请注意,词法规则以大写字母开头,解析器规则以小写字母开头。您还可以创建标记(词法规则)作为解析器规则中的文字。这意味着您的语法只会创建 4 个不同的标记(实际上是 3 个,因为 NEWLINE 是“隐藏的”):

  • 'keyworda'
  • ':'
  • 'keywordb'
  • NEWLINE (从默认 token 流中删除)

  • ( EOF 是内置 token )

    所以,这使您的 anychar规则匹配 'keyworda' , ':''keywordb' ,而不是您可能期望的任何字符。

    此外,您似乎正在分离您的 key ':' value - 通过换行符输入,但您在词法分析阶段删除换行符。通过删除它们,你怎么知道 value 的结尾是什么?是什么开始 key是?您的 token 流将是 的连续流关键词 , 任何字符 冒号 ,因此无法判断某个关键字何时真正是关键字,或者是 value 的一部分。 (在 ':' 的右侧)。为此,您需要一个换行符。

    看起来您已经开始使用 ANTLR 而不真正知道自己在做什么:IMO,这不是学习此特定工具的方法。我建议获取一份 The Definitive ANTLR Reference或阅读/看一些 ANTLR tutorials在继续之前。

    祝你好运!

    编辑

    这是如何让关键字也成为您的“值(value)”的一部分的快速演示:

    文件:T.g

    grammar T;

    parse
    : line+ EOF
    ;

    line
    : key COLON value eol
    {System.out.printf("key='\%s', value='\%s'\n", $key.text, $value.text);}
    ;

    value
    : any_except_newline*
    ;

    key
    : KEYA
    | KEYB
    ;

    any_except_newline
    : COLON
    | KEYA
    | KEYB
    | WORD
    | ANYCHAR
    ;

    eol
    : NEWLINE
    | EOF
    ;

    COLON : ':';
    KEYA : 'keyworda';
    KEYB : 'keywordb';
    WORD : ('a'..'z' | 'A'..'Z')+;
    NEWLINE : '\r'? '\n' | '\r';
    SPACE : (' ' | '\t') {$channel=HIDDEN;};
    ANYCHAR : .;

    文件:Main.java

    import org.antlr.runtime.*;

    public class Main {
    public static void main(String[] args) throws Exception {
    String source =
    "keyworda : this is keyworda.\n" +
    "keywordb : this is another key!";
    TLexer lexer = new TLexer(new ANTLRStringStream(source));
    TParser parser = new TParser(new CommonTokenStream(lexer));
    parser.parse();
    }
    }

    如果您现在通过执行以下操作运行演示:

    java -cp antlr-3.3.jar org.antlr.Tool T.g
    javac -cp antlr-3.3.jar *.java
    java -cp .:antlr-3.3.jar Main

    您会看到以下内容被打印到控制台:

    key='keyworda', value='this is keyworda.'
    key='keywordb', value='this is another key!'

    关于ANTLR - 允许关键字之间的任何字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7286169/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com