Incparser upgrades.

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%402088
This commit is contained in:
Matt Woodrow 2008-04-21 21:41:38 +00:00
parent ac256a6c24
commit af05dbbcdf
5 changed files with 299 additions and 13 deletions

View File

@ -133,7 +133,7 @@ namespace incparser
Initialize(); Initialize();
} }
public void Parse(ParseWriter w) public void Parse(ParseWriter w)
{ {
w.BeginSection(System.IO.Path.GetFileName(FileName)); w.BeginSection(System.IO.Path.GetFileName(FileName));
LexToken tok = LexToken.TOKEN_NONE; LexToken tok = LexToken.TOKEN_NONE;
@ -198,7 +198,12 @@ namespace incparser
} }
default: default:
{ {
throw new ParseException("Unrecognized token: " + tok); if (_LexString == "static" || _LexString == "new")
{
PARSE_Public(w);
break;
}
throw new ParseException("Unrecognized token: " + tok + " " + _LexString);
} }
} }
} }
@ -207,16 +212,29 @@ namespace incparser
private void PARSE_Public(ParseWriter w) private void PARSE_Public(ParseWriter w)
{ {
MatchToken(LexToken.TOKEN_CONST);
/* Eat up an optional tag */ /* Eat up an optional tag */
MatchToken(LexToken.TOKEN_LABEL); MatchToken(LexToken.TOKEN_LABEL);
/* Eat up a name */ /* Eat up a name */
NeedToken(LexToken.TOKEN_SYMBOL); NeedToken(LexToken.TOKEN_SYMBOL);
while (MatchChar('['))
{
DiscardUntilChar(']');
NeedChar(']');
}
if (MatchChar('=')) if (MatchChar('='))
{ {
ignore_block(); ignore_block();
} }
else if (MatchChar('(') && MatchChar(')'))
{
ignore_block();
return;
}
NeedChar(';'); NeedChar(';');
} }
@ -225,6 +243,7 @@ namespace incparser
{ {
/* For now, we completely ignore these (they're not written to the output) */ /* For now, we completely ignore these (they're not written to the output) */
NeedToken(LexToken.TOKEN_SYMBOL); NeedToken(LexToken.TOKEN_SYMBOL);
w.structList.Add(LexString);
NeedChar('{'); NeedChar('{');
bool need_closebrace = true; bool need_closebrace = true;
@ -294,6 +313,7 @@ namespace incparser
/* Get the functag name */ /* Get the functag name */
NeedToken(LexToken.TOKEN_SYMBOL); NeedToken(LexToken.TOKEN_SYMBOL);
w.WritePair("name", LexString); w.WritePair("name", LexString);
w.funcenumList.Add(LexString);
NeedChar('{'); NeedChar('{');
@ -359,6 +379,7 @@ namespace incparser
/* Get the functag name */ /* Get the functag name */
NeedToken(LexToken.TOKEN_SYMBOL); NeedToken(LexToken.TOKEN_SYMBOL);
w.WritePair("name", LexString); w.WritePair("name", LexString);
w.functagList.Add(LexString);
if (MatchToken(LexToken.TOKEN_LABEL)) if (MatchToken(LexToken.TOKEN_LABEL))
{ {
@ -422,14 +443,17 @@ namespace incparser
if (tok == LexToken.TOKEN_FORWARD) if (tok == LexToken.TOKEN_FORWARD)
{ {
w.BeginSection("forward"); w.BeginSection("forward");
w.forwardList.Add(name);
} }
else if (tok == LexToken.TOKEN_NATIVE) else if (tok == LexToken.TOKEN_NATIVE)
{ {
w.BeginSection("native"); w.BeginSection("native");
w.nativeList.Add(name);
} }
else if (tok == LexToken.TOKEN_STOCK) else if (tok == LexToken.TOKEN_STOCK)
{ {
w.BeginSection("stock"); w.BeginSection("stock");
w.stockList.Add(name);
} }
w.WritePair("name", name); w.WritePair("name", name);
@ -571,9 +595,17 @@ namespace incparser
w.WritePair("name", name); w.WritePair("name", name);
w.BeginSection("properties"); w.BeginSection("properties");
w.enumList.Add(name);
NeedChar('{'); NeedChar('{');
bool more_entries = true; bool more_entries = true;
bool need_closebrace = true; bool need_closebrace = true;
if (MatchToken(LexToken.TOKEN_DOCBLOCK))
{
w.WritePair("doc", LexString);
}
do do
{ {
if (MatchChar('}')) if (MatchChar('}'))
@ -583,12 +615,14 @@ namespace incparser
} }
NeedToken(LexToken.TOKEN_SYMBOL); NeedToken(LexToken.TOKEN_SYMBOL);
name = LexString; name = LexString;
if (MatchChar('=')) if (MatchChar('='))
{ {
DiscardUntilCharOrComment(',', true); DiscardUntilCharOrComment(",\n}", true);
} }
more_entries = MatchChar(','); more_entries = MatchChar(',');
w.WritePair("name", name); w.WritePair("name", name);
w.enumTypeList.Add(name);
if (MatchToken(LexToken.TOKEN_DOCBLOCK)) if (MatchToken(LexToken.TOKEN_DOCBLOCK))
{ {
w.WritePair("doc", LexString); w.WritePair("doc", LexString);
@ -637,6 +671,8 @@ namespace incparser
} }
/* Write */ /* Write */
w.defineList.Add(name);
w.BeginSection("define"); w.BeginSection("define");
w.WritePair("name", name); w.WritePair("name", name);
w.WritePair("linetext", value); w.WritePair("linetext", value);
@ -721,6 +757,37 @@ namespace incparser
} }
} }
/**
* Discards all data up to a certain character, ignoring
* the contents, unless specified to stop at a doc block comment.
*/
private void DiscardUntilCharOrComment(string s, bool stop_at_comment)
{
for (int i = 0; i < Contents.Length; i++)
{
if (Contents[i] == '\n')
{
LineNo++;
}
else if (s.Contains(Contents[i].ToString()))
{
if (i > 0)
{
Contents.Remove(0, i);
}
return;
}
else if (stop_at_comment && CheckString(i, "/**"))
{
if (i > 0)
{
Contents.Remove(0, i);
}
return;
}
}
}
/** /**
* Finds the end of an expression * Finds the end of an expression
*/ */
@ -938,7 +1005,7 @@ namespace incparser
bool is_doc = false; bool is_doc = false;
bool is_newline = true; bool is_newline = true;
for (int i=0; i<Contents.Length-1; i++) for (int i=0; i<Contents.Length; i++)
{ {
if (Contents[i] == '\n') if (Contents[i] == '\n')
{ {
@ -953,6 +1020,7 @@ namespace incparser
in_comment = true; in_comment = true;
is_ml = false; is_ml = false;
is_doc = false; is_doc = false;
is_newline = false;
} else if (Contents[i+1] == '*') { } else if (Contents[i+1] == '*') {
/* Detect whether this is a doc comment or not */ /* Detect whether this is a doc comment or not */
if (Contents.Length - i >= 3 if (Contents.Length - i >= 3

View File

@ -1,6 +1,8 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.IO;
namespace incparser namespace incparser
{ {
@ -9,6 +11,16 @@ namespace incparser
private int level; private int level;
private StringBuilder data; private StringBuilder data;
public ArrayList enumList = new ArrayList();
public ArrayList defineList = new ArrayList();
public ArrayList enumTypeList = new ArrayList();
public ArrayList forwardList = new ArrayList();
public ArrayList nativeList = new ArrayList();
public ArrayList stockList = new ArrayList();
public ArrayList funcenumList = new ArrayList();
public ArrayList functagList = new ArrayList();
public ArrayList structList = new ArrayList();
public int Level public int Level
{ {
get get
@ -25,6 +37,12 @@ namespace incparser
} }
} }
public void Reset()
{
level = 0;
data = new StringBuilder();
}
public ParseWriter() public ParseWriter()
{ {
level = 0; level = 0;
@ -52,6 +70,79 @@ namespace incparser
WriteLine("}"); WriteLine("}");
} }
public void WriteFiles(string template, string outputfile)
{
StreamReader sr = null;
try
{
sr = File.OpenText(template);
}
catch (Exception e)
{
Console.WriteLine("Failed to open template file: " + e.Message);
return;
}
string contents = sr.ReadToEnd();
string replace = ToOutputString(defineList);
contents = contents.Replace("$defines", replace);
replace = ToOutputString(enumList);
contents = contents.Replace("$enums", replace);
replace = ToOutputString(enumTypeList);
contents = contents.Replace("$enumtypes", replace);
replace = ToOutputString(forwardList);
contents = contents.Replace("$forwards", replace);
replace = ToOutputString(nativeList);
contents = contents.Replace("$natives", replace);
replace = ToOutputString(stockList);
contents = contents.Replace("$stocks", replace);
replace = ToOutputString(funcenumList);
contents = contents.Replace("$funcenums", replace);
replace = ToOutputString(functagList);
contents = contents.Replace("$functags", replace);
replace = ToOutputString(structList);
contents = contents.Replace("$structs", replace);
StreamWriter sw;
sw = File.CreateText(outputfile);
sw.Write(contents);
sr.Close();
sw.Close();
}
private string ToOutputString(ArrayList a)
{
string defines = "";
int count = 0;
foreach (object o in a)
{
defines += o;
defines += " ";
count += o.ToString().Length;
if (count > 180)
{
defines += "\r\n";
count = 0;
}
}
return defines;
}
private void WriteLine(string line) private void WriteLine(string line)
{ {
Tabinate(); Tabinate();

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.IO;
namespace incparser namespace incparser
{ {
@ -13,16 +14,110 @@ namespace incparser
static int SubMain(string[] args) static int SubMain(string[] args)
{ {
if (args.Length < 1) string directory = ".";
string template = "template.txt";
string outputfile = "output.txt";
string file = null;
if (args.Length == 0 || (args.Length == 1 && args[0] == "-h"))
{ {
Console.WriteLine("Usage: incparser <infile>"); PrintHelp();
return 1; return 0;
}
for (int i=0; i<args.Length-1; i++)
{
if (args[i] == "-d")
{
directory = args[i + 1];
}
if (args[i] == "-t")
{
template = args[i + 1];
}
if (args[i] == "-o")
{
outputfile = args[i + 1];
}
if (args[i] == "-f")
{
file = args[i + 1];
}
if (args[i] == "-h")
{
if (args[i + 1] == "template")
{
PrintTemplateHelp();
return 0;
}
PrintHelp();
return 0;
}
} }
IncParser inc = null; IncParser inc = null;
if (file == null)
{
DirectoryInfo di = new DirectoryInfo(directory);
FileInfo[] rgFiles = di.GetFiles("*.inc");
ParseWriter pwr = new ParseWriter();
foreach (FileInfo fi in rgFiles)
{
pwr.Reset();
Console.Write("Parsing file: " + fi.ToString() + "... ");
try
{
inc = new IncParser(fi.FullName);
}
catch (ParseException e)
{
Console.WriteLine("Initial browsing failed: " + e.Message);
continue;
}
catch (System.Exception e)
{
Console.WriteLine("Failed to read file: " + e.Message);
continue;
}
try
{
inc.Parse(pwr);
}
catch (System.Exception e)
{
Console.WriteLine("Error parsing file (line " + inc.GetLineNumber() + "): " + e.Message);
continue;
}
if (pwr.Level != 0)
{
Console.WriteLine("Fatal parse error detected; unable to complete output.");
continue;
}
Console.WriteLine("Complete!");
}
pwr.WriteFiles(template, outputfile);
Console.WriteLine("Parsing Complete!");
return 0;
}
try try
{ {
inc = new IncParser(args[0]); inc = new IncParser(file);
} }
catch (ParseException e) catch (ParseException e)
{ {
@ -58,5 +153,31 @@ namespace incparser
return 0; return 0;
} }
static void PrintHelp()
{
Console.WriteLine("SourcePawn include file parser by BAILOPAN (edited by pRED*)");
Console.Write("\n");
Console.WriteLine("This can parse a single file into SMC configuration format or an entire directory into a template file if -f is not specified (current directory is used if -d is not specified)");
Console.Write("\n");
Console.WriteLine("Parameters:");
Console.Write("\n");
Console.WriteLine("-f <filename> - Specify an input file to be used");
Console.WriteLine("-d <path> - Specify a directory to parse (only *.inc files are used)");
Console.WriteLine("-t <filename> - Specify a template file to be used");
Console.WriteLine("-o <filename> - Specify an output file to be used");
Console.WriteLine("-h - Display this help");
Console.WriteLine("-h template - Displays help about templates");
}
static void PrintTemplateHelp()
{
Console.WriteLine("Template File Help:");
Console.WriteLine("The inc parser can read a template file and replace variables with the outputs of it's parse and write into the output file");
Console.Write("\n");
Console.WriteLine("Variables:");
Console.Write("\n");
Console.WriteLine("$defines $enums $enumtypes $forwards $natives $stocks $funcenums $functags $structs");
}
} }
} }

View File

@ -1,14 +1,20 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion> <ProductVersion>9.0.21022</ProductVersion>
<SchemaVersion>2.0</SchemaVersion> <SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{064EA9DC-51DC-4EE5-843B-0E3F7069635E}</ProjectGuid> <ProjectGuid>{064EA9DC-51DC-4EE5-843B-0E3F7069635E}</ProjectGuid>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>incparser</RootNamespace> <RootNamespace>incparser</RootNamespace>
<AssemblyName>incparser</AssemblyName> <AssemblyName>incparser</AssemblyName>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>2.0</OldToolsVersion>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>

View File

@ -1,6 +1,6 @@
 
Microsoft Visual Studio Solution File, Format Version 9.00 Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2005 # Visual C# Express 2008
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "incparser", "incparser.csproj", "{064EA9DC-51DC-4EE5-843B-0E3F7069635E}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "incparser", "incparser.csproj", "{064EA9DC-51DC-4EE5-843B-0E3F7069635E}"
EndProject EndProject
Global Global