Javascript PegJS成员表达式解析

Javascript PegJS成员表达式解析,javascript,pegjs,Javascript,Pegjs,我目前正在制作一种编程语言,并使用PegJS进行解析。这是我的语法: Start = __ program:Program __ { return program; } // ----- A.1 Lexical Grammar ----- SourceCharacter = . WhiteSpace "whitespace" = "\t" / "\v" / "\f" / " " / "\u00A0" / "\uFEFF" LineTerminator

我目前正在制作一种编程语言,并使用PegJS进行解析。这是我的语法:

Start
  = __ program:Program __ { return program; }

// ----- A.1 Lexical Grammar -----

SourceCharacter
  = .

WhiteSpace "whitespace"
  = "\t"
  / "\v"
  / "\f"
  / " "
  / "\u00A0"
  / "\uFEFF"

LineTerminator
  = [\n\r\u2028\u2029]

LineTerminatorSequence "end of line"
  = "\n"
  / "\r\n"
  / "\r"
  / "\u2028"
  / "\u2029"

Comment "comment"
  = MultiLineComment
  / SingleLineComment

MultiLineComment
  = "/*" (!"*/" SourceCharacter)* "*/"

MultiLineCommentNoLineTerminator
  = "/*" (!("*/" / LineTerminator) SourceCharacter)* "*/"

SingleLineComment
  = "//" (!LineTerminator SourceCharacter)*

Identifier
  = !ReservedWord name:IdentifierName { return name; }

IdentifierName "identifier"
  = head:IdentifierStart tail:IdentifierPart* {
      return {
        type: "Identifier",
        name: head + tail.join("")
      };
    }

IdentifierStart
  = UnicodeLetter
  / "_"

IdentifierPart
  = IdentifierStart
  / UnicodeDigit
  / "\u200C"
  / "\u200D"

UnicodeLetter
  = [a-zA-Z]

UnicodeDigit
  = [0-9]

ReservedWord
  = Keyword
  / FutureReservedWord
  / NullLiteral
  / BooleanLiteral

Keyword
  = BreakToken
  / CaseToken
  / CatchToken
  / ContinueToken
  / DebuggerToken
  / DefaultToken
  / DeleteToken
  / DoToken
  / ElseToken
  / FinallyToken
  / ForToken
  / FunctionToken
  / IfToken
  / InstanceofToken
  / InToken
  / NewToken
  / ReturnToken
  / SwitchToken
  / ThisToken
  / ThrowToken
  / TryToken
  / TypeofToken
  / VarToken
  / VoidToken
  / WhileToken
  / WithToken
  / GlobalToken
  / ModulusToken
  / QuotientToken
  / ANDToken
  / NOTToken
  / ORToken
  / EndWhileToken
  / ToToken
  / NextToken
  / UntilToken
  / EndIfToken
  / ElseIfToken
  / ThenToken
  / EndSwitchToken
  / EndFunctionToken
  / EndProcedureToken
  / ProcedureToken
  / ArrayToken

FutureReservedWord
  = ClassToken
  / ConstToken
  / EnumToken
  / ExportToken
  / ExtendsToken
  / ImportToken
  / SuperToken

Literal
  = NullLiteral
  / BooleanLiteral
  / NumericLiteral
  / StringLiteral

NullLiteral
  = NullToken { return { type: "Literal", value: null, valType: "null" }; }

BooleanLiteral
  = TrueToken  { return { type: "Literal", value: true, valType: "bool"  }; }
  / FalseToken { return { type: "Literal", value: false, valType: "bool" }; }

// The "!(IdentifierStart / DecimalDigit)" predicate is not part of the official
// grammar, it comes from text in section 7.8.3.
NumericLiteral "number"
  = literal:DecimalLiteral !DecimalDigit {
      return literal;
    }

DecimalLiteral
  = DecimalIntegerLiteral "." DecimalDigit* {
      return { type: "Literal", value: parseFloat(text()), valType: "float" };
    }
  / "." DecimalDigit+ {
      return { type: "Literal", value: parseFloat(text()), valType: "float" };
    }
  / DecimalIntegerLiteral {
      return { type: "Literal", value: parseFloat(text()), valType: "int" };
    }

