From 5338449ca2035fff1b3445c91524ba33b71ba3fd Mon Sep 17 00:00:00 2001 From: Artem3213212 Date: Sun, 26 Aug 2018 22:05:46 +0300 Subject: [PATCH] Init --- .gitignore | 84 +++++++ AG.PascalTokeniser.pas | 243 ++++++++++++++++++++ DOC_EN.MD | 0 DelphiTests/MainTest.pas | 26 +++ DelphiTests/Tests.dpr | 60 +++++ DelphiTests/Tests.dproj | 477 +++++++++++++++++++++++++++++++++++++++ README.md | 6 +- 7 files changed, 895 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 AG.PascalTokeniser.pas create mode 100644 DOC_EN.MD create mode 100644 DelphiTests/MainTest.pas create mode 100644 DelphiTests/Tests.dpr create mode 100644 DelphiTests/Tests.dproj diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5b1ff05 --- /dev/null +++ b/.gitignore @@ -0,0 +1,84 @@ +# Uncomment these types if you want even more clean repository. But be careful. +# Uncomment these types if you want even more clean repository. But be careful. +# It can make harm to an existing project source. Read explanations below. +# +# Resource files are binaries containing manifest, project icon and version info. +# They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files. +#*.res +# +# Type library file (binary). In old Delphi versions it should be stored. +# Since Delphi 2009 it is produced from .ridl file and can safely be ignored. +#*.tlb +# +# Diagram Portfolio file. Used by the diagram editor up to Delphi 7. +# Uncomment this if you are not using diagrams or use newer Delphi version. +#*.ddp +# +# Visual LiveBindings file. Added in Delphi XE2. +# Uncomment this if you are not using LiveBindings Designer. +#*.vlb +# +# Deployment Manager configuration file for your project. Added in Delphi XE2. +# Uncomment this if it is not mobile development and you do not use remote debug feature. +#*.deployproj +# +# C++ object files produced when C/C++ Output file generation is configured. +# Uncomment this if you are not using external objects (zlib library for example). +#*.obj +# + +# Delphi compiler-generated binaries (safe to delete) +*.exe +*.dll +*.bpl +*.bpi +*.dcp +*.so +*.apk +*.drc +*.map +*.dres +*.rsm +*.tds +*.dcu +*.lib +*.a +*.o +*.ocx +Temp/ +*.tmp + +*.res + +# Delphi autogenerated files (duplicated info) +*.cfg +*.hpp +*Resource.rc + +# Delphi local files (user-specific info) +*.local +*.identcache +*.projdata +*.tvsconfig +*.dsk + +# Delphi history and backups +__history/ +__recovery/ +*.~* + +# Castalia statistics file (since XE7 Castalia is distributed with Delphi) +*.stat + +#FPC +backup/ +*.compiled +*.ppu +*.o +*.or +FPCTests/*.ico +*.ini + +Tests/Win32 +!FasmDll/* +!FasmDll/DEMO/* \ No newline at end of file diff --git a/AG.PascalTokeniser.pas b/AG.PascalTokeniser.pas new file mode 100644 index 0000000..24adfea --- /dev/null +++ b/AG.PascalTokeniser.pas @@ -0,0 +1,243 @@ +unit AG.PascalTokeniser; + +interface + +implementation + +(* +# +# PyPascalTokenizer +# Author: Artem Gavrilov (@Artem3213212) +# License: MPL 2.0 +# + +import queue, threading + +SYMS1 = ['(',')','[',']','/','|','\\','@','#','=','>','<',':',';',',','.','$','+','-','*'] +SYMS2 = ['>=','<=','<>',':=','..','-=','+=','/=','*='] +SPACES = ['\f','\n','\r','\t','\v',' '] +NO_NAME_SYMS = SYMS1 + SPACES + ['{','}'] +CHARS_ID0 = '&abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_' +CHARS_ID = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_' + +def is_comment(s): + if type(s) is list: + return True + else: + return s.startswith('{') or s.startswith('(*') or s.startswith('//') + +def is_name(s): + if len(s)<=0: + return False + if s=='&': + return False + if not (s[0] in CHARS_ID0): + return False + for i in s[1:]: + if not (i in CHARS_ID): + return False + return True + +def is_string(s): + return s.startswith("'") + +class PasTokenizer(): + def __init__(self, s): + self.s, self.y, self.x, self.ended = s, 0, 0, False + self._skip_spaces() + + def _do_readable(self): + if not self._is_readable(): + if self.y+1 == len(self.s): + self.ended = True + else: + self.y+=1 + self.x=0 + while not self.s[self.y]: + if self.y+1 == len(self.s): + self.ended = True + break + self.y+=1 + return True + else: + return False + + def _is_readable(self): + return len(self.s[self.y])>self.x + + def _next_readable(self): + self.x+=1 + return self._do_readable() + + def _skip_spaces(self): + self._do_readable() + if not self.ended: + while self.s[self.y][self.x] in SPACES: + self._next_readable() + + def _get_pos(self): + return self.y, self.x + + def _set_pos(self, i0, i1): + self.y, self.x, self.ended = i0, i1, False + self._do_readable() + + def get_next(self): + begin_pos = self._get_pos() + ml, ss, f = '', '', True + str_changed = False + while f and not self.ended: + line = self.s[self.y] + now_sym = line[self.x] + l = len(line) + if self.x+1 != l: + next_sym = line[self.x+1] + else: + next_sym = '' + if ml == '': + if now_sym == '/': + if next_sym == '/': + ss = line[self.x:] + self.x = l + break + elif now_sym == '{': + ml = '}' + ss=[now_sym] + last_i0 = self.y + elif now_sym == '(': + if next_sym == '*': + ml = ')' + self.x+=1 + last_i0 = self.y + ss = [now_sym+next_sym] + else: + ss = '(' + self.x+=1 + break + else: + if now_sym in SYMS1: + ss = now_sym + self.x+=1 + if now_sym + next_sym in SYMS2: + self.x+=1 + ss = ss + next_sym + break + elif now_sym=="'": + ss="'" + self.x+=1 + if next_sym!='': + ss = ss + next_sym + while line[self.x]!="'": + self.x+=1 + if not self._is_readable(): + self.x-=1 + break + ss = ss + line[self.x] + self.x+=1 + break + else: + while not(line[self.x] in NO_NAME_SYMS): + ss=ss+line[self.x] + self.x+=1 + if not self._is_readable(): + break + break + else: + while last_i0!=self.y: + ss.append('') + last_i0+=1 + ss[-1] = ss[-1] + now_sym + if now_sym==ml: + if ml=='}': + self.x+=1 + break + elif self.x!=0: + if line[self.x-1]=='*': + self.x+=1 + break + self._next_readable() + if len(ss)==1: + ss=ss[0] + ss=(ss,begin_pos,self._get_pos(),self.ended) + self._skip_spaces() + return ss + + def read_next(self): + i0, i1 = self._get_pos() + z = self.get_next() + self._set_pos(i0, i1) + return z + + def is_ended(self): + return self.ended + +class PasTokenizerStack(): + def __init__(self, s, comments=True): + self.main = PasTokenizer(s) + self.stack = [] + if comments: + self._pop = self._get_with_comments + else: + self._pop = self._get_without_comments + + def _get_with_comments(self): + return self.main.get_next() + + def _get_without_comments(self): + while True: + s = self.main.get_next() + if not is_comment(s[0]): + return s + if s[3]: + return ('',(0,0),(0,0),True) + + def push(self, s): + self.stack.append(s) + + def pop(self): + if self.stack: + return self.stack.pop() + else: + return self._pop() + + def read_last(self): + if not self.stack: + self.stack.append(self._pop()) + return self.stack[-1] + + def is_ended(self): + return self.stack and self.main.is_ended() + +class PasTokenizerParallelStack(PasTokenizerStack): + def __init__(self, s, comments = True, qlong = 1000): + super(PasTokenizerParallelStack,self).__init__(s, comments) + self.queue = queue.Queue(qlong) + th = threading.Thread(target = self._work, args = (self,)) + th.start() + + def _get_with_comments(self): + s = self.queue.get() + return s + + def _get_without_comments(self): + while True: + s = self.queue.get() + if not is_comment(s[0]): + return s + if s[3]: + return ('',(0,0),(0,0),True) + + def _work(self,s): + while not self.main.is_ended(): + self.queue.put(self.main.get_next()) + self.queue.put(('',(0,0),(0,0),True)) + + def is_ended(self): + return self.stack and self.main.is_ended()and self.queue.empty() + + def stop(self): + self.main.ended = True + self.queue.task_done() +*) + +end. diff --git a/DOC_EN.MD b/DOC_EN.MD new file mode 100644 index 0000000..e69de29 diff --git a/DelphiTests/MainTest.pas b/DelphiTests/MainTest.pas new file mode 100644 index 0000000..108abe7 --- /dev/null +++ b/DelphiTests/MainTest.pas @@ -0,0 +1,26 @@ +unit MainTest; + +interface +uses + DUnitX.TestFramework; + +type + [TestFixture] + TMyTestObject = class(TObject) + public + // Sample Methods + // Simple single Test + [Test] + procedure Test1; + // Test with TestCase Atribute to supply parameters. + end; + +implementation + +procedure TMyTestObject.Test1; +begin +end; + +initialization + TDUnitX.RegisterTestFixture(TMyTestObject); +end. diff --git a/DelphiTests/Tests.dpr b/DelphiTests/Tests.dpr new file mode 100644 index 0000000..2f25df5 --- /dev/null +++ b/DelphiTests/Tests.dpr @@ -0,0 +1,60 @@ +program Tests; + +{$IFNDEF TESTINSIGHT} +{$APPTYPE CONSOLE} +{$ENDIF}{$STRONGLINKTYPES ON} +uses + SysUtils, + {$IFDEF TESTINSIGHT} + TestInsight.DUnitX, + {$ENDIF } + DUnitX.Loggers.Console, + DUnitX.Loggers.Xml.NUnit, + DUnitX.TestFramework, + MainTest in 'MainTest.pas', + AGPascalTokeniser in '..\AGPascalTokeniser.pas'; + +var + runner : ITestRunner; + results : IRunResults; + logger : ITestLogger; + nunitLogger : ITestLogger; +begin +{$IFDEF TESTINSIGHT} + TestInsight.DUnitX.RunRegisteredTests; + exit; +{$ENDIF} + try + //Check command line options, will exit if invalid + TDUnitX.CheckCommandLine; + //Create the test runner + runner := TDUnitX.CreateRunner; + //Tell the runner to use RTTI to find Fixtures + runner.UseRTTI := True; + //tell the runner how we will log things + //Log to the console window + logger := TDUnitXConsoleLogger.Create(true); + runner.AddLogger(logger); + //Generate an NUnit compatible XML File + nunitLogger := TDUnitXXMLNUnitFileLogger.Create(TDUnitX.Options.XMLOutputFile); + runner.AddLogger(nunitLogger); + runner.FailsOnNoAsserts := False; //When true, Assertions must be made during tests; + + //Run tests + results := runner.Execute; + if not results.AllPassed then + System.ExitCode := EXIT_ERRORS; + + {$IFNDEF CI} + //We don't want this happening when running under CI. + if TDUnitX.Options.ExitBehavior = TDUnitXExitBehavior.Pause then + begin + System.Write('Done.. press key to quit.'); + System.Readln; + end; + {$ENDIF} + except + on E: Exception do + System.Writeln(E.ClassName, ': ', E.Message); + end; +end. diff --git a/DelphiTests/Tests.dproj b/DelphiTests/Tests.dproj new file mode 100644 index 0000000..8e427c8 --- /dev/null +++ b/DelphiTests/Tests.dproj @@ -0,0 +1,477 @@ + + + {D45A1419-D0B2-4C03-89FD-530EF21B4F7D} + 17.2 + Tests.dpr + True + Debug + Win32 + 1 + Console + None + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + $(DUnitX);$(DCC_UnitSearchPath) + $(BDS)\bin\delphi_PROJECTICON.ico + System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + $(BDS)\bin\delphi_PROJECTICNS.icns + true + Tests + .\$(Platform)\$(Config) + .\$(Platform)\$(Config) + false + false + false + false + false + + + FireDACTDataDriver;FireDACSqliteDriver;FireDACDSDriver;DBXSqliteDriver;FireDACPgDriver;fmx;IndySystem;tethering;DBXInterBaseDriver;DataSnapClient;DataSnapCommon;DataSnapServer;DataSnapProviderClient;DbxCommonDriver;dbxcds;fmxFireDAC;DBXOracleDriver;CustomIPTransport;dsnap;IndyIPServer;fmxase;IndyCore;CloudService;IndyIPCommon;FmxTeeUI;FireDACIBDriver;DataSnapFireDAC;FireDACDBXDriver;soapserver;inetdbxpress;dsnapxml;FireDACASADriver;bindcompfmx;FireDACODBCDriver;RESTBackendComponents;emsclientfiredac;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;inetdb;ibmonitor;xmlrtl;DataSnapNativeClient;ibxpress;IndyProtocols;DBXMySQLDriver;FireDACCommonDriver;bindcompdbx;bindengine;FMXTee;soaprtl;emsclient;FireDAC;DBXInformixDriver;FireDACMSSQLDriver;DataSnapServerMidas;DBXFirebirdDriver;inet;fmxobj;FireDACMySQLDriver;soapmidas;DBXSybaseASADriver;FireDACOracleDriver;fmxdae;RESTComponents;dbexpress;DataSnapIndy10ServerTransport;IndyIPClient;$(DCC_UsePackage) + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + 1033 + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + FireDACTDataDriver;FireDACSqliteDriver;FireDACDSDriver;frxTee22;DBXSqliteDriver;FireDACPgDriver;fmx;IndySystem;TeeDB;tethering;vclib;DBXInterBaseDriver;DataSnapClient;DataSnapCommon;DataSnapServer;DataSnapProviderClient;DBXSybaseASEDriver;frxe22;DbxCommonDriver;vclimg;dbxcds;DatasnapConnectorsFreePascal;appanalytics;DOSCommandDR;vcldb;vcldsnap;fmxFireDAC;DBXDb2Driver;DBXOracleDriver;CustomIPTransport;vclribbon;dsnap;IndyIPServer;fmxase;vcl;IndyCore;DBXMSSQLDriver;CloudService;IndyIPCommon;FmxTeeUI;FireDACIBDriver;CodeSiteExpressPkg;DataSnapFireDAC;FireDACDBXDriver;soapserver;inetdbxpress;OmniThreadLibraryRuntime;dsnapxml;FireDACInfxDriver;FireDACDb2Driver;adortl;FireDACASADriver;frx22;bindcompfmx;FireDACODBCDriver;RESTBackendComponents;emsclientfiredac;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;inetdb;Tee;DBXOdbcDriver;ibmonitor;vclFireDAC;xmlrtl;DataSnapNativeClient;ibxpress;svnui;IndyProtocols;DBXMySQLDriver;FireDACCommonDriver;bindcompdbx;bindengine;vclactnband;FMXTee;soaprtl;TeeUI;bindcompvcl;vclie;frxDB22;FireDACADSDriver;vcltouch;emsclient;VCLRESTComponents;FireDAC;DBXInformixDriver;FireDACMSSQLDriver;Intraweb;VclSmp;DataSnapConnectors;DataSnapServerMidas;DBXFirebirdDriver;dsnapcon;inet;fmxobj;FireDACMySQLDriver;soapmidas;vclx;svn;DBXSybaseASADriver;FireDACOracleDriver;fmxdae;RESTComponents;dbexpress;FireDACMSAccDriver;DataSnapIndy10ServerTransport;IndyIPClient;$(DCC_UsePackage) + + + FireDACTDataDriver;FireDACSqliteDriver;FireDACDSDriver;DBXSqliteDriver;FireDACPgDriver;fmx;IndySystem;TeeDB;tethering;vclib;DBXInterBaseDriver;DataSnapClient;DataSnapCommon;DataSnapServer;DataSnapProviderClient;DBXSybaseASEDriver;DbxCommonDriver;vclimg;dbxcds;DatasnapConnectorsFreePascal;appanalytics;DOSCommandDR;vcldb;vcldsnap;fmxFireDAC;DBXDb2Driver;DBXOracleDriver;CustomIPTransport;vclribbon;dsnap;IndyIPServer;fmxase;vcl;IndyCore;DBXMSSQLDriver;CloudService;IndyIPCommon;FmxTeeUI;FireDACIBDriver;DataSnapFireDAC;FireDACDBXDriver;soapserver;inetdbxpress;OmniThreadLibraryRuntime;dsnapxml;FireDACInfxDriver;FireDACDb2Driver;adortl;FireDACASADriver;bindcompfmx;FireDACODBCDriver;RESTBackendComponents;emsclientfiredac;rtl;dbrtl;DbxClientDriver;FireDACCommon;bindcomp;inetdb;Tee;DBXOdbcDriver;ibmonitor;vclFireDAC;xmlrtl;DataSnapNativeClient;ibxpress;IndyProtocols;DBXMySQLDriver;FireDACCommonDriver;bindcompdbx;bindengine;vclactnband;FMXTee;soaprtl;TeeUI;bindcompvcl;vclie;FireDACADSDriver;vcltouch;emsclient;VCLRESTComponents;FireDAC;DBXInformixDriver;FireDACMSSQLDriver;Intraweb;VclSmp;DataSnapConnectors;DataSnapServerMidas;DBXFirebirdDriver;dsnapcon;inet;fmxobj;FireDACMySQLDriver;soapmidas;vclx;DBXSybaseASADriver;FireDACOracleDriver;fmxdae;RESTComponents;dbexpress;FireDACMSAccDriver;DataSnapIndy10ServerTransport;IndyIPClient;$(DCC_UsePackage) + + + DEBUG;$(DCC_Define) + true + false + true + true + true + + + false + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + + MainSource + + + + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + + + + Delphi.Personality.12 + Console + + + + Tests.dpr + + + + + + true + + + + + true + + + + + Tests.exe + true + + + + + true + + + + + 1 + .dylib + + + 0 + .bpl + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + + + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + + + 1 + + + 1 + + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + res\drawable-normal + 1 + + + + + library\lib\x86 + 1 + + + + + 1 + + + 1 + + + 1 + + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + 1 + + + + + res\drawable-xlarge + 1 + + + + + res\drawable-xhdpi + 1 + + + + + 1 + + + 1 + + + 1 + + + + + res\drawable-xxhdpi + 1 + + + + + library\lib\mips + 1 + + + + + res\drawable + 1 + + + + + 1 + + + 1 + + + 0 + + + + + 1 + .framework + + + 0 + + + + + res\drawable-small + 1 + + + + + + 1 + + + Contents\MacOS + 0 + + + + + classes + 1 + + + + + + 1 + + + 1 + + + 1 + + + + + res\drawable + 1 + + + + + Contents\Resources + 1 + + + + + + 1 + + + 1 + + + 1 + + + + + library\lib\armeabi-v7a + 1 + + + 1 + + + 0 + + + 1 + + + 1 + + + 1 + + + + + library\lib\armeabi + 1 + + + + + res\drawable-large + 1 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 1 + + + 1 + + + 1 + + + + + res\drawable-ldpi + 1 + + + + + res\values + 1 + + + + + 1 + + + 1 + + + 1 + + + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + + + 1 + + + + + + + + + + + + False + True + False + + + 12 + + + + + diff --git a/README.md b/README.md index 4a9abb7..8aed042 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ # AGPascalTokeniser -Tokenizer for Pascal syntax (Delphi/FreePascal) written for Delphi or FreePascal \ No newline at end of file +Tokenizer for Pascal syntax (Delphi/FreePascal) written for Delphi or FreePascal + +Donate: https://money.yandex.ru/to/410014959153552 + +Site: http://teamfnd.ru \ No newline at end of file