我有一个bbcode - > html转换器,它响应textarea中的change事件.目前,这是使用一系列正则表达式完成的,并且存在许多病理情况.我一直想在这个语法上磨铅笔,但不想进入牦牛剃须.但是......最近我开始意识到pegjs,这似乎是PEG解析器生成的一个非常完整的实现.我已经指定了大部分语法,但现在我想知道这是否适合使用完整的解析器.
我的具体问题是:
由于我的应用程序依赖于将我能够转换为HTML并将其余内容保留为原始文本,因此使用可能在语法错误上失败的解析器实现bbcode是否有意义?例如:[url=/foo/bar]click me![/url]一旦输入关闭标记上的结束括号,肯定会成功.但是在此期间用户会看到什么?使用正则表达式,我可以忽略不匹配的东西,并将其视为普通文本以用于预览目的.使用正式语法,我不知道这是否可行,因为我依赖于从解析树创建HTML以及解析失败的原因是什么?
我不清楚应该在哪里进行转换.在正式的基于lex/yacc的解析器中,我将有头文件和符号表示节点类型.在pegjs中,我得到了带有节点文本的嵌套数组.我可以将翻译后的代码作为pegjs生成的解析器的一个动作发出,但是它似乎是一种将解析器和发射器组合在一起的代码气味.但是,如果我打电话PEG.parse.parse(),我会收到这样的话:
Run Code Online (Sandbox Code Playgroud)[
[
"[",
"img",
"",
[
"/",
"f",
"o",
"o",
"/",
"b",
"a",
"r"
],
"",
"]"
],
[
"[/",
"img",
"]"
]
]
给出如下语法:
document
= (open_tag / close_tag / new_line / text)*
open_tag
= ("[" tag_name "="? tag_data? tag_attributes? "]")
close_tag
= ("[/" tag_name "]")
text
= non_tag+
non_tag
= [\n\[\]]
new_line
= ("\r\n" / "\n")
Run Code Online (Sandbox Code Playgroud)
当然,我正在缩写语法,但你明白了.所以,如果你注意到,数组数组中没有上下文信息告诉我我有什么样的节点,即使解析器已经完成了这个,我还是要再次进行字符串比较.我希望在解析期间可以定义回调并使用操作来运行它们,但是网上很少有关于如何做到这一点的信息.
我吠叫错了树吗?我应该回到正则表达式扫描并忘记解析吗?
谢谢
我正在尝试解析逗号分隔的列表。为了简单起见,我只使用数字。这些表达式是有效的:
(1,4,3)
()
(4)
我可以想到两种方法来做到这一点,我想知道为什么失败的例子不起作用。我相信它是正确的 BNF,但我无法让它像 PEG 一样工作。谁能准确解释为什么吗?我试图更好地理解 PEG 解析逻辑。
我正在使用在线浏览器解析器生成器进行测试: https: //pegjs.org/online
这不起作用:
list = '(' some_digits? ')'
some_digits = digit / ', ' some_digits
digit = [0-9]
Run Code Online (Sandbox Code Playgroud)
(实际上,它解析得很好,喜欢 () 或 (1),但不识别 (1, 2)
但这确实有效:
list = '(' some_digits? ')'
some_digits = digit another_digit*
another_digit = ', ' digit
digit = [0-9]
Run Code Online (Sandbox Code Playgroud)
这是为什么?(语法新手看这里)
我正在尝试为PEG.js写一个简单的语法来匹配这样的东西:
some text;
arbitrary other text that can also have µnicode; different expression;
let's escape the \; semicolon, and \not recognized escapes are not a problem;
possibly last expression not ending with semicolon
Run Code Online (Sandbox Code Playgroud)
所以基本上这些是用分号分隔的一些文本.我的简化语法看起来像这样:
start
= flow:Flow
Flow
= instructions:Instruction*
Instruction
= Empty / Text
TextCharacter
= "\\;" /
.
Text
= text:TextCharacter+ ';' {return text.join('')}
Empty
= Semicolon
Semicolon "semicolon"
= ';'
Run Code Online (Sandbox Code Playgroud)
问题是,如果我在输入中放入除分号以外的任何内容,我会得到:
SyntaxError: Expected ";", "\\;" or any character but end of input found.
Run Code Online (Sandbox Code Playgroud)
怎么解决这个?我已经读过PEG.js无法匹配输入结束.
我试图延长的例子语法PEG.js解析所有的4个运营商对我的网上BASIC解释实验的数学表达式:
http://www.dantonag.it/basicjs/basicjs.html
但并非所有表达式都被正确解析.
这是我的PEG语法:
expression = additive
additive = left:multiplicative atag:("+" / "-") right:additive { return {tag: atag, left:left, right:right}; } / multiplicative
multiplicative = left:primary atag:("*" / "/") right:multiplicative { return {tag: atag, left:left, right:right}; } / primary
primary = number / "(" additive:additive ")" { return additive; }
number = digits:[0-9]+ { return parseInt(digits.join(""), 10); }
Run Code Online (Sandbox Code Playgroud)
它解析正确的表达式,如2*3 + 1(给出7),但不是像2-1-1这样的表达式,它给出2而不是0.
你能帮我改进和调试吗?
提前致谢.
编辑:我已经在语法中添加了"数字"规则.是的,我的语法为输出提供了一个类似于解析树的递归结构.
(注:我读过像其他的问题这个,但我一直没能想出解决办法).
我写了这个语法:
start = call
ident = [a-z]+
spaces = [ ]+
call = f:ident spaces g:(call / ident) {
return f + "(" + g + ")";
}
Run Code Online (Sandbox Code Playgroud)
有了这个输入
a b c d
Run Code Online (Sandbox Code Playgroud)
它返回
"a(b(c(d)))"
Run Code Online (Sandbox Code Playgroud)
而且我要
"a(b)(c)(d)"
Run Code Online (Sandbox Code Playgroud)
我认为这个左递归规则可以给我这样的东西,但是PEG.js不支持左递归.
call = f:(call / ident) spaces g:ident {
return f + "(" + g + ")";
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下如何消除左递归?
PS:你可以在在线PEG.js演示中测试这个
如何允许单引号和双引号,以及PEG.js语法定义中的unicode字符?更具体地说,我希望能够捕获可以包含单引号和双引号的字符串(很可能必须被\ _转义)和所有unicode字符.
目前我有以下内容:
_ name:$(PROP_ASCII+) CHAR_SQ val:$(PROP_ASCII_INNER*) CHAR_SQ
这将捕获类似的东西
key'value'
PROP_ASCII*定义为
PROP_ASCII
= [!-&(-<>-~]
PROP_ASCII_INNER
= [ -&(-~]
因此,如果值包含标准ASCII字符并且不包含单引号,则此工作正常且花花公子......但我想支持上面所述的内容,因此这样的事情将成为可能:
key'somé\'value\'?'
思考?
我想知道您如何在 pegjs 中解析注释(例如,la Haskell)。
目标:
{-
This is a comment and should parse.
Comments start with {- and end with -}.
If you've noticed, I still included {- and -} in the comment.
This means that comments should also nest
{- even {- to -} arbitrary -} levels
But they should be balanced
-}
Run Code Online (Sandbox Code Playgroud)
例如,以下不应解析:
{- I am an unbalanced -} comment -}
Run Code Online (Sandbox Code Playgroud)
但是你也应该有一个转义机制:
{- I can escape comment \{- characters like this \-} -}
Run Code Online (Sandbox Code Playgroud)
这有点像解析 s 表达式,但使用 s 表达式,很容易: …
我又回到探索 pegjs 了,显然还没有掌握核心概念。我正在尝试解析以谓词开头的“查询语言”,然后是操作数列表(其中可能包含另一个谓词)。所以一个简单的例子是:
OR(
"string1"
"string2"
)
Run Code Online (Sandbox Code Playgroud)
我希望将上述内容转换为:
{
predicate: "OR",
operands: [
{
type: "STRING",
value: "string1"
},
{
type: "STRING",
value: "string2"
}
]
}
Run Code Online (Sandbox Code Playgroud)
这个查询:
OR(
"string1"
"string2"
AND (
"string4"
"string5"
)
"string3"
)
Run Code Online (Sandbox Code Playgroud)
将成为这个 AST:
{
predicate: "OR",
operands: [
{
type: "STRING",
value: "string1"
},
{
type: "STRING",
value: "string2"
},
{
predicate: "AND"
operands: [
{
type: "STRING",
value: "string4"
},
{
type: "STRING",
value: "string5"
}
]
},
{
type: "STRING",
value: …Run Code Online (Sandbox Code Playgroud) 我在玩PEG.js。
我创建了一些简单的代码来接受 [LettersNumbers] 形式的输入:
这是代码:
start = expression
expression = text + number
text =
a: [a-z]+
{return a.join("");}
number =
b:[0-9]+
{return b.join("");}
Run Code Online (Sandbox Code Playgroud)
这里:在线版本可以测试代码并下载解析器,另外我下载了peg.js本身。
不幸的是,文档非常稀少。我试过:
<script src="peg-0.9.0.min.js"></script>
<script src="parser.js"></script>
<script>
var parser = new PEG;
parser.parse("test123");
</script>
Run Code Online (Sandbox Code Playgroud)
但是得到了这些错误:
未捕获的引用错误:未定义模块未
捕获的类型错误:PEG 不是函数
有人可以为我提供一个工作示例吗?我只需要将生成的 js 文件集成到网站中。
我一直在使用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.
欢迎任何想法!我在这里用完了......
我试图在最后用分号的parathesis之间捕捉一些文本.
例: (in here there can be 'anything' !"#¤);); any character is possible);
我试过这个:
Text
= "(" text:(.*) ");" { return text.join(""); }
Run Code Online (Sandbox Code Playgroud)
但似乎(.*)将包括最后一个); 之前");" 我和我得到错误:
预期");" 或任何字符,但发现输入结束
问题是文本可以包含");" 所以我想要最外面的); 线路结束时决定.
这个正则表达式\((.*)\);做了我想要的,但我怎样才能在PEG.js中做同样的事情呢?我不想在结果中包含外括号和分号.
如果你知道你在做什么= P,这似乎应该很容易
我有一个 AngularJS Web 应用程序。
我想在我的应用程序中使用 peg.js。我刚刚编写了一个 peg.js 语法: CriteriaValue.pegjs 并使用命令行生成了解析器:
pegjs CriteriaValue.pegjs,它生成了 CriteriaValue.js。
有人可以向我解释如何使用解析器吗?
var result = parser.parse('我的字符串'); 不起作用。
我创建了一个plunker: http://plnkr.co/edit/Ae05SeZAjKOQ75B3lvLc ?p=preview
我只是想将这个文本文件分成行并对行进行分类.如果该行以"数量"开头,则下一行是订单商品,直到该行以"GST"开头.
如果该行以"总金额"开头,则这是总金额行.
Business me . ' l Address "rwqagePnnter Pro DemcRa??lp Address "mfgr Eva|uat|on Only Contact line 1 Transaction Number 10006 Issue Date 27/02/201 Time 10:36:55 Salesperson orsa orsa Qty Description Unit Price Total 1 test $120.00 $120.00 GST $10.91 Total Amount $120.00 Cash $120.00 Please contact us for more information about this receipt. Thank you for your business. d . test
请告诉我如何处理PegJS http://pegjs.majda.cz/