C# 클래스 Loyc.Syntax.Les.LesPrecedence

Contains Precedence objects that represent the precedence levels of LES.
In LES, the precedence of an operator is decided based simply on the text of the operator. The precedence of each one-character operator is predefined; the precedence of any operator with two or more characters is decided based on the first and last characters (according to the rules below). Other characters, if any, do not affect precedence. The LES precedence table mostly matches popular programming languages, i.e. those in the C family. An operator consists of a sequence of the following characters:
 ~ ! % ^ * - + = | < > / ? : . & 
In addition, the $ character is allowed as the first character and, if present, it forces the operator to be interpreted as a prefix operator. LESv3 also has operators that start with a single quote, which can include both letters and punctuation (e.g. '|foo|). The quote itself is ignored for the purpose of choosing precedence. LESv2 has `backquoted` operators instead, whereas in LESv3 backquoted strings are simply identifiers. It is notable that the following punctuation cannot be used in operators:
  • "@" is used for multiple other purposes.
  • "#" is conventionally used to mark "keywords" (although in LESv2, the parser treats it like an underscore or a letter.)
  • "," and ";" are separators, so for example, "?,!" is parsed as three separate tokens.
  • The backslash "\" is reserved for future use.
The following table shows all the precedence levels and associativities of the "built-in" LES operators, except a couple of special operators such as the "lambda" operator =>, whose precedence is different on the left side than on the right side. Each precedence level has a name, which corresponds to a static field of this class. All binary operators are left-associative unless otherwise specified.
  1. Substitute: prefix $ . :
  2. Primary: binary . =:, generic arguments List!(int), suffix ++ --, method calls f(x), indexers a[i]
  3. NullDot: binary ?. ::
  4. DoubleBang: binary right-associative !!
  5. Prefix: prefix ~ ! % ^ * / - + & `backtick` (LESv2 only)
  6. Power: binary **
  7. Multiply: binary * / % \ >> <<
  8. Add: binary + -
  9. Arrow: binary right-associative -> <-
  10. PrefixDots: prefix ..
  11. Range: binary right-associative ..
  12. Compare: binary != == >= > < <=
  13. And: binary &&
  14. Or: binary || ^^
  15. IfElse: binary right-associative ? :
  16. LowerKeyword: a lowercase keyword
  17. PrefixOr: |
Not listed in table: binary => ~ = ?? >> ^ | & << ; prefix ? = > <; non-lowercase keywords. Notice that the precedence of an operator depends on how it is used. The prefix operator - has higher precedence than the binary operator -, so for example - y * z is parsed as (- y) * z, while x - y * z is parsed as x - (y * z). Programmers often use the shift operators >> and << in place of multiplication or division, so their natural precedence is the same as * and /. However, traditionally the C family of languages confusingly give the shift operators a precedence below +. Therefore, LES does not allow mixing of shift operators with + - * /; a >> b + c should produce a parse error. This is called immiscibility as explained in the documentation of Precedence. Parsing may still complete, but the exact output tree is unspecified (may be (a >> b) + c or a >> (b + c)). Likewise, the bitwise ^ | & operators cannot be mixed with comparison operators as in a | 1 == 3. The Lambda operator =>, which is right-associative, has a precedence level above Multiply on the left side, but below Assign on the right side. For example, the expression a = b => c = d is parsed as a = (b => (c = d)), and similarly a + b => c + d is parsed as a + (b => (c + d)), but a ** b => c ** d is parsed (a ** b) => (c ** d). The idea of two different precedences on the two sides of an operator may seem strange; see the documentation of Precedence for more explanation. Similarly, all assignment operators (including compound assignments like +=) have a high precedence on the left side and low precedence on the right. This decision was made for WebAssembly, in which an expression like 2 * i32_store[$f(),4] = 3 * $g() is best parsed as 2 * (i32_store[$f(),4] = (3 * $g())) (NOTE: this example will surely be wrong by the time Wasm is released). As a nod to functional languages, the arrow operator "->" is right- associative and has a precedence below '*' so that int * int -> int parses as (int * int) -> int rather than int * (int -> int) as in the C family of languages. Some operators like 'this-one do not begin with punctuation. These "keyword operators" must be used as binary operators. They either start with a lowercase letter or they don't. If they do start with a lowercase letter, their precedence is LowerKeyword, which is very low, below assignment, so that a = b 'then x = y parses like (a = b) 'then (x = y). If they do not start with a lowercase letter (as in 'Foo or '123) then they have an indeterminate precedence, below power (**) but above comparison (==). This means that an operator like 'XOR or 'Mod cannot be mixed with operators of precedence Multiply, Add, Arrow, AndBits, OrBits, OrIfNull, PrefixDots, and Range operators. Mixing operators illegally (e.g. x 'Mod y + z) will produce a parse error. After constructing an initial table based on common operators from other languages, I noticed that
  • None of the high-precedence operators were right-associative, so I added the !! operator to "fill in the gap".
  • There were no prefix operators with low precedence, so I added ".." whose precedence is just above binary "..", and "|" which has a precedence lower than anything except attributes (this "operator" is inspired by Nemerle, which uses "|" in pattern matching and variants.)
I also wanted to have a little "room to grow"--to defer the precedence decision to a future time for some operators. So the precedence of the binary operator ~ has a range of operators with which it cannot be mixed, the same range as for uppercase operators without punctuation; for example, x ~ y + z is invalid but x ~ y == z is allowed. The operators \ ? = > < cannot be used as prefix operators. The way that low-precedence prefix operators are parsed deserves some discussion... TODO. Most operators can have two roles. Most operators can either be binary operators or prefix operators; for example, !*! is a binary operator in x !*! y but a prefix operator in x + !*! y. The operators ++ -- also have two roles, but different roles: they can be either prefix or suffix operators, but not binary operators. For example, -*- is a suffix operator in x -*- + y and a prefix operator in x + -*- y. Please note that x -*- y is ambiguous (it could be parsed as either of two superexpressions, (x -*-) (y) or (x) (-*- y)) and it is illegal. Operators that start with $ can only be prefix operators (not binary or suffix). Having only a single role makes these operators unambiguous inside superexpressions (LESv2) or with juxtaposition (LESv3). An operator cannot have all three roles (suffix, prefix and binary); that would be overly ambiguous. For example, if "-" could also be a suffix operator then x - + y could be parsed as (x -) + y as well as x - (+ y). More subtly, LES does not define any operators that could take binary or suffix roles, because that would also be ambiguous. For example, suppose |?| is a binary or suffix operator, but not a prefix operator. Clearly x |?| y and x |?| |?| y are unambiguous, but x |?| + y is ambiguous: it could be parsed as (x |?|) + y or x |?| (+ y). It turns out that a computer language can contain operators that serve as binary and prefix operators, OR it can contain operators that serve as binary and suffix operators, but a language is ambiguous if it has both kinds of operators at the same time.

How to detect an operator's precedence

To determine the precedence of any given operator, first you must decide, mainly based on the context in which the operator appears and the text of the operator, whether it is a prefix, binary, or suffix operator. Suffix operators can only be derived from the operators ++, -- ("derived" means that you can add additional operator characters in the middle, e.g. +++ and -%- are can be prefix or suffix operators.) If an operator starts with a single quote in LESv3 ('), the quote is not considered for the purpose of choosing precedence (rather, it is used to allow letters and digits in the operator name). Next, if the operator is only one character, simply find it in the list of operators in the previous section to learn its precedence. If the operator is two or more characters, take the first character A and the and the last character Z, and of the following rules, use the first rule that applies:
  1. If AZ is "!=" or "==", or if the operator is exactly two characters long (ignoring the initial single quote) and equal to ">=", or "<=", its precedence is Compare. This rule separates comparison operators from assignment operators, so that ">>=" is different from ">=", and "===" counts as a comparison operator.
  2. If it's an infix operator and Z is '=', the precedence is Assign.
  3. Look for an operator named AZ from the section above. If it is defined, the operator will have the same precedence. For example, binary =|> has the same precedence as binary "=>".
  4. Otherwise, look for an entry in the table for A. For example, binary "%+" has the same precedence as binary "%" and unary "-*" has the same precedence as unary "-".
  5. If the operator is not an infix operator, it is illegal (e.g. prefix ?? doesn't exist).
  6. If A is a lowercase letter, the precedence is LowerKeyword.
  7. Otherwise, the operator's precedence is Other.
The double-colon :: has the "wrong" precedence according to C# and C++ rules; a.b::c.d is parsed (a.b)::(c.d) although it would be parsed ((a.b)::c).d in C# and C++. The change in precedence allows double colon to be used for variable declarations in LeMP, as in x::System.Drawing.Point. The lower precedence allows this to be parsed properly, but it sacrifices full fidelity with C#/C++. There are no ternary operators in LES. '?' and ':' are right-associative binary operators, so c ? a : b is parsed as c ? (a : b). The lack of an official ternary operator reduces the complexity of the parser. LES represents Loyc trees, which do not distinguish operators and functions except by name; x += y is equivalent to the function call `'+=`(x, y) in LESv3 (@'+=(x, y) in LESv2), and the actual name of the function is '+=. Operators that do not start with a single quote in LES do start with a single quote in the final output (e.g. 2 + 2 is equivalent to 2 '+ 2). There is an exception: While prefix ++ and -- are named '++ and '--, the suffix versions are named '++suf and '--suf in the output tree. For LESv2 operators surrounded by `backquotes`, the backquotes are not included in the output tree (e.g. `sqrt` x is equivalent to sqrt(x)).
파일 보기 프로젝트 열기: qwertie/ecsharp

공개 프로퍼티들

프로퍼티 타입 설명
Add Precedence
And Precedence
AndBits Precedence
Arrow Precedence
Assign Precedence
Compare Precedence
DoubleBang Precedence
IfElse Precedence
Lambda Precedence
LowerKeyword Precedence
Multiply Precedence
NullDot Precedence
Of Precedence
Or Precedence
OrBits Precedence
OrIfNull Precedence
Other Precedence
Power Precedence
Prefix Precedence
PrefixDots Precedence
PrefixOr Precedence
Primary Precedence
Range Precedence
Shift Precedence
Substitute Precedence
SuperExpr Precedence

프로퍼티 상세

Add 공개적으로 정적으로 프로퍼티

public static Precedence Add
리턴 Precedence

And 공개적으로 정적으로 프로퍼티

public static Precedence And
리턴 Precedence

AndBits 공개적으로 정적으로 프로퍼티

public static Precedence AndBits
리턴 Precedence

Arrow 공개적으로 정적으로 프로퍼티

public static Precedence Arrow
리턴 Precedence

Assign 공개적으로 정적으로 프로퍼티

public static Precedence Assign
리턴 Precedence

Compare 공개적으로 정적으로 프로퍼티

public static Precedence Compare
리턴 Precedence

DoubleBang 공개적으로 정적으로 프로퍼티

public static Precedence DoubleBang
리턴 Precedence

IfElse 공개적으로 정적으로 프로퍼티

public static Precedence IfElse
리턴 Precedence

Lambda 공개적으로 정적으로 프로퍼티

public static Precedence Lambda
리턴 Precedence

LowerKeyword 공개적으로 정적으로 프로퍼티

public static Precedence LowerKeyword
리턴 Precedence

Multiply 공개적으로 정적으로 프로퍼티

public static Precedence Multiply
리턴 Precedence

NullDot 공개적으로 정적으로 프로퍼티

public static Precedence NullDot
리턴 Precedence

Of 공개적으로 정적으로 프로퍼티

public static Precedence Of
리턴 Precedence

Or 공개적으로 정적으로 프로퍼티

public static Precedence Or
리턴 Precedence

OrBits 공개적으로 정적으로 프로퍼티

public static Precedence OrBits
리턴 Precedence

OrIfNull 공개적으로 정적으로 프로퍼티

public static Precedence OrIfNull
리턴 Precedence

Other 공개적으로 정적으로 프로퍼티

public static Precedence Other
리턴 Precedence

Power 공개적으로 정적으로 프로퍼티

public static Precedence Power
리턴 Precedence

Prefix 공개적으로 정적으로 프로퍼티

public static Precedence Prefix
리턴 Precedence

PrefixDots 공개적으로 정적으로 프로퍼티

public static Precedence PrefixDots
리턴 Precedence

PrefixOr 공개적으로 정적으로 프로퍼티

public static Precedence PrefixOr
리턴 Precedence

Primary 공개적으로 정적으로 프로퍼티

public static Precedence Primary
리턴 Precedence

Range 공개적으로 정적으로 프로퍼티

public static Precedence Range
리턴 Precedence

Shift 공개적으로 정적으로 프로퍼티

public static Precedence Shift
리턴 Precedence

Substitute 공개적으로 정적으로 프로퍼티

public static Precedence Substitute
리턴 Precedence

SuperExpr 공개적으로 정적으로 프로퍼티

public static Precedence SuperExpr
리턴 Precedence