μ΄κ²μ λμκ² κ½€ μΌλ°μ μ λλ€. μ΄κΈ°ν λ μ΄λΈμμ μνμ€μ κ΄λ ¨ λΆλΆλ§ λ°ννκ³ μΆμ΅λλ€. μ΄ κ²½μ° AssignmentExpressionλ§ μ¬μ©ν©λλ€.
pattern:Pattern init:(_ "=" _ a:AssignmentExpression {return a})?
μνμ€μμ λ€μ ννμλ§ λ°ννλ @ ννμμ μΆκ°νλ κ²μ΄ μ’μ΅λλ€. λ°λΌμ μμ μλ λ€μκ³Ό κ°μ΅λλ€.
pattern:Pattern init:(_ "=" _ @AssignmentExpression)?
κ΄λ ¨ λ¬Έμ :
λλ μ΄κ²μ΄ μΌλ°μ μΈ λ¬Έμ λΌλ λ° λμν©λλ€. κ·Έλ¬λ ν΄κ²°ν κ°μΉκ° μλμ§ νμ€νμ§ μμ΅λλ€. λ€μ λ§ν΄μ, μΆ©λΆν μμ£Ό λ°μνλμ§, μ루μ μ ꡬννμ¬ PEG.jsμ 볡μ‘μ±μ μΆκ°νλ κ²μ μ λΉνν λ§νΌ κ³ ν΅μ μ λ°νλμ§ μ¬λΆλ νμ€νμ§ μμ΅λλ€.
μ΄ λ¬Έμ λ₯Ό μ΄μ΄λκ³ 1.0.0 μ΄νμ κ³ λ €νλλ‘ νμνκ² μ΅λλ€.
λμ. 1.0μμ μ λ§ λ³΄κ³ μΆμ΅λλ€. λλ @ ꡬ문μ κ·Έλ€μ§ μ΄κ΄νμ§ μμ΅λλ€. IMHOλ μ΄λ κ² νλ κ²μ΄ μ’μ΅λλ€. "μ΅μμ μμ€" λ μ΄λΈμ΄ νλλ§ μλ κ²½μ° ν΄λΉ λ μ΄λΈμ μμμ μΌλ‘ λ°νν©λλ€. λ°λΌμ λ€μ λμ :
rule = space* a:(text space+ otherText)+ newLine* { return a; }
λΉμ μ μ»μ:
rule = space* a:(text space+ otherText)+ newLine*
κ·Έλ¦¬κ³ λ μ΄λΈμ΄ νΉλ³ν μλ―Έ μλ κ²μ΄ μλ κ²½μ°μλ λ€μμ νμ©νμμμ€.
rule = space* :(text space+ otherText)+ newLine*
λ°λΌμ λ μ΄λΈ μ΄λ¦μ μμ ν 건λλλλ€.
@mulderr @ μ°μ°μκ° λ λ«λ€κ³ μκ°ν©λλ€.
@μ κ²½μ° +1 - μ΄κ²μ λ΄ μ½λ μ 체μμ λ§μ΄ λ°λ³΅λ©λλ€.
μ΄ μμ μ μννλ λͺ κ°μ§ κ°κ²°ν λ°©λ²μ λν +1μ λλ€.
μ΄ κ³ ν΅μ ES6μ΄ νμ΄ν ν¨μλ₯Ό μ¬μ©νμ¬ μ²λ¦¬νλ JSμ μ₯ν©ν function
ꡬ문과 μ μ¬ν κ² κ°μ΅λλ€. μλ§λ λΉμ·ν κ²μ΄ μ¬κΈ°μ μ¬μ©λ μ μμ΅λκΉ? λ€μκ³Ό κ°μ κ²:
rule = (space* a:(text space+ otherText) newLine*) => a
μ΄κ²μ λ§€μ° μ μ°νκ³ μ¬μ ν λͺ μμ μ΄λ©°( @wildeyes μ κ΄μ¬μ¬) ꡬ문과 ꡬν λͺ¨λμμ κΈ°λ³Έ JSλ₯Ό
λλ λ€μκ³Ό κ°μ κ²μ μ‘°κΈ μμνμ΅λλ€.
additive = left:multiplicative "+" right:additive {= left + right; }
μ¬κΈ°μ =
(λ¬Έμ μ νμ λν΄ μμ λ‘κ² ν λ‘ ν μ μμ)λ κ³΅λ°±μ΄ μλ λΈλ‘μ 첫 λ²μ§Έ λ¬Έμλ‘ return
.
μ΄λ μ 체 ννμμμλ μλνλ©° λ³ν ν¨μ€λ‘ κ°λ₯ν΄μΌ ν©λλ€.
μμμ΄ μλμ? μ additive = left:multiplicative "+" right:additive { => left + right }
μλκ°μ?
μ΄μ νμ΄ν κΈ°λ₯μ΄ μλνλ λ°©μ( (left, right) => left + right
)μ κ³ λ €ν λ νμ€ν μ§κ΄μ μΌλ‘ λκ»΄μ§ κ²μ
λλ€.
μ€μ λ‘ μ΄ κΈ°λ₯μΌλ‘ κ°μ λ parser.pegjs νμΌμ μμΉμ λν λͺ κ°μ§ μκ° μμ΅λλ€.
μλ₯Ό λ€μ΄:
= head:ActionExpression tail:(__ "/" __ ActionExpression)* {
return tail.length > 0
? {
type: "choice",
alternatives: buildList(head, tail, 3),
location: location()
}
: head;
}
μνμ€μμ ActionExpressionμ μμΉμ μ§κ΄μ μΌλ‘ μ°κ²°λμ§ μμ buildList νΈμΆμ λ§€μ§ λλ² 3 λλ¬Έμ μ·¨μ½ν©λλ€. buildList ν¨μ μ체λ λ κ°μ§ λ€λ₯Έ μμ μ κ²°ν©νμ¬ λ³΅μ‘ν©λλ€. @ μκ³Ό es6 μ€νλ λ ꡬ문μ μ¬μ©νλ©΄ λ€μκ³Ό κ°μ΄ λ κΉλν΄μ§λλ€.
= head:ActionExpression tail:(__ "/" __ @ActionExpression)* {
return tail.length > 0
? {
type: "choice",
alternatives: [head, ...tail],
location: location()
}
: head;
}
μ΄κ²μ κ±°μ ꡬ문μμ μ€νμ΄λ―λ‘ parser.pegjsμμ ActionExpressionμ μμ νλ κ²λ§μΌλ‘ μ΄ κΈ°λ₯μ νμμ μΆκ°ν μ μμμ΅λλ€.
= ExtractSequenceExpression
/ expression:SequenceExpression code:(__ CodeBlock)? {
return code !== null
? {
type: "action",
expression: expression,
code: code[1],
location: location()
}
: expression;
}
ExtractExpression
= "@" __ expression:PrefixedExpression {
return {
type: "labeled",
label: "value",
expression: expression,
location: location()
};
}
ExtractSequenceExpression
= head:(__ PrefixedExpression)* _ extract:ExtractExpression tail:(__ PrefixedExpression)* {
return {
type: "action",
expression: {
type: "sequence",
elements: extractList(head, 1).concat(extract, extractList(tail, 1)),
location: location()
},
code: "return value;",
location: location()
}
}
@ νκΈ°λ²μ μ¬μ©νμ¬ parser.pegjsλ₯Ό λ¨μννλ λ°©λ²μ 보μ¬μ£Όλ μμ§λ₯Ό νμΈνμ΅λλ€.
@ νκΈ°λ²μ μ¬μ©νλ©΄ μνμ€μμ μνλ κ°μ μ½κ² μΆμΆν μ μμΌλ―λ‘ extractOptional, extractList λ° buildList ν¨μλ μμ ν μ κ±°λμμ΅λλ€.
https://gist.github.com/krisnye/a6c2aac94ffc0e222754c52d69e44b83
@krisnye ꡬ문 μ€νμ΄ λ λ§μ΄ μμΌλ©΄ λ€μκ³Ό κ°μ΄ νμλ©λλ€.
https://github.com/polkovnikov-ph/newpeg/blob/master/parse.np
μ΄ κ΅¬λ¬Έ κΈ°λ₯μ ::
λ° #
μ‘°ν©μ μ¬μ©ν μκ°μ
λλ€( #545 μ μ€λͺ
/μ΄μ μ°Έμ‘°).
::
λ°μΈλ© μ°μ°μ#
νμ₯ μ°μ°μ// this is imported into grammar
class List extends Array {
constructor() { this.isList = true; }
}
// grammar
number = _ ::value+ _
value = ::int #(_ "," _ ::int)* { return new List(); }
int = $[0-9]+
_ = [ \t]*
::
λ ννμμ κ²°κ³Όλ₯Ό κ·μΉ κ²°κ³Όλ‘ λ°νν©λλ€.::
λ μ€μ²©λ ννμμ κ²°κ³Όλ₯Ό μνμ€ κ²°κ³Όλ‘ λ°νν©λλ€.::
κ° μ¬μ©λλ©΄ νμλ ννμμ κ²°κ³Όκ° λ°°μ΄λ‘ λ°νλ©λλ€.#
κ° ν¬ν¨λ μ€μ²© μνμ€μ ::
λλ©΄ κ²°κ³Όκ° μμ ββλ°°μ΄λ‘ νΈμλ©λλ€.::
/ #
μ ν¨κ» μ½λ λΈλ‘μ΄ μλ κ²½μ° λ¨Όμ μ€νν λ€μ κ²°κ³Ό push
λ©μλλ₯Ό μ¬μ©ν©λλ€.μ΄λ¬ν κ·μΉμ λ°λΌ 09 , 55, 7
λ₯Ό μμ μμ μμ μμ±λ νμμ μ λ¬νλ©΄ λ€μμ΄ μμ±λ©λλ€.
result = [
isList: true
0: "09"
1: "55"
2: "7"
]
result instanceof Array # true in ES2015+ enviroments
result instanceof List # true
κ·μΉμ λ£¨νΈ μνμ€μμ ::λ ννμμ κ²°κ³Όλ₯Ό κ·μΉ κ²°κ³Όλ‘ λ°νν©λλ€.
μ€μ²©λ μνμ€μμ ::λ μ€μ²©λ ννμμ κ²°κ³Όλ₯Ό μνμ€ κ²°κ³Όλ‘ λ°νν©λλ€.
μ μ΄κ²λ€μ΄ λΆλ¦¬λμ΄ μμ΅λκΉ? μνμ€μ " ::
κ° μνμ€μ μΈμ κ²°κ³Όλ₯Ό μμ±νμ§ μλ μ΄μ λ 무μμ
λκΉ?"
::κ° νλ μ΄μ μ¬μ©λλ©΄ νμλ ννμμ κ²°κ³Όκ° λ°°μ΄λ‘ λ°νλ©λλ€.
그건 λμ μκ°μ΄μΌ. μ΄ κ²½μ° κ΅¬μ νλ κ²μ΄ μ’μ΅λλ€. μ¬λ¬ μ νμ κ°μ λ°°μ΄λ‘ κ²°ν©νλ κ²μ μλ―Έκ° μμ΅λλ€. (ννμ΄μ§λ§ JSμμλ κ±°μ μΈλͺ¨κ° μμ΅λλ€.)
#μ΄ μνμ€μ μ¬μ©λλ©΄ κ²°κ³Όλ Array#κ° λΆλͺ¨μ λ°°μ΄μ μ°κ²°λ©λλ€.
μ΄μ κ·Έκ²μ λμ°ν μκ°μ
λλ€. μ΄κ²μ λΆλͺ
ν λΆνμν { return xs.push(x), xs }
μ κ±°νκΈ° μν κ³€μ§λ¦μ
λλ€. μ΄λ¬ν νΉλ³ν κ²½μ°λ₯Ό λ§λλ κ²μ μλ―Έκ° μμ΅λλ€. 맀κ°λ³μνλ κ·μΉμ μ¬μ©νμ¬ μΌλ°μ μΈ λ°©μμΌλ‘ ν΄κ²°ν μ μκΈ° λλ¬Έμ
λλ€. μ°μ°μμ μ¬μ©ν λ¨μΌ λ¬Έμ μνμ€λ λ§μ§ μμΌλ©° λλΉν΄μλ μλ©λλ€.
κ·μΉμ ::/#μ ν¨κ» μ½λ λΈλ‘μ΄ μλ κ²½μ° λ¨Όμ μ€νν λ€μ κ²°κ³Ό νΈμ λ©μλλ₯Ό μ¬μ©ν©λλ€.
λ°λΌμ f = ::"a" { return "b" }
λ κ²°κ³Όμ μΌλ‘ ["a", "b"]
λ₯Ό κ°μ ΈμΌ ν©λκΉ?
ν΅κ³Ό 09 . 55: 7μ μμ μμμ μμ±λ νμμ λμ νλ©΄ λ€μμ΄ μμ±λ©λλ€.
κ·Έλ μ§ μμ΅λλ€. μΈκΈλ .
λλ :
. μ€λͺ
λ λμμ΄ κ²°κ³Όλ₯Ό μμ±νλ λ°©μλ μ μ μμ΅λλ€.
μ«μ = _ ::κ°+ _
λν _
λ₯Ό μ¬μ©ν΄μλ μ λ©λλ€. ν ν°μ μ€λ₯Έμͺ½ λλ μΌμͺ½μΌλ‘ μ΄λνλ©° λ¬Έλ²μ μν΄ ν λ² μ νλ μͺ½μ
λλ€. μ€λ₯Έμͺ½μ μλ κ²½μ° κΈ°λ³Έ κ·μΉλ _
μμν΄μΌ νλ©° κ·Έ λ°λμ κ²½μ°λ λ§μ°¬κ°μ§μ
λλ€.
start = _ value
value = ::int #("," _ ::int)* { return new List(); }
number = ::$[0-9]+ _
_ = [ \t]*
JavaScript μμ μμ ꡬνλ ν΄λμ€μ μ(μ€μ ꡬνμ΄ μλ):
ClassMethod
= head:FunctionHead __ params:FunctionParameters __ body:FunctionBody {
return {
type: "method",
name: head[ 1 ],
modifiers: head[ 0 ],
params: params,
body: body
};
}
// `::` inside the zero_or_more "( ... )*" builds an array as we want,
// so this rule returns `[FunctionModifier[], Identifier]` as expected
MethodHead = (::MethodModifier __)* ("function" __)? ::Identifier
// https://github.com/tc39/proposal-class-fields#private-fields
MethodModifier
= "#"
/ "static"
/ "async"
FunctionParameters
= "(" __ head:FunctionParam tail:(__ "," __ ::FunctionParam)* __ ")" {
// due to `::`, tail is `FunctionParam[]` instead of `[__, "", __, FunctionParam][]`
return [ head ].concat( tail );
}
/ "(" __ ")" { return []; }
FunctionParam
= name:Identifier value:(__ "=" __ ::Expression)? {
return { name, value };
}
FunctionBody = "{" __ ::SourceElements? __ "}"
μ μ΄κ²λ€μ΄ λΆλ¦¬λμ΄ μμ΅λκΉ? μνμ€μ
::
μνμ€μ μΈμ κ²°κ³Όλ₯Ό μμ±νμ§ μλ μ΄μ λ 무μμ λκΉ?"
κ°μκ±° μλκ°μ? MethodHead
, FunctionParam
λ° FunctionBody
μ κ°μ λ€μν μ¬μ© μ¬λ‘μ κ²°κ³Όλ₯Ό μ½κ² μ΄ν΄ν μ μλλ‘ λ λͺ
ννκ² λ§λ€μμ΅λλ€.
μ¬λ¬ μ νμ κ°μ λ°°μ΄λ‘ κ²°ν©νλ κ²μ μλ―Έκ° μμ΅λλ€. (ννμ΄μ§λ§ JSμμλ κ±°μ μΈλͺ¨κ° μμ΅λλ€.)
λ΄ μ견μΌλ‘λ AST(μμ±λ νμμ κ°μ₯ μΌλ°μ μΈ κ²°κ³Ό)λ₯Ό μμ±ν λ λ€μκ³Ό κ°μ΄ μμ±νλ λμ MethodHead
μ κ°μ μ¬μ© μ¬λ‘λ₯Ό λ¨μνν©λλ€.
MethodHead
= modifiers:(::MethodModifier __)* ("function" __)? name:Identifier {
return [ modifiers, name ];
}
μ’ λ μκ°ν΄ λ³Έ κ²°κ³Ό, μ μ€ μΌμ΄μ€λ₯Ό λ¨μννκΈ°λ νμ§λ§ κ°λ°μκ° μ€μλ₯Ό ν κ°λ₯μ±(λ¬Έλ²μ ꡬννλ λ°©μμ΄λ κ²°κ³Όκ° μ‘μ
μΌλ‘ μ²λ¦¬λλ λ°©μ)λ μ΄λ¦¬λ―λ‘ λ€μκ³Ό κ°μ΄ μκ°ν©λλ€. multipleSingleReturns
(κΈ°λ³Έκ°: false
)μ κ°μ μ΅μ
λ€μ μλ μ¬μ© μ¬λ‘κ° μ¬κΈ°μμ κ°μ₯ μ’μ μ‘°μΉκ° λ κ²μ
λλ€(μ΄ κΈ°λ₯μ΄ κ΅¬νλ κ²½μ°).
#μ΄ μνμ€μ μ¬μ©λλ©΄ κ²°κ³Όλ Array#κ° λΆλͺ¨μ λ°°μ΄μ μ°κ²°λ©λλ€.
μ΄μ κ·Έκ²μ λμ°ν μκ°μ λλ€. μ΄κ²μ λΆλͺ ν λΆνμν { return xs.push(x), xs }
λν FunctionParameters
μ κ°μ λ³΄λ€ μΌλ°μ μΈ μ¬μ© μ¬λ‘μμ λ€μκ³Ό κ°μ΄ μμ±νλ κ²μ΄ λ μ’μ΅λλ€.
// should always return `FunctionParam[]`
FunctionParameters
= "(" __ ::FunctionParam #(__ "," __ ::FunctionParam)* __ ")"
/ "(" __ ")" { return []; }
맀κ°λ³μνλ κ·μΉμ μ¬μ©νμ¬ μΌλ°μ μΈ λ°©μμΌλ‘ ν΄κ²°ν μ μμ΅λλ€.
λμ€μ κ³μ μ§ννλ λ°©λ²μ μμ§ μ λͺ¨λ₯΄κΈ° λλ¬Έμ 맀κ°λ³μνλ κ·μΉ μ μ λ¨μΌ λ°ν κ°μ ꡬνν΄μΌ νλ€κ³ μκ°ν©λλ€(ν
νλ¦Ώμ μ¬μ©νλ κ²μ μ’μνμ§λ§ rule < .., .. > = ..
λ₯Ό μ¬μ©νλ©΄ PEG.js λ¬Έλ²μ΄λ―λ‘ μ’ λ μ λ§λλ‘ μ½κ°μ ꡬ문 λ³κ²½μ μκ°νλ €κ³ ν©λλ€.) νμ§λ§ 그건 λ³κ°μ λ¬Έμ μ
λλ€.
μ°μ°μμ μ¬μ©ν λ¨μΌ λ¬Έμ μνμ€λ λ§μ§ μμΌλ©° λλΉν΄μλ μλ©λλ€.
λ§λ λ§μ΄μ§λ§ νμ¬μ μν© μμ²΄κ° μ΄μ κ°μ λ μ¬μ©νμ§ μμΌλ©΄ κ·Έκ²λ λμ©λλ€.
μ μ²λ¦¬ μ§μλ¬Έμ ꡬννλ μΌλΆ μΈμ΄μμ νμ₯ μ°μ°μλ‘ μ¬μ©λλ€λ κ²μ κΈ°μ΅ν ν μ΄ μ¬μ© μ¬λ‘μ #
λ₯Ό μ¬μ©νλ €κ³ μκ°νμ΅λλ€. μ΄κ²μ΄ λ³Έμ§μ μΌλ‘ μ΄ μ¬μ© μ¬λ‘κ° μ¬κΈ°μμ λ€λ£¨λ λ΄μ©μ
λλ€.
λ°λΌμ
f = ::"a" { return "b" }
λ κ²°κ³Όμ μΌλ‘["a", "b"]
λ₯Ό κ°μ ΈμΌ ν©λκΉ?
μ½λ λΈλ‘μ΄ ν¬ν¨ λ κ°μ²΄μ κ°μ λ°°μ΄μ λ°ν νμ κ³Όμ° μλ push
λ°©λ² (κ° λ μ μλλ‘ f = ::"a" { return [ "b" ] }
λ³΅κ· [ "b", "a" ]
κ²°κ³Ό) λ°λΌμ μ΄λ μ΄λΏλ§ μλλΌ μ μ¬ν λ°©μμΌλ‘ μλνλλ‘ κ΅¬νλ λμΌν λ°©λ²μ΄ μλ μ¬μ©μ μ μ λ
Έλμ νΈμν μ μμ΅λλ€. κ·Έκ²μ μ½μ ν μ΄κ²μ΄ μ΄λ»κ² μκ°μ 첫 λ²μ§Έ κΈ°μ°¨μλκ°λ₯Ό 보μμ λ μ΄κ²μ΄ pushSingleReturns
μ κ°μ μ΅μ
λ€μ μλμ§ μ΄ν΄νλ κ²μ΄ λ false
(κΈ°λ³Έκ°)μΈ κ²½μ° λ¨μΌ λ°ν κ°μ ν¬ν¨νλ μνμ€ λ€μ μ½λ λΈλ‘μ΄ μμΌλ©΄ μ€λ₯κ° λ°μν©λλ€.
ν΅κ³Ό 09 . 55: 7μ μμ μμμ μμ±λ νμμ λμ νλ©΄ λ€μμ΄ μμ±λ©λλ€.
κ·Έλ μ§ μμ΅λλ€.
.
λλ:
μΈκΈλμ§ μμμ΅λλ€.
μ£μ‘ν©λλ€. μ£Όμ΄μ§ μμ λ₯Ό λ€μ μμ±ν λ λ¨κ²¨μ§ μ€μμμ΅λλ€.
λν
_
λ₯Ό μ¬μ©ν΄μλ μ λ©λλ€. ν ν°μ μ€λ₯Έμͺ½ λλ μΌμͺ½μΌλ‘ μ΄λνλ©° λ¬Έλ²μ μν΄ ν λ² μ νλ μͺ½μ λλ€. μ€λ₯Έμͺ½μ μλ κ²½μ° κΈ°λ³Έ κ·μΉλ_
μμν΄μΌ νλ©° κ·Έ λ°λμ κ²½μ°λ λ§μ°¬κ°μ§μ λλ€.
λλ μ΄κ²μ΄ λ¨μ§ μ νΈλμ λ¬Έμ λΌκ³ μκ°ν©λλ€ :smile:, λΉλ‘ μ΄ μλ₯Ό μ΄ν΄νλ κ²μ΄ λ μ¬μ μ κ²μ΄λΌκ³ μκ°νμ§λ§:
number = _ ::value+ EOS
...
EOS = !.
μ€λͺ λ λμμ΄ κ²°κ³Όλ₯Ό μμ±νλ λ°©μλ μ μ μμ΅λλ€.
μ΄ μ λ°μ΄νΈλ λκΈμ΄ λ΄κ° λ§νλ €λ λ΄μ©μ μ΄ν΄νλ λ° λμμ΄ λ©λκΉ? κ·Έλ μ§ μμ κ²½μ° μ΄ν΄νμ§ λͺ»νλ λΆλΆμ΄ 무μμΈμ§ μ΄ν΄νμμμ€.
μ₯μλ³λ‘ μ 곡λλ λ³κ²½ μ¬νμ΄ κ·Ήλλ‘ λͺ ννμ§ μκ³ μΆκ° μ€λ₯μ μμΈμΌ λΏμ΄λΌλ @polkovnikov-phμ λμν©λλ€.
#μ΄ μνμ€μ μ¬μ©λλ©΄ κ²°κ³Όλ Array#κ° λΆλͺ¨μ λ°°μ΄μ μ°κ²°λ©λλ€.
start = #('a')
λ¬Έλ²μμ 무μμ λ°νν΄μΌ ν©λκΉ? λ΄κ° μ΄ν΄νλ ν, κ·Έλ λ°°μ΄μ λ³ν©νκΈ° μν ꡬ문 μ€νμ΄ μ΄λ»κ² λλμ§ μκ°νμ΅λλ€. μ΄ μ°μ°μκ° νμνλ€κ³ μκ°νμ§ μμ΅λλ€. κ°μ₯ λΆλͺ
ν μ©λ(κ΅¬λΆ κΈ°νΈκ° μλ λ©€λ² λͺ©λ‘ νν)λ₯Ό μ¬μ©νλ €λ©΄ νΉμ ꡬ문μ λ§λλ κ²μ΄ μ’μ΅λλ€(#30 λ° λ΄ ν¬ν¬, https://github.com/Mingun/pegjs/commit/db4b2b102982a53dbed1f579477c85c06f8b92e6 μ°Έμ‘°).
κ·μΉμ ::/#μ ν¨κ» μ½λ λΈλ‘μ΄ μλ κ²½μ° λ¨Όμ μ€νν λ€μ κ²°κ³Ό νΈμ λ©μλλ₯Ό μ¬μ©ν©λλ€.
λ§€μ° λΆλΆλͺ ν νλμ λλ€. λ¬Έλ² μμ€μ μμ μ ννμ λ€μ μμΉνλ©° μΌλ°μ μΌλ‘ ννμ ꡬ문 λΆμ νμ νΈμΆλ©λλ€. κ·Έλ¦¬κ³ κ°μκΈ° μ΄λ»κ² λ ꡬ문 λΆμ μ μ νΈμΆλκΈ° μμν©λλ€. λ μ΄λΈμ μ΄λ»κ² μλν©λκΉ?
λλ¨Έμ§ 3μ μ λΉμ μ΄ κ·Έλμ λ μ€λͺ νμ¬ κ·Έλ€μ λͺ νν κ°κ°μ΄ νμΆνκΈ° μμνμ΅λλ€. μ€λͺ μ 첫 λ²μ§Έμ λ λ²μ§Έ κ²½μ°λ₯Ό ꡬλΆνλ μ΄μ κ° @polkovnikov-phμ μΌλ§λ μ ννκ² κΈ°λ‘λμμ΅λκΉ? λ κ°μ§ κ°λ¨ν κ·μΉλ§ μ€νλ©λλ€.
::
(μμ§ν λ§ν΄μ, λλ μ΄ μΊλ¦ν°μ μ νμ΄ λ§μμ λ€μ§ μμ΅λλ€. λ무 μλλ½μ΅λλ€) ννμμ΄ μ΄ λ¬Έμλ‘ νμλ sequence
λ
Έλ μμμμ μ΄ λ¬Έμκ° λ°νλλ€λ μ¬μ€λ‘ μ΄μ΄μ§κΈ° μ μμ:
start = 'a' 'b' 'c'; // => ['a', 'b', 'c']
start = ::'a' 'b' 'c'; // => 'a'
start = ::'a' 'b' ::'c'; // => ['a', 'c']
ν° μλ λ΄κ° ::
μμ λ³Ό κ²μΌλ‘ μμλλ κ²μ μ νν μ€λͺ
νκ³ λͺ¨νΈν μ¬μ© μ¬λ‘( #
, μ¬λ¬ ::
)λ₯Ό μ€λͺ
νμ§ μμ΅λλ€.
κ°μκ±° μλκ°μ?
κ·Έκ² λ΄κ° λ¬Όμ΄λ³Έκ±°μΌ. μΌλ°μ μΈ λ°©μμ μ€λͺ μ μΌλ°μ μΌλ‘ λ μ μ©ν©λλ€. μλνλ©΄ λ μκ° κ·Έκ²μ΄ μ€μ λ‘ κ°μ κ²μμ νμ νκ² νκΈ° λλ¬Έμ λλ€. μ€λͺ ν΄μ£Όμ μ κ°μ¬ν©λλ€. :)
μ μκ°μλ MethodHeadμ κ°μ μ¬μ© μ¬λ‘λ₯Ό λ¨μνν κ²μ λλ€.
κ·Έλ¬λ λμ κ°μ²΄λ₯Ό μμ±νμ§ μλ μ΄μ λ 무μμ
λκΉ? νκΈ°λ²μ modifiers:
λ° name:
κ° μμ΅λλ€. κ²°κ³Ό JS κ°μ²΄μ κ·Έλλ‘ λμμμ€. κ·Έλ¬λ©΄ λ©μ§ κ²μ
λλ€.
κ·Έκ²μ λν κ°λ°μκ° μ€μλ₯Ό ν κ°λ₯μ±μ μ΄μ΄μ€λλ€(κ·Έλ€μ΄ λ¬Έλ²μ ꡬννλ λ°©μμ΄λ μ‘°μΉμ μν΄ κ²°κ³Όκ° μ²λ¦¬λλ λ°©μ)
μ²μμλ μ΄κ²μ λν΄ κΈμ μΈ μμ μ΄μμ§λ§, λμ€μλ μ΄λ €μ΄ λ
Όκ±°κ° μΆ©λΆνμ§ μλ€κ³ κ²°μ νμ΅λλ€. λμΌν μμ€μ μνμ€μμ μ¬λ¬ ::
λ₯Ό νμ©νμ§ μλ κ²μ΄ μ’μ΅λλ€(νλκ·Έκ° μλ κ²½μ°μλ μ μΈ).
λν λ€μκ³Ό κ°μ΄ μμ±νλ κ²μ΄ λ μ’μ FunctionParametersμ κ°μ λ³΄λ€ μΌλ°μ μΈ μ¬μ© μ¬λ‘μ λμμ΄ λ©λλ€.
κ·Έλ¬λ κ·Έκ²μ κ°μ κ²μ
λλ€. μ λ§ μ’μ ꡬ문μ inter(FunctionParam, "," __)
μ
λλ€.
inter a b = x:a xs:(b ::a)* { return xs.unshift(x), xs; }
rule < .., .. > = .. PEG.js λ¬Έλ²μ λ§μ λ Έμ΄μ¦λ₯Ό μΆκ°νλ κ² κ°μ΅λλ€
μ¬λλ€μ <...>
κ° μ νμ μ¬μ©λκΈ°λ₯Ό κΈ°λνμ§λ§ μ΄ κ²½μ° μΈμλ μ νμ΄ μλλλ€. κ°μ₯ μ’μ λ°©λ²μ μΆκ° λ¬Έμκ° μ ν μλ Haskell λ°©λ²μ
λλ€(μμ inter
μ°Έμ‘°). ;
μλ΅λ PEG.js λ¬Έλ²μμ μ΄κ²μ΄ μ΄λ»κ² μνΈ μμ©νλμ§ μ λͺ¨λ₯΄κ² μ΅λλ€. f a b = ...
κ° μ΄μ νμ (λΆλΆμ μΌλ‘) ν¬ν¨λλ κ²½μ°κ° μμ μ μμ΅λλ€.
μ μ²λ¦¬ μ§μλ¬Έμ ꡬννλ μΌλΆ μΈμ΄μμ νμ₯ μ°μ°μλ‘ μ¬μ©
μ, νμ§λ§ μ€λ§νΈνκ² μ¬μ©νλ κ²μ΄ μ’μ΅λλ€. λ°°μ΄μ λν΄ μ μλ push
μμ
λμ κ°μ²΄μ λν Object.assign
μμ
λλ λΉ λ¬Έμμ΄( eps
)κ³Ό μΌμΉνμ§λ§ λ°ννλ μμ
μΌλ‘ μ¬μ©ν©λλ€. κ·Έ μ£Όμ₯. μλ₯Ό λ€μ΄,
f = type:#"ident" name:$([a-z]i [a-z0-9_]i+)
"abc"
μ
λ ₯μ λν΄ {type: "ident", name: "abc"}
λ₯Ό λ°νν©λλ€.
μλμ€, μ½λ λΈλ‘μ νμκ° νΈμ λ©μλλ₯Ό ν¬ν¨νλ λ°°μ΄κ³Ό μ μ¬ν κ°μ²΄λ₯Ό λ°νν κ²μΌλ‘ μμνκΈ° λλ¬Έμ(λ°λΌμ f = ::"a" { return [ "b" ] } λ°ν [ "b", " a" ] κ²°κ³Ό),
μ€_μ€
μ΄κ±΄ μ λ§ μ·¨ν₯μ λ¬Έμ μΈ κ² κ°μμ
λΏλ§ μλλΌ μ±λ₯λ κ·Έλ μ΅λλ€. λͺ¨λ ν ν°μ μμͺ½μ _
μλ κ²½μ° κ³΅λ°± λ¬Έμ μνμ€λ ννμλ§ μΌμΉνκ³ _
μμλ μ무κ²λ μΌμΉνμ§ μμ΅λλ€. parse$_
λν μΆκ° νΈμΆμ μκ°μ΄ μ‘°κΈ λ 걸립λλ€. λν _
κ° λ λ°° λ λ§κΈ° λλ¬Έμ μ½λκ° λ κΉλλ€.
@Mingun @futagoza λ λμμΈ κ³΅κ°μ νꡬνλ€κ³ μκ°ν©λλ€. κ·Έκ²μ μ’μ μΌμ λλ€. νΉν κ·Έκ²μ΄ 곡κ°λμ΄ μκ³ μ°λ¦¬κ° λμνμ§ μμ κΈ°νκ° μλ κ²½μ°μ κ·Έλ μ΅λλ€. :)
κ°μ₯ μ€μν κ²μ "μ"λΌκ³ 묻λ κ²μ΄ μλλΌ "μλμ€! κ·Έλ μ§ μμ΅λλ€!"λΌκ³ λ§νλ κ²μ λλ€.
f = type:#"ident" name:$([a-z]i [a-z0-9_]i+)
λ"abc"
μ λ ₯μ λν΄{type: "ident", name: "abc"}
λ₯Ό λ°νν©λλ€.
μλ, νν. κ·Έ ꡬ문μ _wayyy_ λ무 λ§μ μ μ λλ€.
μλ μ μλ @
μ°μ°μλ μλ κ·Έλλ‘ μλ²½ νλ€κ³ μκ°ν©λλ€. λ무 λ§μ μκ° λλ μνμ€ λ¬Έμ μ λΆλͺμΉ©λλ€.
sequence
= first:element rest:(whitespace next:element {return next;})*
{
return [first].concat(rest);
}
;
_κ·Έλ°_ _ λ°λ³΅ν΄μ μ λ ₯νλ κ²μ κ³ ν΅μ€λ½μ΅λλ€. νΉν κ·Έλ³΄λ€ λ 볡μ‘ν κ²½μ°μλ λμ± κ·Έλ μ΅λλ€.
κ·Έλ¬λ @
μ°μ°μλ₯Ό μ¬μ©νλ©΄ μμ λ΄μ©μ λ€μκ³Ό κ°μ΄ κ°λ¨ν΄μ§λλ€.
sequence = first:element rest:(whitespace @element)* { return [first].concat(rest); };
https://github.com/pegjs/pegjs/issues/235#issuecomment -66915879 λλ https://github.com/pegjs/pegjs/issues/235#issuecomment -67544080μ μ¬μ©νλ©΄ λ€μκ³Ό κ°μ΄ μΆκ°λ‘ μΆμλ©λλ€.
sequence = first:element rest:(whitespace @element)* => [first].concat(rest);
/* or */
sequence = first:element rest:(whitespace @element)* {=[first].concat(rest)};
... 첫 λ²μ§Έλ λ΄κ° λ§€μ° λΆλΆμ μ λλ€.
μ΄κ²μ λ¬μ±νκΈ° μ¬μ΄ μ΄μ λ²μ κ³Ό νΈνλλ λ³κ²½μΈ κ²μ²λΌ 보μ λλ€(λκ΅°κ°κ° μ΄λ―Έ μνν κ²μΌλ‘ 보μ λλ€).
μ¬μ€ μ μ°©κ°μ΄ μλλΌλ©΄ μ¬μν μΆ©λμΌ μλ μμ΅λλ€. 0.11.0 @futagozaμ λν΄ μκ°ν μ μλ κ²μ λλ€.
λ°©κΈ λ§μ€ν°μ μΆκ°νμ΅λλ€. ::
λ₯Ό λ€μ€ λ½κΈ°μ μ¬μ©νκ³ @
λ₯Ό λ¨μΌ λ½κΈ°μ μ¬μ©ν κ³νμ΄μμ§λ§ λ μ΄λΈκ³Ό ν¨κ» ::
μ¬μ©νλ κ²μ΄ 보기μ λ무 μΆνκ³ νΌλμ€λ¬μμ κ·Έ μμ΄λμ΄λ₯Ό μ€λ¨νμ΅λλ€ π
λλ μ΄κ²μ μ μ λμ μ€μ€λ‘ ꡬννκΈ° μμνμ§λ§ μ§κΈκΉμ§ (λμ #579λ₯Όν΄μΌ ν λ π) λ°μ΄νΈ μ½λ μμ±κΈ°λ₯Ό Mingunμ ꡬνμ κΈ°λ°νμ΅λλ€ (https://github.com/Mingun/pegjs/commit/1c1c852bae91868eaa90d9bd9f7e4f722ea6435 )
https://pegjs.org/development/try (μ¨λΌμΈ νΈμ§κΈ°μ΄μ§λ§ PEG 0.11.0-dev μ¬μ©)μμ μλν΄ λ³Ό μ μμ΅λλ€.
μ±μ€λ¬μ΄ μ ν μκ°, λ°°νΈλ§¨. λ©μ§ μμ
@futagoza , μ΄κ²μ μλ²½νκ² μλνμ΅λλ€. λλ¨ν κ°μ¬ν©λλ€. μ΄κ²μ μ΄λ―Έ npmμ dev
νκ·Έλ‘ μΆμλμμ΅λκΉ? λλ κ·Έκ²μΌλ‘ ν
μ€νΈλ₯Ό μμνκ³ μΆμ΅λλ€.
κΈ°λ³Έ λ¬Έλ²μΌλ‘ μλνκ³ μΆμ μ¬λμ μν΄ μ΄ κ°μμ§λ₯Ό κ±°κΈ°μ λ£κ³ "abcd"
μ κ°μ μ
λ ₯μ μ 곡νμμμ€.
foo
= '"' @$bar '"'
;
bar
= [abcd]*
;
μ΄κ²μ μ΄λ―Έ npmμ dev νκ·Έμ 릴리μ€λμμ΅λκΉ?
μλ νμΈμ, μ΄κ²μ es6μ΄ μμΌλ©΄ μ¬λΌμ§λ λ¬Έμ μ€ νλμ΄λ©°, κ·Έ μ΄νλ‘ es6μ μΆκ°λ λ€λ₯Έ κΈ°λ₯μ μν΄ ν΄λΉ λ¬Έμκ° νμν©λλ€. μ΄λ―Έ ν μ μλ μΌμ μ°μ°μλ₯Ό μΆκ°νλ κ²μ λ§€μ° λΉμμ°μ μ λλ€.
μ΄ ν°μΌμ΄ λ³ν©λμμ΅λλ€.
pattern:Pattern init:(_ "=" _ <strong i="7">@a</strong>:AssignmentExpression)?
λͺ¨λ μ¬λμ΄ λ³Έμ§μ μΌλ‘ μ΄ν΄νκ³ νμμ λ€λ₯Έ λΆλΆμ΄ μλ£λλ©΄ 무λ£λ‘ μ 곡λλ es6μ λμΌν λ΄μ©μ λ€μκ³Ό κ°μ΅λλ€.
pattern:Pattern init:(_ "=" _ a:AssignmentExpression)? => a
λ¬Έμ λ ν μ€νΈνμ λ μ΄ pluck ꡬνμ΄ λ²κ·Έκ° μλ κ² κ°μΌλ©° λ¬Όλ‘ λ¦΄λ¦¬μ€λμ§ μμ λΆκΈ°μμ μμ λμκΈ° λλ¬Έμ λ«ν κ²μΌλ‘ νμλλ€λ κ²μ λλ€.
μ΄ λ¬Έμ κ° λ¦΄λ¦¬μ€λ λ²μ μμ μμ λ λκΉμ§ @futagoza λ₯Ό λ€μ μ¬μμμ€.
κ°μ₯ μ μ©ν λκΈ
https://www.npmjs.com/package/pegjs/v/0.11.0-dev.325