DecimalIntegerLiteral
  = "0"
  / NonZeroDigit DecimalDigit*

DecimalDigit
  = [0-9]

NonZeroDigit
  = [1-9]

ExponentPart
  = ExponentIndicator SignedInteger

ExponentIndicator
  = "e"i

SignedInteger
  = [+-]? DecimalDigit+

StringLiteral "string"
  = '"' chars:DoubleStringCharacter* '"' {
      return { type: "Literal", value: chars.join(""), valType: "string" };
    }
  / "'" chars:SingleStringCharacter* "'" {
      return { type: "Literal", value: chars.join(""), valType: "string" };
    }

DoubleStringCharacter
  = !('"' / "\\" / LineTerminator) SourceCharacter { return text(); }
  / "\\" sequence:EscapeSequence { return sequence; }
  / LineContinuation

SingleStringCharacter
  = !("'" / "\\" / LineTerminator) SourceCharacter { return text(); }
  / "\\" sequence:EscapeSequence { return sequence; }
  / LineContinuation

LineContinuation
  = "\\" LineTerminatorSequence { return ""; }

EscapeSequence
  = CharacterEscapeSequence
  / "0" !DecimalDigit { return "\0"; }

CharacterEscapeSequence
  = SingleEscapeCharacter
  / NonEscapeCharacter

SingleEscapeCharacter
  = "'"
  / '"'
  / "\\"
  / "b"  { return "\b"; }
  / "f"  { return "\f"; }
  / "n"  { return "\n"; }
  / "r"  { return "\r"; }
  / "t"  { return "\t"; }
  / "v"  { return "\v"; }

NonEscapeCharacter
  = !(EscapeCharacter / LineTerminator) SourceCharacter { return text(); }

EscapeCharacter
  = SingleEscapeCharacter
  / DecimalDigit
  / "x"
  / "u"

BreakToken      = body:"break" !IdentifierPart {return body}
CaseToken       = "case"       !IdentifierPart
CatchToken      = "catch"      !IdentifierPart
ClassToken      = "class"      !IdentifierPart
ConstToken      = "const"      !IdentifierPart
ContinueToken = body:"continue"!IdentifierPart {return body}
DebuggerToken   = "debugger"   !IdentifierPart
DefaultToken    = "default"    !IdentifierPart
DeleteToken     = "delete"     !IdentifierPart
DoToken         = "do"         !IdentifierPart
ElseIfToken     = "elseif"     !IdentifierPart
ElseToken       = "else"       !IdentifierPart
EnumToken       = "enum"       !IdentifierPart
ExportToken     = "export"     !IdentifierPart
ExtendsToken    = "extends"    !IdentifierPart
FalseToken      = "false"      !IdentifierPart
FinallyToken    = "finally"    !IdentifierPart
ForToken        = "for"        !IdentifierPart
FunctionToken   = "function"   !IdentifierPart
GetToken        = "get"        !IdentifierPart
IfToken         = "if"         !IdentifierPart
ImportToken     = "import"     !IdentifierPart
InstanceofToken = "instanceof" !IdentifierPart
InToken         = "in"         !IdentifierPart
NewToken        = "new"        !IdentifierPart
NullToken       = "none"       !IdentifierPart
ReturnToken     = body:"return"     !IdentifierPart {return body}
SetToken        = "set"        !IdentifierPart
SuperToken      = "super"      !IdentifierPart
SwitchToken     = "switch"     !IdentifierPart
ThisToken       = "this"       !IdentifierPart
ThrowToken      = "throw"      !IdentifierPart
TrueToken       = "true"       !IdentifierPart
TryToken        = "try"        !IdentifierPart
TypeofToken     = "typeof"     !IdentifierPart
VarToken        = "var"        !IdentifierPart
VoidToken       = "void"       !IdentifierPart
WhileToken      = "while"      !IdentifierPart
WithToken       = "with"       !IdentifierPart
GlobalToken     = "global"     !IdentifierPart
ModulusToken    = "MOD"        !IdentifierPart
QuotientToken   = "DIV"        !IdentifierPart
ANDToken        = "AND"        !IdentifierPart
ORToken         = "OR"         !IdentifierPart
NOTToken        = "NOT"        !IdentifierPart
EndWhileToken   = "endwhile"   !IdentifierPart
ToToken         = "to"         !IdentifierPart
NextToken       = "next"       !IdentifierPart
UntilToken      = "until"      !IdentifierPart
EndIfToken      = "endif"      !IdentifierPart
ThenToken       = "then"       !IdentifierPart
EndSwitchToken  = "endswitch"  !IdentifierPart
EndFunctionToken= "endfunction" !IdentifierPart
ProcedureToken  = "procedure"  !IdentifierPart
EndProcedureToken= "endprocedure"  !IdentifierPart
ArrayToken       = "array"         !IdentifierPart


