标签: antlr

访问 ANTLR 4 中的通道并单独解析它们

我已将我的评论添加到 ANTLR 4 中的一个单独频道中。在我的例子中,它是频道 2。

这是我的词法分析器语法。

COMMENT: '/*' .*? '*/' -> channel(2) 
       ;
Run Code Online (Sandbox Code Playgroud)

我想访问这个频道 2 并在这个频道上进行解析以积累评论。所以我将其包含在解析语法中,如下所示:

comment
:COMMENT
;
Run Code Online (Sandbox Code Playgroud)

节目中

        string s = " paring string"
        AntlrInputStream input = new AntlrInputStream(s);
        CSSLexer lexer = new CSSLexer(input); 
       
        CommonTokenStream tokens = new CommonTokenStream(lexer,2);
Run Code Online (Sandbox Code Playgroud)

然后我想对令牌进行解析

var xr = parser.comment().GetRuleContexts<CommentContext>();
Run Code Online (Sandbox Code Playgroud)

因为我想从 CommentContext 对象获取信息,例如Start.Column等。

编辑:

这是改进后的问题

更具体地说,我想获取通道 2 中的所有标记,并使用注释语法解析它们,将所有注释获取到 list( IReadOnly<CommentContext>) 中,以便我可以迭代每个注释并访问诸如起始行、起始列、结束行结束列和标记文本。

CommonTokenStream tokens = new CommonTokenStream(lexer,2);
Run Code Online (Sandbox Code Playgroud)

这并没有给我通道 2 中的标记。我发现的另一件事是,直到这些标记作为参数传递给解析器构造XParser parser = new XParser(tokens);

然后只有我可以通过调用来访问令牌GetTokens()。在令牌中,我可以看到有一些注释被标识为令牌并且位于通道 2 中。尽管CommentTokenStrem指定了上面的通道号。它包含所有令牌。 …

c# antlr antlr4

3
推荐指数
1
解决办法
4182
查看次数

使用 Antlr 获取标识符和函数名称

我正在尝试使用和理解 AntLR,这对我来说是新的。我的目的是读取用 C 编写的源代码文件并从中提取标识符(变量和函数名称)。

在我的 C 语法(文件C.g4)中考虑:

identifierList
    :   Identifier
    |   identifierList Comma Identifier
    ;
Identifier
    :   IdentifierNondigit
        (   IdentifierNondigit
        |   Digit
        )*
    ;
Run Code Online (Sandbox Code Playgroud)

生成解析器和侦听器后,我创建了自己的标识符列表侦听器。

请注意,MyCListener 类扩展了 CBaseListener:

public class MyCListener extends CBaseListener {


@Override
public void enterIdentifierList(CParser.IdentifierListContext ctx) {
    List<ParseTree> children = ctx.children;
    for (ParseTree parseTree : children) {
        System.out.println(parseTree.getText());
    }

}
Run Code Online (Sandbox Code Playgroud)

然后我在主课上有这个:

 String fileurl = "C:/example.c";

