我想解析字符串,以便检查它们是否具有指定的语法.
例:
Str = Z344-R565l t
Run Code Online (Sandbox Code Playgroud)
在这里,我的要求是Z应该有一个数字之后,之后a -和之后R应该有一个数字l,然后是一个空格,然后是最后一个t.
如果除此之外的任何事情应该是一个错误.
我必须解析许多不同类型的语法.如果为每种语法类型编写一个函数,我会很尴尬.我听说yacc或lex可以解决这个问题.
任何人都可以对我的问题有所了解吗?
我想解析以下内容:
name:name
Run Code Online (Sandbox Code Playgroud)
名称以alnum开头和结尾,并且可以包含alnum和space内部的任意组合.它们也可能是空白的.我的规则是:
identifier = alnum (space* alnum)*;
name = (identifier | zlen) >sName $pName %fName;
Run Code Online (Sandbox Code Playgroud)
名称可以用冒号分隔,也可以选择名称和冒号之间的空格.我的规则是:
sep = space* ":" space*;
main := name sep name;
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为显然是space*在identifier和space*中sep混淆解析器.我最终fName在名称的每个空间中执行了操作.
如果我将sep更改为:
sep = ":";
Run Code Online (Sandbox Code Playgroud)
一切都很好.如何修改这些规则以使解析器完成我想要的操作?
这个问题的源代码:https://gist.github.com/1661150
我一直在使用PEG.js版本0.6.1使用Maven插件(即从Java代码调用PEG.js)构建解析器,但是现在在尝试升级到新版本时,它失败并显示错误消息:
sun.org.mozilla.javascript.internal.EcmaError: SyntaxError: missing ; before statement (#3213(eval)#1) in #3213(eval) at line number 1
调试时我注意到PEG.buildParser()函数调用出来的解析器看起来语法错误,当然从浏览器调用它时不会发生.
这是我如何称呼它:
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine jsEngine = manager.getEngineByName("JavaScript");
jsEngine.eval(new InputStreamReader(this.getClass().getResourceAsStream(PEGJS_LIB)));
Invocable invok = (Invocable) jsEngine;
Object peg = jsEngine.get("PEG");
invok.invokeMethod(peg, "buildParser", grammarSource);
Run Code Online (Sandbox Code Playgroud)
其中,grammarSource在我的测试情况下,是作为基本语法的网站例如,和PEGJS_LIB = peg-0.7.0.js.
欢迎任何想法!我在这里用完了......
我知道如何使用SKIP声明跳过这些注释,但我需要做的就是获取C源并输出相同的源而不带注释.
所以我声明了一个令牌<GENERIC_TEXT:(〜[])+>,它被复制到输出中,并且不会跳过注释.我怀疑这个令牌为自己获取所有输入.
有谁可以帮助我吗?
谢谢
我有以下(严重剥离)快乐的语法
%token
'{' { Langle }
'}' { Rangle }
'..' { DotDot }
'::' { ColonColon }
'@' { At }
mut { Mut }
ident { Ident }
%%
pattern
: binding_mode ident at_pat { error "identifier pattern" }
| expr_path { error "constant expression" }
| expr_path '{' '..' '}' { error "struct pattern" }
binding_mode
: mut { }
| { }
at_pat
: '@' pat { }
| { }
expr_path
: expr_path '::' ident …Run Code Online (Sandbox Code Playgroud) 出于性能原因,我将C#库移植到C++.在正常操作期间,此库需要解析大约150'000个数学表达式(想想excel公式),平均长度小于150个字符.
在C#版本中,我使用GOLD解析器生成解析代码.它可以在一秒钟内解析所有150'000个表达式.
因为我们正在考虑扩展我们的语言,所以我认为转向C++可能是改为ANTLR的好机会.我已将(简单)语法移植到ANTLR并从中生成C代码.解析150'000表达式需要12秒,因为对于每个表达式,我需要创建一个新的ANTL3_INPUT_STREAM,令牌流,词法分析器和解析器 - 至少在版本3.4中,没有办法重用它们.
我很感激有人可以给我一个推荐使用的内容 - GOLD当然是一个选项,虽然生成C++或C代码似乎比C#变种复杂得多.我的语法是LALR和LL(1)兼容.最重要的是解析小输入的性能.
我正在尝试使用antlr 4解析文件,我无法理解为什么不能解析多于一位的整数(第79:44行在输入'17'处没有可行的替代方案).
这是有趣的语法http://pastebin.com/rxktvUBi
这是int的定义
fragment DIGIT : [0-9] ;
integer : DIGIT+ ;
Run Code Online (Sandbox Code Playgroud)
这根本不起作用.这个版本
integer : ('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9')+ ;
Run Code Online (Sandbox Code Playgroud)
仅适用于1位整数.
这是未解析的行的示例
struct p_77_bound_17_or: ((bound(MEK)<=17) | (bound(MEKPP)<=17))
Run Code Online (Sandbox Code Playgroud)
问题在于
simple_expression:
(integer)+
Run Code Online (Sandbox Code Playgroud)
请注意,如果我使用标识符
ID:
('a'..'z'|'A'..'Z'|'0'..'9'|'_')+;
identifier: ID;
Run Code Online (Sandbox Code Playgroud)
而不是整数
simple_expression:
identifier
Run Code Online (Sandbox Code Playgroud)
这样可行.
为什么?任何的想法?
parsing ×3
c++ ×2
antlr ×1
antlr4 ×1
c ×1
comments ×1
gold-parser ×1
grammar ×1
happy ×1
haskell ×1
integer ×1
java ×1
javacc ×1
javascript ×1
pegjs ×1
performance ×1
ragel ×1
rhino ×1
scriptengine ×1