// Skipped

___
  = (WhiteSpace / /*LineTerminatorSequence / Comment*/ MultiLineCommentNoLineTerminator)+
__
  = (WhiteSpace / LineTerminatorSequence / Comment)*

_
  = (WhiteSpace / MultiLineCommentNoLineTerminator)*

Program
  = __ body:StatementList __ {
  return {
    type: "Program",
    body: body
  }
  }

StatementList
  = (Statement)*

Statement
  = __ body:(VariableAssignment
  / GlobalAssignment
  / IterativeStatement
  / IndividualKeyword
  / IfBlock
  / SwitchBlock
  / FunctionCallMember
  / MemberExpression
  / FunctionCallNoMember
  / FunctionDefinition
  / ArrayDeclaration) __
  {
  return body
  }

IterativeStatement
  = WhileStatement / ForStatement / UntilStatement

MathematicalExpression = additive

additive = left:multiplicative _ atag:("+" / "-") _ right:additive { return {type: "MathematicalExpression", operator: atag, left:left, right:right}; } / multiplicative

multiplicative = left:exponential _ atag:("*" / "/" / "MOD" / "DIV") _ right:multiplicative { return {type: "MathematicalExpression", operator: atag, left:left, right:right}; } / exponential

exponential = left:primary _ atag:("^") _ right:exponential { return {type: "MathematicalExpression", operator: atag, left:left, right:right}; } / primary

primary = (DirectValueNoEq) / "(" additive:additive ")" { return additive; }

LogicalExpression = operative

operative = left:negative _ atag:("AND" / "OR") _ right:operative { return {type: "LogicalExpression", operator: atag, left:left, right:right}; } / negative

negative = atag:("NOT") _ right:negative { return {type: "LogicalExpression", operator: atag, right:right}; } / comparative

comparative = left:primaryLogic _ atag:("==" / "!=" / ">=" / ">" / "<=" / "<") _ right:comparative { return {type: "LogicalExpression", operator: atag, left:left, right:right}; } / primaryLogic

primaryLogic = (DirectValue) / "(" operative:operative ")" { return operative; }


DirectValue
 = MathematicalExpression
 / DirectValueNoEq

DirectValueNoEq
 = FunctionCallMember
 / MemberExpression
 / FunctionCallNoMember
 / Identifier
 / Literal

DirectValueNoMember
 = FunctionCallNoMember
 / Identifier
 / Literal

AllowedDefArg
  = VariableAssignment
  / Identifier

FuncArgumentList
  =  help:((AllowedDefArg)?) main:((FuncArgument)*)
  {
  if (help === null) {
  return main
  }
  else {
  return [help].concat(main)
  }
  }
FuncArgument
  = _ "," _ body:AllowedDefArg _
  {
  return body
  }
ArgumentList
  =  help:((DirectValue)?) main:((Argument)*)
  {
  if (help === null) {
  return main
  }
  else {
  return [help].concat(main)
  }
  }
Argument
  = _ "," _ body:DirectValue _
  {
  return body
  }

VariableAssignment
  = left:(MemberExpression / Identifier) _ "=" _ right:DirectValue
  {
  return {
  type: "VariableAssignment",
  left: left,
  right: right
  }
  }

GlobalAssignment
  = GlobalToken ___ left:Identifier _ "=" _ right:DirectValue
  {
  return {
  type: "GlobalAssignment",
  left: left,
  right: right
  }
  }

IfBlock
  = IfToken ___ condition:LogicalExpression ___ ThenToken _
  LineTerminatorSequence
  body:StatementList
  alternative:(ElseIfBlock / ElseBlock)
  {
  return {
  type: "IfBlock",
  condition: condition,
  body: body,
  alternative: alternative
  }
  }

ElseIfBlock
  = ElseIfToken ___ condition:LogicalExpression ___ ThenToken _
  LineTerminatorSequence
  body:StatementList
  alternative:(ElseIfBlock / ElseBlock)
  {
  return {
  type: "ElseIfBlock",
  condition: condition,
  body: body,
  alternative: alternative
  }
  }

ElseBlock
  = ElseToken _
  LineTerminatorSequence
  body:StatementList
  EndIfToken
  {
  return {
  type: "ElseBlock",
  body: body
  }
  }
  / EndIfToken
  {
  return null
  }

SwitchBlock
  = SwitchToken ___ value:DirectValue _ ":" _
  LineTerminatorSequence
  attachedCase:(CaseBlock / DefaultBlock)
  {
  return {
  type: "SwitchBlock",
  value: value,
  attachedCase: attachedCase
  }
  }

CaseBlock
  = CaseToken ___ value:DirectValue _ ":" _
  LineTerminatorSequence
  body:StatementList
  attachedCase:(CaseBlock / DefaultBlock)
  {
  return {
  type: "CaseBlock",
  value: value,
  body: body,
  attachedCase: attachedCase
  }
  }

DefaultBlock
  = DefaultToken _ ":" _
  LineTerminatorSequence
  body:StatementList
  EndSwitchToken
  {
  return {
  type: "DefaultBlock",
  body: body
  }
  }
  / EndSwitchToken
  {
  return null
  }

WhileStatement
  = WhileToken ___ condition:LogicalExpression _
  LineTerminatorSequence
  body:StatementList
  EndWhileToken
  {
  return {
  type: "WhileStatement",
  condition: condition,
  body: body
  }
  }

UntilStatement
  = DoToken _
  LineTerminatorSequence
  body:StatementList
  UntilToken ___ condition:LogicalExpression
  {
  return {
  type: "UntilStatement",
  condition: condition,
  body: body
  }
  }

ForStatement
  = ForToken ___ init:VariableAssignment ___ ToToken ___ end:DirectValue _
  LineTerminatorSequence
  body:StatementList
  NextToken ___ iden:Identifier
  {
  return {
  type: "ForStatement",
  init: init,
  end: end,
  body: body,
  iden: iden
  }
  }

/*MemberFunctionCall
  = callee:("subString") _ "(" _ arg:ArgumentList _ ")"
  {
  return {
  type: "MemberFunctionCall",
  callee: callee,
  arg: arg
  }
  }

BuiltInMemberProperty
  = property:("length")
  {
  return {
  type: "BuiltInMemberProperty",
  property: property
  }
  }*/

FunctionDefinition
 = FunctionToken ___ name:Identifier _ "(" _ arg:FuncArgumentList _ ")" _
 LineTerminatorSequence
 body:StatementList
 EndFunctionToken
 {
  return {
  type: "FunctionDefinition",
  name: name,
  arg: arg,
  body: body
  }
  }


ArrayDeclaration
  = ArrayToken ___ name:Identifier _ "[" _ arg:ArgumentList _ "]"
  {
  return {
  type: "ArrayDeclaration",
  name: name,
  arg: arg
  }
  }

FunctionCall
  = callee:(MemberExpression / Identifier) _ "(" _ arg:ArgumentList _ ")"
  {
  return {
  type: "FunctionCall",
  callee: callee,
  arg: arg
  }
  }

FunctionCallNoMember
  = callee:(Identifier) _ "(" _ arg:ArgumentList _ ")"
  {
  return {
  type: "FunctionCall",
  callee: callee,
  arg: arg
  }
  }

FunctionCallMember
  = callee:(MemberExpression) _ "(" _ arg:ArgumentList _ ")"
  {
  return {
  type: "FunctionCall",
  callee: callee,
  arg: arg
  }
  }

IndividualKeyword
  = keyword:(BreakToken / ContinueToken)
  {
  return {
  type: "IndividualKeyword",
  keyword: keyword
  }
  }
  / keyword:(ReturnToken) ___ value:DirectValue
  {
  return {
  type: "IndividualKeyword",
  keyword: keyword,
  value: value
  }
  }

MemberExpression
  = head:(
  DirectValueNoMember
  )
  tail:(
        __ "[" __ property:ArgumentList __ "]" {
          return { property: property, computed: true };
        }
      / __ "." __ property:(/*MemberFunctionCall /*/ FunctionCallNoMember / Identifier) {
          return { property: property, computed: false };
        }
    )+
    {
      return tail.reduce(function(result, element) {
        return {
          type: "MemberExpression",
          object: result,
          property: element.property,
          computed: element.computed
        };
      }, head);
    }

开始
={program:program{return program;}
//----A.1词汇语法-----
源字符
= .
空白“空白”
=“\t”
/“\v”
/“\f”
/ " "
/“\u00A0”
/“\uFEFF”
线路终端
=[\n\r\u2028\u2029]
LineTerminatorSequence“行尾”
=“\n”
/“\r\n”
/“\r”
/“\u2028”
/“\u2029”
评论“评论”
=多元素
/单行注释
多重元素
=“/*”(!“*/”源字符)*“*/”
多元素联机终结器
=“/*”(!(“*/”/LineTerminator)源字符)*“*/”
单行注释
=“/”(!LineTerminator SourceCharacter)*
标识符
= !ReservedWord名称:IdentifierName{return name;}
标识符名称“标识符”
=头部:标识开始尾部:标识部分*{
返回{
键入:“标识符”,
名称:头+尾。连接(“”)
};
}
标识开始
=单删除器
/ "_"
识别零件
=标识符开始
/独角兽
/“\u200C”
/“\u200D”
单选机
=[a-zA-Z]
独角兽
= [0-9]
保留字
=关键字
/未来保留地
/空文字
/布尔文字
关键词
=BreakToken
/CaseToken
/捕手
/连续剧
/调试令牌
/DefaultToken
/删除令牌
/多肯
/埃尔塞托肯
/最后,伊托肯
/福托克
/FunctionToken
/伊夫托肯
/瞬间停止
/InToken
/纽顿
/返回令牌
/开关令牌
/此令牌
/扔掉
/特里特肯
/token类型
/瓦托克
/无效代币
/WhileToken
/带令牌
/环球托肯
/模块化
/商代币
/和代币
/NOTToken
/奥托肯
/EndWhileToken
/托托肯
/NextToken
/Unteltoken
/EndIfToken
/埃尔塞弗托肯
/ThenToken
/EndSwitchToken
/EndFunctionToken
/结束程序
/程序
/阿雷特肯
未来保留地
=类令牌
/康斯特代克
/枚举令牌
/出口代币
/延长行程
/进口
/超级令牌
字面意义的
=空文本
/布尔文字
/数字文字
/StringLiteral
空文字
=NullToken{return{type:“Literal”,value:null,valType:“null”};}
布尔文字
=TrueToken{return{type:“Literal”,value:true,valType:“bool”};}
/FalseToken{return{type:“Literal”,value:false,valType:“bool”};}
//“!(IdentifierStart/DecimalDigit)”谓词不是官方
//语法,它来自第7.8.3节中的文本。
数字文字“数字”
=文字:小数位数!小数位数{
返回文本;
}
分米线
=DecimalIntegerLiteral.“小数位数*{
返回{type:“Literal”,值:parseFloat(text()),valType:“float”};
}
/““小数位数+{
返回{type:“Literal”,值:parseFloat(text()),valType:“float”};
}
/小数单位文字{
返回{type:“Literal”,值:parseFloat(text()),valType:“int”};
}
小数单位文字
= "0"
/非零位小数*
小数位数
= [0-9]
非零位
= [1-9]
指数部分
=指数指示器签名整数
指数指示器
=“e”i
签名整数
= [+-]? 小数位数+
StringLiteral“字符串”
='“'字符:DoubleStringCharacter*'”{
返回{type:“Literal”,值:chars.join(“”),valType:“string”};
}
/“'“字符:SingleStringCharacter*””{
返回{type:“Literal”,值:chars.join(“”),valType:“string”};
}
双线字符
= !(“'”/“\\”/LineTerminator)源字符{return text();}
/“\\”序列:转义序列{返回序列;}
/行延拓
单线字符
=!(“”/“\\”/LineTerminator)源字符{返回文本();}
/“\\”序列:转义序列{返回序列;}
/行延拓
行延拓
=“\\”行终止顺序{return”“;}
逃逸序列
=字符转义序列
/“0”!小数位数{返回“\0”;}
字符逃逸序列
=单转义字符
/非替身角色
单逃逸字符
= "'"
/ '"'
/ "\\"
/“b”{返回“\b”;}
/“f”{返回“\f”;}
/“n”{返回“\n”}
/“r”{返回“\r”}
/“t”{返回“\t”}
/“v”{返回“\v”;}
非替身角色
= !(EscapeCharacter/LineTerminator)源字符{return text();}
逃逸字符
=单转义字符
/小数位数
/“x”
/“u”
BreakToken=正文:“break”!标识符部分{返回体}
CaseToken=“case”!识别零件
CatchToken=“catch”!识别零件
ClassToken=“class”!识别零件
ConstToken=“const”!识别零件
ContinueToken=正文:“continue”!标识符部分{返回体}
DebuggerToken=“调试器”!识别零件
DefaultToken=“default”!识别零件
DeleteToken=“删除”!识别零件
DoToken=“do”!识别零件
ElseIfToken=“elseif”!识别零件
ElseToken=“else”!识别零件
EnumToken=“enum”!识别零件
ExportToken=“导出”!识别零件
ExtendsToken=“extends”!识别零件
FalseToken=“false”!识别零件
FinallyToken=“finally”!识别零件
ForToken=“for”!识别零件
FunctionToken=“函数”!识别零件
GetToken=“get”!识别零件
IfToken=“如果”!识别零件
ImportToken=“导入”!识别零件
InstanceofToken=“instanceof”!识别零件
InToken=“in”!识别零件
NewToken=“new”!识别零件
NullToken=“无”!识别零件
ReturnToken=body:“return”!标识符部分{返回体}
SetToken=“set”!识别零件
SuperToken=“super”!识别零件
SwitchToken=“开关”!识别零件
ThisToken=“this”!识别零件
ThrowToken=“扔”!识别零件
TrueToken=“true”!识别零件
特里特肯
  tail:(
        __ "[" __ property:ArgumentList __ "]" {
          return { property: property, computed: true };
        }
      / __ "." __ property:(/*MemberFunctionCall /*/ FunctionCallNoMember / Identifier) {
          return { property: property, computed: false };
        }
    )+
FunctionCallNoMember
  = callee:(Identifier) _ "(" _ arg:ArgumentList _ ")"
  {
  return {
  type: "FunctionCall",
  callee: callee,
  arg: arg
  }
  }
MemberExpression
  = head:(
  DirectValueNoMember
  )
  tail:(
        __ "[" __ property:ArgumentList __ "]" {
          return { property: property, computed: true };
        }
      /
        __ "(" _ arg:ArgumentList _ ")"
        {
          return {
            property: {
              type: "FunctionCall",
              arg: arg
            },
            computed: true
          }
        }
      / __ "." __ property:(/*MemberFunctionCall /*/ FunctionCallNoMember / Identifier) {
          return { property: property, computed: false };
        }
    )+
    {
      return tail.reduce(function(result, element) {
        return {
          type: "MemberExpression",
          object: result,
          property: element.property,
          computed: element.computed
        };
      }, head);
    }
{
   "type": "Program",
   "body": [
      {
         "type": "VariableAssignment",
         "left": {
            "type": "Identifier",
            "name": "one"
         },
         "right": {
            "type": "MemberExpression",
            "object": {
               "type": "MemberExpression",
               "object": {
                  "type": "MemberExpression",
                  "object": {
                     "type": "Identifier",
                     "name": "two"
                  },
                  "property": [
                     {
                        "type": "Literal",
                        "value": 3,
                        "valType": "int"
                     }
                  ],
                  "computed": true
               },
               "property": {
                  "type": "FunctionCall",
                  "arg": []
               },
               "computed": true
            },
            "property": {
               "type": "Identifier",
               "name": "four"
            },
            "computed": false
         }
      }
   ]
}