 CLexer lexer;
 try {
       lexer = new CLexer(new ANTLRFileStream(fileurl));
       CommonTokenStream tokens = new CommonTokenStream(lexer);
       CParser parser = new CParser(tokens);

       CParser.IdentifierListContext …
Run Code Online (Sandbox Code Playgroud)

c java antlr

3
推荐指数
1
解决办法
3223
查看次数

ANTLR V4 词法分析器前瞻正则表达式

我正在尝试为类似 XML 的语言编写语法,其中我们使用 << 而不是 < 字符。这是词法分析器的部分快照,其中 TEXT 表示(外部)标签之间的文本:

OPEN  : '<<' ;
CLOSE : '>>' ;
TEXT  : ~[^<]+ ;
Run Code Online (Sandbox Code Playgroud)

上面 TEXT 的定义显然是错误的,因为即使一个后面没有另一个 <,它也会在第一次出现 < 时停止。我正在寻找一种方法来定义“捕获所有内容,直到遇到 <<”,但不将 << 包含在匹配中。

所以这样的事情也行不通:

TEXT  : .*? '<<' ;
Run Code Online (Sandbox Code Playgroud)

有没有办法在 ANTLR4 中实现这一点?

——TR

regex parsing antlr lexer antlr4

3
推荐指数
1
解决办法
1368
查看次数

有没有办法生成单元测试来测试我的语法

我使用 antlr4 创建了我的语法,但我想测试鲁棒性
是否有自动工具或快速完成的好方法

谢谢 :)

grammar antlr antlr4

3
推荐指数
1
解决办法
1951
查看次数

ANTLR4 Lexing C++11 原始字符串

全部,

我一直在尝试从标准文档 N4567 创建 C++ 语法,这是我能找到的最新版本。我相信语法是完整的,但我需要测试它。我一直试图解决的一个问题是让词法分析器从标准中识别原始字符串。我已经使用 Actions & Semantic Predicates 实现了一个可能的解决方案。我需要帮助确定它是否真的有效。我已经阅读了关于操作和谓词之间交互的 ANTLR4 参考,但可以决定我的解决方案是否有效。下面包含一个精简语法。任何想法将不胜感激。我试图将我的想法包含在样本中。

grammar SampleRaw;

@lexer::members {
    string d_char_seq = "";
}

string_literal
        : ENCODING_PREFIX? '\"' S_CHAR* '\"'
        | ENCODING_PREFIX? 'R' Raw_String
        ;

ENCODING_PREFIX             //  one of
        : 'u8'
        | [uUL]
        ;

S_CHAR          /* any member of the source character set except the
                   double_quote ", backslash \, or NEW_LINE character
                 */
        : ~[\"\\\n\r]
        | ESCAPE_SEQUENCE
        | UNIV_CHAR_NAME
        ;

fragment ESCAPE_SEQUENCE
        : SIMPLE_ESCAPE_SEQ
        | OCT_ESCAPE_SEQ
        | HEX_ESCAPE_SEQ
        ;
fragment SIMPLE_ESCAPE_SEQ  // …
Run Code Online (Sandbox Code Playgroud)

c++ antlr lexer c++11 antlr4

3
推荐指数
1
解决办法
340
查看次数

ANTLR4 - 如何在 ANTLR 中获取令牌 TYPE 作为令牌文本?

假设我有一个具有如下标记的语法:

AND        : 'AND' | 'and' | '&&' | '&';
OR         : 'OR' | 'or' | '||' | '|' ;
NOT        : 'NOT' | 'not' | '~' | '!';
Run Code Online (Sandbox Code Playgroud)

当我使用 TreeViewer 可视化 ParseTree 或使用 tree.toStringTree() 打印树时,每个节点的文本与匹配的文本相同。

因此,如果我解析“A 和 B 或 C”,两个二元运算符将是“和”/“或”。如果我解析“A && B || C”,它们将是“&&”/“||”。

我希望它们始终是“AND”/“OR/NOT”,无论匹配什么文字符号。这可能吗?

antlr antlr4

3
推荐指数
1
解决办法
3828
查看次数

antlr4 中的 ParseTree 遍历

我正在使用antlr4 c++。我有一个ParseTree,我正在尝试重新创建树结构。为此,我使用了访问者my_Visitor和我自己的节点对象。

我的问题是visitChildren(tree::RuleNode*)调用所有子树的访问函数,所以当遍历一棵子树并访问下一棵子树时,我会丢失信息。

假设一棵树是这样的:

  A
 / \
B   C
Run Code Online (Sandbox Code Playgroud)

当我调用visitChildren(A)visitExpression(ExpressionContext*)对B和C使用重载函数)时,我可以提取访问顺序为A,B,C的信息。

这个序列也可能是由于:

A
|
B
|
C
Run Code Online (Sandbox Code Playgroud)

要重新创建树,我想我需要类似的东西

antlrcpp::Any my_Visitor::my_visitChildren(tree::RuleNode* A){
    for(int i=0;i<A->children.size();i++){
        //create a new node in my own tree representation as child of A
        visit(A->children[i]);
    }
}
Run Code Online (Sandbox Code Playgroud)

并调用my_visitChildren我的重载visitExpression函数。

这里的问题A->children[i]是 aTree并且visit(.)需要 a ParseTree

我可以以某种方式创建一个ParseTreefromchildren[i]还是有更好的方法来做到这一点?

我也在考虑使用映射tree->parent到我的对象并将我的新节点附加到那里,但是如果我想省略一些节点(例如对于 AST),这不是最佳选择。

c++ antlr antlr4

3
推荐指数
1
解决办法
883
查看次数

ANTLR if-else 歧义错误

我正在尝试为简单的编程语言创建 ANTLR 语法。

它有类似 C 的 if 语句:

program
    : statement* EOF
    ;

statement
    : block                                                                 # blockStatement
    | SEMI                                                                  # emptyStatement
    | assignment                                                            # assignmentStatement
    | declaration                                                           # variableDeclarationStatement
    | 'if' parExpression ifBody=statement ('else' elseBody=statement)?      # ifStatement
    ..........
    ;

block
    : '{' statement* '}'
    ;

expression
    : literal                                                           # literalExpression
    | Identifier                                                        # variableReference
    ..........
    ;

parExpression : '(' expression ')';

assignment : Identifier assignmentOp expression SEMI;

SEMI : ';';

Identifier : (LETTER | '_') (LETTER | DIGIT | …
Run Code Online (Sandbox Code Playgroud)

compiler-construction grammar antlr antlr4

3
推荐指数
1
解决办法
631
查看次数

ANTLR4 在导入时找不到语法

我试图将我的 ANTLR4 语法拆分为多个文件,以便我可以更轻松地测试它们,我在 java 项目中使用 gradle 作为构建工具。

两种语法都可以单独正确编译,但是当我将导入添加到我的主语法时,我得到下一个编译错误

错误(110):kanekotic/specflow/rider/SpecflowFeature.g4:3:7:无法找到或加载语法SpecflowScenario

inherited语法看起来像:

grammar SpecflowScenario;

@header {
    package kanekotic.specflow.rider;
}

scenario
    : 'Scenario: ';
Run Code Online (Sandbox Code Playgroud)

main语法看起来像:

grammar SpecflowFeature;

import SpecflowScenario;

@header {
    package kanekotic.specflow.rider;
}

file returns [List<String> values]
    @init { $values = new ArrayList<String>(); }
    : 'Feature: ' EOF;
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?这是不允许的吗?

编辑:

gradle.build样子:

plugins {
    id "org.jetbrains.intellij" version "0.1.10"
}

apply plugin: 'org.jetbrains.intellij'
apply plugin: 'java'
apply plugin: 'antlr'

sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8

intellij {
    version …
Run Code Online (Sandbox Code Playgroud)

java parsing antlr gradle antlr4

3
推荐指数
1
解决办法
1494
查看次数

AntLR4:构建一个函数

我一直在尝试构建一个函数: concat('A','B') OR concat('A',9)

这是我写的示例语法:

    LPAREN : '(' ;
    RPAREN : ')' ;
    FUNCTIONNAME : 'CONCAT' ;
    ARGUMENTS : TEXT (',' TEXT)* ;
    TEXT : ('a'..'z' | '0'..'9' | 'A'..'Z')+; 
    allFunction : FUNCTIONNAME LPAREN ARGUMENTS (',' ARGUMENTS)* RPAREN ;
Run Code Online (Sandbox Code Playgroud)

但无法正确构建一棵树。

更新1

这是树:

  0 null
-- 11 CONCAT
-- 4 (
-- 13 2,5
-- 5 ) 
Run Code Online (Sandbox Code Playgroud)

和语法:

allFunction : FUNCTIONNAME LPAREN ARGUMENTS RPAREN;
Run Code Online (Sandbox Code Playgroud)

更新2

语法:

allfunction : COMMA | FUNCTIONNAME LPAREN ARGUMENTS (COMMA ARGUMENTS)* RPAREN ;
Run Code Online (Sandbox Code Playgroud)

解析输出:

CONCAT(A,B,C) …

java antlr function context-free-grammar antlr4

3
推荐指数
1
解决办法
1994
查看次数