?? parser.cs
字號:
#line 1 "cs.ATG"
using System.Drawing;
using System.Collections;
using System.Collections.Specialized;
using System.Text;
using ICSharpCode.SharpRefactory.Parser;
using ICSharpCode.SharpRefactory.Parser.AST;
using System;
using System.Reflection;
namespace ICSharpCode.SharpRefactory.Parser {
public class Parser
{
const int maxT = 125;
const bool T = true;
const bool x = false;
const int minErrDist = 2;
const string errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text
int errDist = minErrDist;
Errors errors;
Lexer lexer;
public Errors Errors {
get {
return errors;
}
}
#line 10 "cs.ATG"
string assemblyName = null;
public CompilationUnit compilationUnit;
public string ContainingAssembly {
set {
assemblyName = value;
}
}
Token t {
get {
return lexer.Token;
}
}
Token la {
get {
return lexer.LookAhead;
}
}
Hashtable typeStrings = null;
ArrayList usingNamespaces = null;
public void Error(string s)
{
if (errDist >= minErrDist) {
errors.Error(la.line, la.col, s);
}
errDist = 0;
}
public Expression ParseExpression(Lexer lexer)
{
this.errors = lexer.Errors;
this.lexer = lexer;
errors.SynErr = new ErrorCodeProc(SynErr);
lexer.NextToken();
Expression expr;
Expr(out expr);
return expr;
}
bool IsTypeCast()
{
if (IsSimpleTypeCast()) {
return true;
}
if (assemblyName != null) {
return CheckTypeCast();
}
return GuessTypeCast();
}
bool IsSimpleTypeCast()
{
// check: "(" pointer or array of keyword type ")"
if (la.kind != Tokens.OpenParenthesis) {
return false;
}
StartPeek();
Token pt1 = Peek();
Token pt = Peek();
return ParserUtil.IsTypeKW(pt1) && IsPointerOrDims(ref pt) &&
pt.kind == Tokens.CloseParenthesis;
}
bool CheckTypeCast()
{
// check: leading "(" pointer or array of some type ")"
if (la.kind != Tokens.OpenParenthesis) {
return false;
}
string qualident;
StartPeek();
Token pt = Peek();
return IsQualident(ref pt, out qualident) && IsPointerOrDims(ref pt) &&
pt.kind == Tokens.CloseParenthesis && IsType(qualident);
}
bool IsType(string qualident)
{
if (typeStrings == null) {
CreateTypeStrings();
}
if (typeStrings.ContainsValue(qualident)) {
return true;
}
foreach (string ns in usingNamespaces) {
if (typeStrings.ContainsValue(String.Concat(ns, '.', qualident))) {
return true;
}
}
return false;
}
bool GuessTypeCast()
{
// check: "(" pointer or array of some type ")" possible type cast successor
if (la.kind != Tokens.OpenParenthesis) return false;
string qualident;
StartPeek();
Token pt = Peek();
if (IsQualident(ref pt, out qualident) && IsPointerOrDims(ref pt) &&
pt.kind == Tokens.CloseParenthesis) {
// check successor
return pt.kind == Tokens.Identifier || pt.kind == Tokens.Literal ||
pt.kind == Tokens.OpenParenthesis || ParserUtil.IsUnaryOperator(pt) ||
pt.kind == Tokens.New || pt.kind == Tokens.This ||
pt.kind == Tokens.Base || pt.kind == Tokens.Null ||
pt.kind == Tokens.Checked || pt.kind == Tokens.Unchecked ||
pt.kind == Tokens.Typeof || pt.kind == Tokens.Sizeof ||
(ParserUtil.IsTypeKW(pt) && Peek().kind == Tokens.Dot);
} else return false;
}
void CreateTypeStrings()
{
Assembly a;
Type[] types;
AssemblyName [] aNames;
if (assemblyName != null && assemblyName.Length > 0) { /* AW 2002-12-30 add check for length > 0 */
typeStrings = new Hashtable();
a = Assembly.LoadFrom(assemblyName);
types = a.GetTypes();
foreach (Type t in types)
typeStrings.Add(t.FullName.GetHashCode(), t.FullName);
aNames = a.GetReferencedAssemblies();
for (int i = 0; i < aNames.Length; i++) {
a = Assembly.LoadFrom(aNames[i].Name);
types = a.GetExportedTypes();
foreach(Type t in types)
if (usingNamespaces.Contains(t.FullName.Substring(0, t.FullName.LastIndexOf('.'))))
typeStrings.Add(t.FullName.GetHashCode(), t.FullName);
}
}
}
/* Checks whether the next sequences of tokens is a qualident *
* and returns the qualident string */
/* !!! Proceeds from current peek position !!! */
bool IsQualident(ref Token pt, out string qualident)
{
if (pt.kind == Tokens.Identifier) {
StringBuilder qualidentsb = new StringBuilder(pt.val);
pt = Peek();
while (pt.kind == Tokens.Dot) {
pt = Peek();
if (pt.kind != Tokens.Identifier) {
qualident = String.Empty;
return false;
}
qualidentsb.Append('.');
qualidentsb.Append(pt.val);
pt = Peek();
}
qualident = qualidentsb.ToString();
return true;
}
qualident = String.Empty;
return false;
}
/* skip: { "*" | "[" { "," } "]" } */
/* !!! Proceeds from current peek position !!! */
bool IsPointerOrDims (ref Token pt)
{
for (;;) {
if (pt.kind == Tokens.OpenSquareBracket) {
do pt = Peek();
while (pt.kind == Tokens.Comma);
if (pt.kind != Tokens.CloseSquareBracket) return false;
} else if (pt.kind != Tokens.Times) break;
pt = Peek();
}
return true;
}
/* Return the n-th token after the current lookahead token */
void StartPeek()
{
lexer.StartPeek();
}
Token Peek()
{
return lexer.Peek();
}
Token Peek (int n)
{
lexer.StartPeek();
Token x = la;
while (n > 0) {
x = lexer.Peek();
n--;
}
return x;
}
/*-----------------------------------------------------------------*
* Resolver routines to resolve LL(1) conflicts: * *
* These resolution routine return a boolean value that indicates *
* whether the alternative at hand shall be choosen or not. *
* They are used in IF ( ... ) expressions. *
*-----------------------------------------------------------------*/
/* True, if ident is followed by "=" */
bool IdentAndAsgn ()
{
return la.kind == Tokens.Identifier && Peek(1).kind == Tokens.Assign;
}
bool IsAssignment () { return IdentAndAsgn(); }
/* True, if ident is followed by ",", "=", or ";" */
bool IdentAndCommaOrAsgnOrSColon () {
int peek = Peek(1).kind;
return la.kind == Tokens.Identifier &&
(peek == Tokens.Comma || peek == Tokens.Assign || peek == Tokens.Semicolon);
}
bool IsVarDecl () { return IdentAndCommaOrAsgnOrSColon(); }
/* True, if the comma is not a trailing one, *
* like the last one in: a, b, c, */
bool NotFinalComma () {
int peek = Peek(1).kind;
return la.kind == Tokens.Comma &&
peek != Tokens.CloseCurlyBrace && peek != Tokens.CloseSquareBracket;
}
/* True, if "void" is followed by "*" */
bool NotVoidPointer () {
return la.kind == Tokens.Void && Peek(1).kind != Tokens.Times;
}
/* True, if "checked" or "unchecked" are followed by "{" */
bool UnCheckedAndLBrace () {
return la.kind == Tokens.Checked || la.kind == Tokens.Unchecked &&
Peek(1).kind == Tokens.OpenCurlyBrace;
}
/* True, if "." is followed by an ident */
bool DotAndIdent () {
return la.kind == Tokens.Dot && Peek(1).kind == Tokens.Identifier;
}
/* True, if ident is followed by ":" */
bool IdentAndColon () {
return la.kind == Tokens.Identifier && Peek(1).kind == Tokens.Colon;
}
bool IsLabel () { return IdentAndColon(); }
/* True, if ident is followed by "(" */
bool IdentAndLPar () {
return la.kind == Tokens.Identifier && Peek(1).kind == Tokens.OpenParenthesis;
}
/* True, if "catch" is followed by "(" */
bool CatchAndLPar () {
return la.kind == Tokens.Catch && Peek(1).kind == Tokens.OpenParenthesis;
}
bool IsTypedCatch () { return CatchAndLPar(); }
/* True, if "[" is followed by the ident "assembly" */
bool IsGlobalAttrTarget () {
Token pt = Peek(1);
return la.kind == Tokens.OpenSquareBracket &&
pt.kind == Tokens.Identifier && pt.val == "assembly";
}
/* True, if "[" is followed by "," or "]" */
bool LBrackAndCommaOrRBrack () {
int peek = Peek(1).kind;
return la.kind == Tokens.OpenSquareBracket &&
(peek == Tokens.Comma || peek == Tokens.CloseSquareBracket);
}
bool IsDims () { return LBrackAndCommaOrRBrack(); }
/* True, if "[" is followed by "," or "]" *
* or if the current token is "*" */
bool TimesOrLBrackAndCommaOrRBrack () {
return la.kind == Tokens.Times || LBrackAndCommaOrRBrack();
}
bool IsPointerOrDims () { return TimesOrLBrackAndCommaOrRBrack(); }
bool IsPointer () { return la.kind == Tokens.Times; }
/* True, if lookahead is a primitive type keyword, or *
* if it is a type declaration followed by an ident */
bool IsLocalVarDecl () {
if ((ParserUtil.IsTypeKW(la) && Peek(1).kind != Tokens.Dot) || la.kind == Tokens.Void) return true;
StartPeek();
Token pt = la ; // peek token
string ignore;
return IsQualident(ref pt, out ignore) && IsPointerOrDims(ref pt) &&
pt.kind == Tokens.Identifier;
}
/* True, if lookahead ident is "get" */
bool IdentIsGet () {
return la.kind == Tokens.Identifier && la.val == "get";
}
/* True, if lookahead ident is "set" */
bool IdentIsSet () {
return la.kind == Tokens.Identifier && la.val == "set";
}
/* True, if lookahead ident is "add" */
bool IdentIsAdd () {
return la.kind == Tokens.Identifier && la.val == "add";
}
/* True, if lookahead ident is "remove" */
bool IdentIsRemove () {
return la.kind == Tokens.Identifier && la.val == "remove";
}
/* True, if lookahead is a local attribute target specifier, *
* i.e. one of "event", "return", "field", "method", *
* "module", "param", "property", or "type" */
bool IsLocalAttrTarget () {
int cur = la.kind;
string val = la.val;
return (cur == Tokens.Event || cur == Tokens.Return ||
(cur == Tokens.Identifier &&
(val == "field" || val == "method" || val == "module" ||
val == "param" || val == "property" || val == "type"))) &&
Peek(1).kind == Tokens.Colon;
}
/*------------------------------------------------------------------------*
*----- LEXER TOKEN LIST ------------------------------------------------*
*------------------------------------------------------------------------*/
/*
*/
void SynErr(int n)
{
if (errDist >= minErrDist) {
errors.SynErr(lexer.LookAhead.line, lexer.LookAhead.col, n);
}
errDist = 0;
}
public void SemErr(string msg)
{
if (errDist >= minErrDist) {
errors.Error(lexer.Token.line, lexer.Token.col, msg);
}
errDist = 0;
}
void Expect(int n)
{
if (lexer.LookAhead.kind == n) {
lexer.NextToken();
} else {
SynErr(n);
}
}
bool StartOf(int s)
{
return set[s, lexer.LookAhead.kind];
}
void ExpectWeak(int n, int follow)
{
if (lexer.LookAhead.kind == n) {
lexer.NextToken();
} else {
SynErr(n);
while (!StartOf(follow)) {
lexer.NextToken();
}
}
}
bool WeakSeparator(int n, int syFol, int repFol)
{
bool[] s = new bool[maxT + 1];
if (lexer.LookAhead.kind == n) {
lexer.NextToken();
return true;
} else if (StartOf(repFol)) {
return false;
} else {
for (int i = 0; i <= maxT; i++) {
s[i] = set[syFol, i] || set[repFol, i] || set[0, i];
}
SynErr(n);
while (!s[lexer.LookAhead.kind]) {
lexer.NextToken();
}
return StartOf(syFol);
}
}
void CS() {
#line 522 "cs.ATG"
compilationUnit = new CompilationUnit();
while (la.kind == 120) {
UsingDirective();
}
while (
#line 525 "cs.ATG"
IsGlobalAttrTarget()) {
GlobalAttributeSection();
}
while (StartOf(1)) {
NamespaceMemberDecl();
}
Expect(0);
}
void UsingDirective() {
#line 532 "cs.ATG"
usingNamespaces = new ArrayList();
string qualident = null, aliasident = null;
Expect(120);
#line 536 "cs.ATG"
Point startPos = t.Location;
INode node = null;
if (
#line 539 "cs.ATG"
IsAssignment()) {
lexer.NextToken();
#line 539 "cs.ATG"
aliasident = t.val;
Expect(3);
}
Qualident(
#line 540 "cs.ATG"
out qualident);
#line 540 "cs.ATG"
if (qualident != null && qualident.Length > 0) {
if (aliasident != null) {
node = new UsingAliasDeclaration(aliasident, qualident);
} else {
usingNamespaces.Add(qualident);
node = new UsingDeclaration(qualident);
}
}
Expect(10);
#line 549 "cs.ATG"
node.StartLocation = startPos;
node.EndLocation = t.EndLocation;
compilationUnit.AddChild(node);
}
void GlobalAttributeSection() {
Expect(16);
#line 558 "cs.ATG"
Point startPos = t.Location;
Expect(1);
#line 558 "cs.ATG"
if (t.val != "assembly") Error("global attribute target specifier (\"assembly\") expected");
string attributeTarget = t.val;
ArrayList attributes = new ArrayList();
ICSharpCode.SharpRefactory.Parser.AST.Attribute attribute;
Expect(9);
Attribute(
#line 563 "cs.ATG"
out attribute);
#line 563 "cs.ATG"
attributes.Add(attribute);
while (
#line 564 "cs.ATG"
NotFinalComma()) {
Expect(12);
Attribute(
#line 564 "cs.ATG"
out attribute);
#line 564 "cs.ATG"
attributes.Add(attribute);
}
if (la.kind == 12) {
lexer.NextToken();
}
Expect(17);
#line 566 "cs.ATG"
AttributeSection section = new AttributeSection(attributeTarget, attributes);
section.StartLocation = startPos;
section.EndLocation = t.EndLocation;
compilationUnit.AddChild(section);
}
void NamespaceMemberDecl() {
#line 648 "cs.ATG"
AttributeSection section;
ArrayList attributes = new ArrayList();
Modifiers m = new Modifiers(this);
string qualident;
if (la.kind == 87) {
lexer.NextToken();
#line 654 "cs.ATG"
Point startPos = t.Location;
Qualident(
#line 655 "cs.ATG"
out qualident);
#line 655 "cs.ATG"
INode node = new NamespaceDeclaration(qualident);
node.StartLocation = startPos;
compilationUnit.AddChild(node);
compilationUnit.BlockStart(node);
Expect(14);
while (la.kind == 120) {
UsingDirective();
}
while (StartOf(1)) {
NamespaceMemberDecl();
}
Expect(15);
if (la.kind == 10) {
lexer.NextToken();
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -