跳至正文
Wener Notes

peggy

约 2 分钟阅读
bash
npx -y peggy ./parser.pegjs --format es
flagfor
--allowed-start-rules <rules>默认第一个,逗号分隔指定多个,* for all
--ast输出内部 AST 代替 parser 源码
--cache缓存结果,避免指数级解析时间,但解析会更慢
-d, --dependency <[name:]module>依赖
-D, --dependencies <json>依赖
--dts生成 .d.ts 文件
-e, --export-var <variable>全局变量
--extra-options <options>额外选项 for peg.generate, json object
-c, --extra-options-file <file>额外选项
--format <format>输出格式, amd, commonjs, globals, umd, es
-o, --output <file>输出文件
--plugin插件
-m, --source-map <file>生成 source map
--return-types <JSON object>返回类型, for --dts
-S, --start-rule <rule>指定 start rule
-t, --test <text>测试
-T, --test-file <text>测试
--trace追踪
-w,--watch监听
config.cjs
module.exports = {
  allowedStartRules = ["foo", "bar"],
  format: "umd",
  exportVar: "foo",
  input: "fooGrammar.peggy",
  plugins: [require("./plugin.js")],
  testFile: "myTestInput.foo",
  trace: true,
};
plugin.ts
export function use(config:{parser:Parser,reservedWords,passes:{ [stage: string]: Pass[] } }, options) => {
}
JavaScript
import peggy from 'peggy';
const parser = peggy.generate("start = ('a' / 'b')+");

const parser = peggy.generate([
  { source: 'file1.peggy', text: "numbers = number|.., ','|" },
  { source: 'lib.peggy', text: 'number = n:$[0-9]+ { return parseInt(n, 10) }' },
]);
syntaxfor
"a",'a'匹配 a
'a'i匹配 a 或 A
.匹配任意
!.EOF, EOI, End of Input
[ab]匹配 a 或 b
<rule>匹配 rule
(expr)分组
expr *,expr +,expr ?重复
& exprpositive assertion, lookahead
! exprnegative assertion, lookahead
& { predicate }code block
! { predicate }code block
$ expr-> {return text();} - 语法糖
label: expr定义 label/变量
@(label:)? expr返回 label 作为内容 - pluck
expr1 expr2顺序匹配
expr { action }执行脚本
expr1 / expr2alternate , choose
expr |COUNT|
expr |COUNT,SEQ|
expr |MIN..MAX|
expr |MIN..MAX,SEP|
expr |..|-> expr*
expr |0..|-> expr*
expr |1..|-> expr+
expr |..1|-> expr?
text
// use runtime value as option
start = count:n1 "a"|count|;
n1 = n:$[0-9] { return parseInt(n); };

start = "a"|{ return options.count; }|;
  • min,max,count 可以是 label/变量/code block
text
start = "a"|{ return options.count; }|;
text
// 手写
Values = next:(a:Value _ b:(_ ',' _ next:Value {return next})* ','? {return b?[a,...b]:a})? {return next || []}
// repeat
Values = next:(Value|..,","|)  ','?  {return next || []}

Action Execution Environment

  • () 会形成变量作用域
  • input - parse 参数
  • options - parse 参数
  • error(message,where=location()) - 返回错误
  • expected(message, where=location())
  • location() - {source:options.grammarSource,start:{offset,line,column},end}
  • range() 只返回 offset 对象
  • offset() -> location().start.offset
  • text()
  • reserved/保留关键词
    • count
text
{{
  // 全局初始化 - 定义的方法和变量全局有效
}}

{
  // parser 初始化
}

list = head:word tail:(_ "," _ @word)* { return [head, ...tail]; }
word = $[a-z]i+
_ = [ \t]*
__ "whitespace" // human-readable name
  = [ \t]+
text
// 引入另外的 rule
import {number} from "./number.js"
a = number|1.., "," WS|
WS = [ \t]*
text
list
  = word|.., delimiter| delimiter?
delimiter
  = _ "," _
word
  = $[a-z]i+
_
  = [ \t]*

关联信息

反向链接、本文链接的其他页面和外部资料。

反向链接

  • ohmjs
    笔记 · PEG.js

    harc/ohm · MIT, JS · 133kB, 36kB · 不生成代码,使用类似 Regex - 注语法解析 · 规则复用 - · 语法继承 - · 通过 semantics 添加执行逻辑 - 而不是在 grammar 里嵌入 · 参考

  • Parser Awesome
    笔记 · peggy

    Antlr · Adaptive LL(\) · JavaCC · LL(k) · Grammer · yacc - Yet Another Compiler-Compiler · bison - YACC-compatible Parser Generator

  • PEG.js
    笔记 · peggy

    pegjs/pegjs · 最后更新 2019 - 活跃 fork peggy · JavaScript PEG 语法解析生成器 · 语法 · - 单引号字符串忽略大小写 · - 双引号字符串大小写敏感 · - 用于条件预测 - 类似于前向环视 - Lookahead

站内链接

  • PEG.js
    笔记 · PEG.js

    pegjs/pegjs · 最后更新 2019 - 活跃 fork peggy · JavaScript PEG 语法解析生成器 · 语法 · - 单引号字符串忽略大小写 · - 双引号字符串大小写敏感 · - 用于条件预测 - 类似于前向环视 - Lookahead

参考资料

GitHub6 条
其他外链3 条
最近更新commit 18c892b编辑