【问题标题】:Grammar in ANTLR4ANTLR4 中的语法
【发布时间】:2022-01-09 18:49:21
【问题描述】:

所以我从这个 github 存储库 grammars-v4/dot/DOT.g4 中的 DOT.g4 语法中获得了灵感。这就是为什么我还要解析一个 DOT 文件。

这是我的 DOT 文件的可能结构:

digraph G {
 rankdir=LR
  label="\n[Büchi]"
  labelloc="t"
  node [shape="circle"]
  I [label="", style=invis, width=0]
  I -> 34
  0 [label="0", peripheries=2]
  0 -> 0 [label="!v_0"]
  1 [label="1", peripheries=2]
  1 -> 1 [label="!v_2 & !v_5"]
  2 [label="2"]
  2 -> 1 [label="v_0 & v_1 > 5 & !v_2 & v_3 < 8 & !v_5"]
  3 [label="3"]
  3 -> 1 [label="v_0 & v_1 > 5 & !v_2 & v_3 < 8 & !v_5"]
  4 [label="4"]
  4 -> 1 [label="v_1 > 5 & !v_2 & v_3 < 8 & !v_5"]
  5 [label="5"]
  5 -> 1 [label="v_0 & v_1 > 5 & !v_2 & v_3 < 8 & !v_5"]
}

这里是我从上面的链接修改的grammar.g4文件:

parse: nba| EOF;
nba: STRICT? ( GRAPH | DIGRAPH ) ( initialId? ) '{' stmtList '}';
stmtList : ( stmt ';'? )* ;
stmt: nodeStmt| edgeStmt| attrStmt | initialId '=' initialId;
attrStmt: ( GRAPH | NODE | EDGE )  '[' a_list? ']';
a_list: ( initialId ( '=' initialId  )? ','? )+;
edgeStmt: (node_id) edgeRHS label ',' a_list? ']';
label: ('[' LABEL '=' '"' (id)+ '"' );
edgeRHS: ( edgeop ( node_id ) )+;
edgeop: '->';
nodeStmt: node_id label? ',' a_list? ']';
node_id: initialId ;
id: ID | SPACE | DIGIT | LETTER | SYMBOL | STRING ;
initialId : STRING | LETTER | DIGIT;

这里是词法规则:

GRAPH: [Gg] [Rr] [Aa] [Pp] [Hh];
DIGRAPH: [Dd] [Ii] [Gg] [Rr] [Aa] [Pp] [Hh];
NODE: [Nn] [Oo] [Dd] [Ee];
EDGE: [Ee] [Dd] [Gg] [Ee];
LABEL: [Ll] [Aa] [Bb] [Ee] [Ll];
/** "a numeral [-]?(.[0-9]+ | [0-9]+(.[0-9]*)? )" */
NUMBER: '-'? ( '.' DIGIT+ | DIGIT+ ( '.' DIGIT* )? );
DIGIT: [0-9];
/** "any double-quoted string ("...") possibly containing escaped quotes" */
STRING: '"' ( '\\"' | . )*? '"';
/** "Any string of alphabetic ([a-zA-Z\200-\377]) characters, underscores
 *  ('_') or digits ([0-9]), not beginning with a digit"
*/
ID: LETTER ( LETTER | DIGIT )*;
SPACE: '" "';
LETTER: [a-zA-Z\u0080-\u00FF_];
SYMBOL: '<'| '>'| '&'| 'U'| '!';
COMMENT: '/*' .*? '*/' -> skip;
LINE_COMMENT: '//' .*? '\r'? '\n' -> skip;
/** "a '#' character is considered a line output from a C preprocessor */
PREPROC: '#' ~[\r\n]* -> skip;
/*whitespace are ignored from the constructor*/
WS: [ \t\n\r]+ -> skip;

我单击了 ANTLR Recognizer 部分,该部分在 java 中创建自己的文件和解释语法的标记。现在我必须构建一个解析器,在其中我重写一些方法来匹配我在 Java 中的代码与由 ANTLR4 创建的 java 文件。但首先我想了解我对那种 DOT 的语法是否正确。如何验证?

【问题讨论】:

  • 您的语法不起作用。使用 Mike 在下面解释的“grun”命令(又名java org.antlr.v4.gui.TestRig)进行测试。其他一些注意事项: (1) 将解析器和词法分析器规则放在一个文件中。 (2) 它不会解析您的输入,因为“initialId”在右侧没有“ID”或只有“id”。 (3) “LETTER”总是被“ID”隐藏(在规则列表中它在“LETTER”之前),所以它是一个完全没用的规则/符号,永远不会被词法分析器识别。

标签: parsing antlr4 grammar


【解决方案1】:

回复:“我点击了 ANTLR 识别器”...听起来您正在使用某种带有插件或其他 ANTLR 工具的 IDE。将 VS Code 和 IntelliJ 与插件一起使用,但都没有“ANTLR Recognizer”部分(我可以看到)。所以以下假设使用命令行。这是简单的命令行内容,在使用 ANTLR 时绝对值得早期学习。 (不过,我使用的两个插件都可以在插件中查看令牌流和解析树)

如果您按照 www.antlr.org 上的“快速入门”进行操作,那么您将创建专门用于此目的的 grun 别名。

(假设你的语法名称是DOT

转储您的令牌流(所有词法分析器规则的结果)

grun DOT tokens -tokens

验证您是否正确解析输入:

grun DOT parse -gui

grun DOT parse -tree

顺便说一句,您不太可能需要覆盖解析器类。首先看看访客和听众。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-08
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多