我使用 AntlrWorks 创建了一个 antlr 语法,并创建了一个供内部使用的本地化工具。我想在解析时将 unicode 转义序列转换为实际的 Java 字符,但不确定执行此操作的最佳方法。这是我的语法中的标记定义。是否有某种方法可以为片段 UNICODE_ESC 指定一个操作,该操作将返回字符,而不是六个字符转义序列?
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
INT : '0'..'9'+
;
COMMENT
: '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
| '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
;
WS : ( ' '
| '\t'
| '\r'
| '\n'
) {$channel=HIDDEN;}
;
STRING
: '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
;
fragment
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;
fragment
ESC_SEQ
: '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
| UNICODE_ESC
| OCTAL_ESC
;
fragment
OCTAL_ESC
: …Run Code Online (Sandbox Code Playgroud) 可能它会结合几个问题,但上下文是相同的。
背景:我需要为 Lucene 实现自定义查询解析。原因是我不将某些字段存储在 Lucene 中,而是将它们保存在单独的数据库中,因为它们更改得太频繁。该字段为分类类别,即猫
所以,我想像这样解析查询:
(猫:重要和你好)或(猫:不重要和你好)
是否有类似 Lucene 的语言的标准 ANTLR4 查询解析器(或示例)?有没有一种方法可以引入自定义 QueryNode,而不需要我从头开始重写所有内容(Sytax、QueryBuilders 等)?
非常感谢大家!!!
我正在尝试学习语言解析以获得乐趣......
我创建了一个ANTLR语法,我相信它与我希望实现的简单语言相匹配.它将具有以下语法:
<FunctionName> ( <OptionalArguments>+) {
<OptionalChildFunctions>+
}
Run Code Online (Sandbox Code Playgroud)
实际例子:
ForEach(in:[1,2,3,4,5] as:"nextNumber") {
Print(message:{nextNumber})
}
Run Code Online (Sandbox Code Playgroud)
我相信我的语法正确地匹配这个结构,现在我正在尝试为该语言构建一个抽象语法树.
首先,我必须承认我不完全确定这棵树应该看起来如何.其次,我完全失去了如何在我的Antlr语法中做到这一点......我几个小时都没有取得太大的成功.
这是我正在寻找树的当前想法:
FunctionName
/ \
Attributes \
/ \ / \
ID /\ ChildFunctions
/ \ ID etc
/ \
Attribute AttributeValue
Type
Run Code Online (Sandbox Code Playgroud)
这是我目前的Antlr语法文件:
grammar Test;
options {output=AST;ASTLabelType=CommonTree;}
program : function ;
function : ID (OPEN_BRACKET (attribute (COMMA? attribute)*)? CLOSE_BRACKET)? (OPEN_BRACE function* CLOSE_BRACE)?;
attribute : ID COLON datatype;
datatype : NUMBER | STRING | BOOLEAN | array | lookup ;
array : OPEN_BOX (datatype (COMMA …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用ANTLR为各种时间格式(12:30,0945,1:30-2:45,...)编写语法.到目前为止,只要我没有输入未在语法文件中定义的字符,它就像魅力一样.
我正在使用以下JUnit测试,例如:
final CharStream stream = new ANTLRStringStream("12:40-1300,15:123-18:59");
final TimeGrammarLexer lexer = new TimeGrammarLexer(stream);
final CommonTokenStream tokenStream = new CommonTokenStream(lexer);
final TimeGrammarParser parser = new TimeGrammarParser(tokenStream);
try {
final timeGrammar_return tree = parser.timeGrammar();
fail();
} catch (final Exception e) {
assertNotNull(e);
}
Run Code Online (Sandbox Code Playgroud)
抛出异常(如预期),因为"15:123"无效.如果我尝试("15:23a"),但没有异常被抛出,ANTLR将其视为有效输入.
现在,如果我在语法中定义字符,ANTLR似乎会注意到它们,我再一次得到我想要的异常:
CHAR: ('a'..'z')|('A'..'Z');
Run Code Online (Sandbox Code Playgroud)
但是如何排除用户可以输入的变音符号,符号和其他内容(äöü{%&<>!).所以基本上我正在寻找一种语法:匹配一切但是"0..9,: - "
我正在尝试构建一个解释用户输入文本,搜索引擎样式的语法.它将支持AND,OR,NOT和ANDNOT布尔运算符.我几乎所有工作都有效,但是我想添加一个规则,即在带引号的字符串之外的两个相邻关键字被隐含地视为AND子句.例如:
奶酪和饼干=奶酪和饼干
(上下)或(左和右)=(上下)或(左和右)
猫狗"大肚猪"=猫与狗和"大肚猪"
我遇到了最后一个问题,我希望有人可以指出我正确的方向.到目前为止,这是我的*.g文件,请保持良好,我的ANTLR体验不到一个工作日:
grammar SearchEngine;
options { language = CSharp2; output = AST; }
@lexer::namespace { Demo.SearchEngine }
@parser::namespace { Demo.SearchEngine }
LPARENTHESIS : '(';
RPARENTHESIS : ')';
AND : ('A'|'a')('N'|'n')('D'|'d');
OR : ('O'|'o')('R'|'r');
ANDNOT : ('A'|'a')('N'|'n')('D'|'d')('N'|'n')('O'|'o')('T'|'t');
NOT : ('N'|'n')('O'|'o')('T'|'t');
fragment CHARACTER : ('a'..'z'|'A'..'Z'|'0'..'9');
fragment QUOTE : ('"');
fragment SPACE : (' '|'\n'|'\r'|'\t'|'\u000C');
WS : (SPACE) { $channel=HIDDEN; };
PHRASE : (QUOTE)(CHARACTER)+((SPACE)+(CHARACTER)+)+(QUOTE);
WORD : (CHARACTER)+;
startExpression : andExpression;
andExpression : andnotExpression (AND^ andnotExpression)*;
andnotExpression : orExpression (ANDNOT^ orExpression)*; …Run Code Online (Sandbox Code Playgroud) 我的问题是关于在ANTLRWorks中运行以下语法:
INT :('0'..'9')+;
SEMICOLON: ';';
NEWLINE: ('\r\n'|'\n'|'\r');
STMTEND: (SEMICOLON (NEWLINE)*|NEWLINE+);
statement
: STMTEND
| INT STMTEND
;
program: statement+;
Run Code Online (Sandbox Code Playgroud)
无论选择哪个换行NL(CR / LF / CRLF)或整数,我都可以通过以下输入(以程序作为开始规则)获得以下结果:
“; NL ”或“ 32; NL ”解析没有错误。“;” 或“ 45;” (不包含换行符)将导致EarlyExitException。“ NL ”本身解析没有错误。不带分号的“ 456 NL ”会导致MismatchedTokenException。
我想要的是一个语句以换行符,分号或分号后接换行符来终止,并且我希望解析器在终止符上尽可能多地吃掉连续的换行符,因此“; NL NL NL NL ”只是一个终端,而不是四个或五个。另外,我希望文件结尾的情况也可以是有效的终止,但是我还不知道该怎么做。
那么,这有什么问题,如何使它在EOF终止呢?我对解析,ANTLR和EBNF完全陌生,并且在简单的计算器示例和参考之间的某个水平上,我没有发现太多要阅读的资料(我有The Definitive ANTLR Reference,但它确实是一个参考,前面有一个快速入门,我还没有在ANTLRWorks之外运行过,所以任何阅读建议(除了Wirth的1977 ACM论文)也将有所帮助。谢谢!
大家好,
这可能是这个问题的后续行动:Antlr规则优先事项
我正在尝试为reStructuredText标记语言编写ANTLR语法.
我面临的主要问题是:"如何在不掩盖其他语法规则的情况下匹配任何字符序列(常规文本)?"
让我们举一个带内联标记的段落的例子:
In `Figure 17-6`_, we have positioned ``before_ptr`` so that it points to the element
*before* the insert point. The variable ``after_ptr`` points to the element *after* the
insert. In other words, we are going to put our new element **in between** ``before_ptr``
and ``after_ptr``.
Run Code Online (Sandbox Code Playgroud)
我认为编写内联标记文本的规则很容易.所以我写了一个简单的语法:
grammar Rst;
options {
output=AST;
language=Java;
backtrack=true;
//memoize=true;
}
@members {
boolean inInlineMarkup = false;
}
// PARSER
text
: inline_markup (WS? inline_markup)* WS? EOF …Run Code Online (Sandbox Code Playgroud) 有没有人知道(或有)一个简单的ANTLR 3.4示例main()函数用于C目标?我试图在C或C++中开始使用ANTLR,我看到的所有示例(包括这个)都已过时,例如它们使用的函数不再存在.下载的软件包本身似乎没有任何示例,Wiki上的示例已过时.
我正在为我的编译器类编写一个简单的解析器(只是一个概念证明,我可以让工具工作)并且正在使用带有python绑定的ANTLR.我已经得到了我们琐碎的语法来正确地标记和解析,但我也希望以自定义的方式处理错误.根据ANTLR文档(更具体地说:http://www.antlr.org/wiki/display/ANTLR3/Error+reporting+and+recovery),我可以将以下代码放在我的语法文件中:
@members {
private List<String> errors = new LinkedList<String>();
public void displayRecognitionError(String[] tokenNames,
RecognitionException e) {
String hdr = getErrorHeader(e);
String msg = getErrorMessage(e, tokenNames);
errors.add(hdr + " " + msg);
}
public List<String> getErrors() {
return errors;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,这是一个Java示例,我似乎无法在python中复制(我可以复制代码,但实际上似乎无法让它运行).有谁知道我怎么会这样做?
以下非常简单的示例语法不像我预期的那样(根本没有).
Declaration : 'VAR';
Letter: ('A'..'Z');
message : Declaration Letter+;
Run Code Online (Sandbox Code Playgroud)
我所期望的结果是,任何字母序列都会作为单个字母而形成,并且序列"VAR"将被作为单个标记.
当我查看ANTLRWorks interperter时,我看到以下结果:
VARA解析message -> "VAR", "A"(预期)VARVA不解析(MismatchedTokenException(-1!= 5).词法分析器命中第二个VA并尝试标记Declaration.预期:message -> "VAR", "V", "A"VARVPP解析message -> "VAR", "V", "P", "P"(预期)VARVALL解析message -> "VAR", "VALL".我想帮助理解这种行为,并建议我如何解决这个问题.
特别:
VA为"声明",如果后跟一个字母?V?开头的所有字符串来执行此操作?