ANTLR4 CSharp Lexer produces error with unicode source code files - antlr

I am using the CSharp Java target - i am parsing some Csharp code like this:
List<Token> codeTokens = new ArrayList<Token>();
List<Token> commentTokens = new ArrayList<Token>();
//CharStream cs = CharStreams.fromString(contents);
CharStream cs = CharStreams.fromPath(path);
CSharpLexer lexer = new CSharpLexer(cs);
// recognition error happens here:
List<? extends Token> tokens = lexer.getAllTokens();
List<Token> directiveTokens = new ArrayList<Token>();
ListTokenSource directiveTokenSource = new ListTokenSource(directiveTokens);
CommonTokenStream directiveTokenStream = new CommonTokenStream(directiveTokenSource, CSharpLexer.DIRECTIVE);
CSharpPreprocessorParser preprocessorParser = new CSharpPreprocessorParser(directiveTokenStream);
If my source code is ASCII encoded, it works fine. But if it's UNICODE, even if there's nothing in the file, I always get this error:
line 1:0 token recognition error at: ''
Do I need to configure my Lexer differently? The error comes from Lexer.java => getAllTokens() => nextToken() => getInterpreter().match(_input, _mode);
Again, I get this even with an empty UNICODE-encoded file - but it still contains the U+FEFF character:
$ less ApiUserInfo.cs
<U+FEFF>
ApiUserInfo.cs (END)
Thank you
Angel

Related

allow arabic text in pdf table using itext7 (xamarin android)

I have to put my list data in a table in a pdf file. My data has some Arabic words. When my pdf is generated, the Arabic words don't appear. I searched and found that I need itext7.pdfcalligraph so I installed it in my app. I found this code too https://itextpdf.com/en/blog/technical-notes/displaying-text-different-languages-single-pdf-document and tried to do something similar to allow Arabic words in my table but I couldn't figure it out.
This is a trial code before I apply it to my real list:
var path2 = global::Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
filePath = System.IO.Path.Combine(path2.ToString(), "myfile2.pdf");
stream = new FileStream(filePath, FileMode.Create);
PdfWriter writer = new PdfWriter(stream);
PdfDocument pdf2 = new iText.Kernel.Pdf.PdfDocument(writer);
Document document = new Document(pdf2, PageSize.A4);
FontSet set = new FontSet();
set.AddFont("ARIAL.TTF");
document.SetFontProvider(new FontProvider(set));
document.SetProperty(Property.FONT, "Arial");
string[] sources = new string[] { "يوم","شهر 2020" };
iText.Layout.Element.Table table = new iText.Layout.Element.Table(2, false);
foreach (string source in sources)
{
Paragraph paragraph = new Paragraph();
Bidi bidi = new Bidi(source, Bidi.DirectionDefaultLeftToRight);
if (bidi.BaseLevel != 0)
{
paragraph.SetTextAlignment(iText.Layout.Properties.TextAlignment.RIGHT);
}
paragraph.Add(source);
table.AddCell(new Cell(1, 1).SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER).Add(paragraph));
}
document.Add(table);
document.Close();
I updated my code and added the arial.ttf to my assets folder . i'm getting the following exception:
System.InvalidOperationException: 'FontProvider and FontSet are empty. Cannot resolve font family name (see ElementPropertyContainer#setFontFamily) without initialized FontProvider (see RootElement#setFontProvider).'
and I still can't figure it out. any ideas?
thanks in advance
- C #
I have a similar situation for Turkish characters, and I've followed these
steps :
Create a folder under projects root folder which is : /wwwroot/Fonts
Add OpenSans-Regular.ttf under the Fonts folder
Path for font is => ../wwwroot/Fonts/OpenSans-Regular.ttf
Create font like below :
public static PdfFont CreateOpenSansRegularFont()
{
var path = "{Your absolute path for FONT}";
return PdfFontFactory.CreateFont(path, PdfEncodings.IDENTITY_H, true);
}
and use it like :
paragraph.Add(source)
.SetFont(FontFactory.CreateOpenSansRegularFont()); //set font in here
table.AddCell(new Cell(1, 1)
.SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER)
.Add(paragraph));
This is how I used font factory for Turkish characters ex: "ü,i,ç,ş,ö"
For Xamarin-Android, you could try
string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var path = Path.Combine(documentsPath, "Fonts/Arial.ttf");
Look i fixed it in java,this may help you:
String font = "your Arabic font";
//the magic is in the next 4 lines:
PdfFontFactory.register(font);
FontProgram fontProgram = FontProgramFactory.createFont(font, true);
PdfFont f = PdfFontFactory.createFont(fontProgram, PdfEncodings.IDENTITY_H);
LanguageProcessor languageProcessor = new ArabicLigaturizer();
//and look here how i used setBaseDirection and don't use TextAlignment ,it will work without it
com.itextpdf.kernel.pdf.PdfDocument tempPdfDoc = new com.itextpdf.kernel.pdf.PdfDocument(new PdfReader(pdfFile.getPath()), TempWriter);
com.itextpdf.layout.Document TempDoc = new com.itextpdf.layout.Document(tempPdfDoc);
com.itextpdf.layout.element.Paragraph paragraph0 = new com.itextpdf.layout.element.Paragraph(languageProcessor.process("الاستماره الالكترونية--الاستماره الالكترونية--الاستماره الالكترونية--الاستماره الالكترونية"))
.setFont(f).setBaseDirection(BaseDirection.RIGHT_TO_LEFT)
.setFontSize(15);

Error creating PDF with Zend (fontWithName)

I'm trying to generate a PDF file using Zend but I keep getting errors when trying to set the font.
Here is my code:
$pdf = new Zend_Pdf();
$page = new Zend_Pdf_Page(Zend_Pdf_Page::SIZE_A4);
$font = new Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA);
$page->setFont($font,24)
->drawText("Hello world!",72,720);
$pdf->$page;
$pdf->save("example.pdf");
And this is the error:
Parse error: syntax error, unexpected 'fontWithName' (T_STRING), expecting variable (T_VARIABLE) or '$' in /Users/pawel/Sites/Zend/application/modules/default/controllers/IndexController.php on line 83
I think you can just remove new for the font declaration:
$font = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA);
$style = new Zend_Pdf_Style();
$style->setFont($font, 24);
$page->setStyle($style);
fontWithName is a static function and Zend_Pdf_Font is an abstract class.
See the documentation for example.
There is another problem:
Replace
$pdf->$page;
by
$pdf->pages[] = $page;

ANTLR3 Tree Grammar: loop did not match anything at input 'EOF'

I am trying to create my first ANTLR3 tree grammar, but I keep hitting the same problem. The output of the parser is:
$ echo 'foo, bar' | ./run.sh
foo bar
TreeGrammar.g: node from line 0:0 required (...)+ loop did not match anything at input 'EOF'
Exception in thread "main" java.lang.NullPointerException
at Driver.main(Driver.java:29)
The output clearly shows that the stage-1 parser results in the right tokens ('foo' and 'bar'). Somehow the stage-2 tree-parser refuses to parse the results from stage-1. Since the code is very basic, it must be some simple, dumb oversight at my part ;-)
Here's my simple test code:
Grammar.g:
grammar Grammar;
options {
output = AST;
}
statement: word (','! word)* EOF!;
word: ID;
ID: ('a'..'z'|'A'..'Z')+;
WS: (' ' | '\t' | '\n' | '\r')+ { $channel = HIDDEN; } ;
TreeGrammar.g:
tree grammar TreeGrammar;
options {
tokenVocab = Grammar;
ASTLabelType = CommonTree;
output = template;
}
statement: word+;
word: ID;
Driver.java:
import java.io.*;
import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
import org.antlr.stringtemplate.*;
public class Driver {
public static void main(String[] args) throws Exception {
FileReader groupFileR = new FileReader("Template.stg" );
StringTemplateGroup templates = new StringTemplateGroup(groupFileR);
groupFileR.close();
ANTLRInputStream input = new ANTLRInputStream(System.in);
GrammarLexer lexer = new GrammarLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
GrammarParser parser = new GrammarParser(tokens);
GrammarParser.statement_return result = parser.statement();
CommonTree t = (CommonTree)result.getTree();
System.out.println(t.toStringTree());
CommonTreeNodeStream nodes = new CommonTreeNodeStream(t);
nodes.setTokenStream(tokens);
TreeGrammar walker = new TreeGrammar(nodes);
walker.setTemplateLib(templates);
walker.statement();
TreeGrammar.statement_return r2 = walker.statement();
StringTemplate output = (StringTemplate) r2.getTemplate();
System.out.println(output.toString());
}
}
Assuming your Stringtemplate groups is properly formed, your problem is most probably the fatc you walk your AST twice:
walker.statement();
TreeGrammar.statement_return r2 = walker.statement();
E.g., you call walker.statement() twice. This is what the (first) error is telling you:
TreeGrammar.g: node from line 0:0 required (...)+ loop did not match anything at input 'EOF'
You consume the input once with walker.statement() resulting the node stream is at the end (EOF), and then you call walker.statement() again and it expects tow walk word+ again, yet there's only a EOF left.

Eclipse AST not changing files which are not opened in eclipse

I am trying to modify source code using eclipse plugin, JDT and AST (Abstract Syntax Tree). I can read all Java files and make operation on all those file, But when i am saving those changes (Edits) in to files using
TextEdit edits = rewriter.rewriteAST();
// apply the text edits to the compilation unit
edits.apply(document);
iCompilationUnit.getBuffer().setContents(document.get());
It only make changes in file those are open in eclipse in unsaved mode. Rest of files are not affected.
Find my code snippet below:
CompilationUnit cu = parse(iCompilationUnit);
MethodVisitor visitor = new MethodVisitor();
cu.accept(visitor);
String source = iCompilationUnit.getSource();
Document document= new Document(source);
ASTRewrite rewriter = ASTRewrite.create(cu.getAST());
cu.recordModifications();
for (MethodDeclaration methodDeclaration : visitor.getMethods()) {
System.out.print("Method name: " + methodDeclaration.getName()
+ " Return type: " + methodDeclaration.getReturnType2());
MethodDeclaration methodDecl = methodDeclaration;
Block block = methodDecl.getBody();
ListRewrite listRewrite = rewriter.getListRewrite(block, Block.STATEMENTS_PROPERTY);
Statement placeHolder = (Statement) rewriter.createStringPlaceholder("System.out.println(\"Test Print\");", ASTNode.EMPTY_STATEMENT);
listRewrite.insertFirst(placeHolder, null);
}
TextEdit edits = rewriter.rewriteAST();
// apply the text edits to the compilation unit
edits.apply(document);
iCompilationUnit.getBuffer().setContents(document.get());
Try to:
Apply the TextEdit directly to the ICompilationUnit instead of using Document.
Use ICompilationUnit.commitWorkingCopy to save the changes
I use code similar to this:
iCompilationUnit.becomeWorkingCopy(new NullProgressMonitor());
CompilationUnit cu = parse(iCompilationUnit);
ASTRewrite rewriter = ASTRewrite.create(cu.getAST());
... process AST ...
iCompilationUnit.applyTextEdit(rewrite.rewriteAST(), new NullProgressMonitor());
iCompilationUnit.commitWorkingCopy(false, new NullProgressMonitor());

Adobe AIR NativeProcess fails with spaces in arguments?

I have a problem running the NativeProcess if I put spaces in the arguments
if (Capabilities.os.toLowerCase().indexOf("win") > -1)
{
fPath = "C:\\Windows\\System32\\cmd.exe";
args.push("/c");
args.push(scriptDir.resolvePath("helloworld.bat").nativePath);
}
file = new File(fPath);
var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
nativeProcessStartupInfo.executable = file;
args.push("blah");
nativeProcessStartupInfo.arguments = args;
process = new NativeProcess();
process.start(nativeProcessStartupInfo);
in the above code, if I use
args.push("blah") everything works fine
if I use
args.push("blah blah") the program breaks as if the file wasn't found.
Seems like I'm not the only one:
http://tech.groups.yahoo.com/group/flexcoders/message/159521
As one of the users their pointed out, it really seems like an awful limitation by a cutting edge SDK of 21st century. Even Alex Harui didn't have the answer there and he's known to workaround every Adobe bug:)
Any ideas?
I am using AIR 2.6 SDK in JavaScript like this, and it is working fine even for spaces.
please check your code with this one.
var file = air.File.applicationDirectory;
file = file.resolvePath("apps");
if (air.Capabilities.os.toLowerCase().indexOf("win") > -1)
{
file = file.resolvePath(appFile);
}
var nativeProcessStartupInfo = new air.NativeProcessStartupInfo();
nativeProcessStartupInfo.executable = file;
var args =new air.Vector["<String>"]();
for(i=0; i<arguments.length; i++)
args.push(arguments[i]);
nativeProcessStartupInfo.arguments = args;
process = new air.NativeProcess();
process.addEventListener(air.ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData);
process.addEventListener(air.ProgressEvent.STANDARD_INPUT_PROGRESS, inputProgressListener);
process.start(nativeProcessStartupInfo);
To expand on this: The reason that this works (see post above):
var args =new air.Vector["<String>"]();
for(i=0; i<arguments.length; i++)
args.push(arguments[i]);
nativeProcessStartupInfo.arguments = args;
is that air expects that the arguments being passed to the nativeProcess are delimited by spaces. It chokes if you pass "C:\folder with spaces\myfile.doc" (and BTW for AIR a file path for windows needs to be "C:\\folder with spaces\\myfile.doc") you would need to do this:
args.push("C:\\folder");
args.push("with");
args.push("spaces\\myfile.doc");
Hence, something like this works:
var processArgs = new air.Vector["<String>"]();
var path = "C:\\folder with spaces\\myfile.doc"
var args = path.split(" ")
for (var i=0; i<args.length; i++) {
processArgs.push(args[i]);
};
UPDATE - SOLUTION
The string generated by the File object by either nativePath or resolvePath uses "\" for the path. Replace "\" with "/" and it works.
I'm having the same problem trying to call 7za.exe using NativeProcess. If you try to access various windows directories the whole thing fails horribly. Even trying to run command.exe and calling a batch file fails because you still have to try to pass a path with spaces through "arguments" on the NativeProcessStartupInfo object.
I've spent the better part of a day trying to get this to work and it will not work. Whatever happens to spaces in "arguments" totally destroys the path.
Example 7za.exe from command line:
7za.exe a MyZip.7z "D:\docs\My Games\Some Game Title\Maps\The Map.map"
This works fine. Now try that with Native Process in AIR. The AIR arguments sanitizer is FUBAR.
I have tried countless ways to put in arguments and it just fails. Interesting I can get it to spit out a zip file but with no content in the zip. I figure this is due to the first argument set finally working but then failing for the path argument.
For example:
processArgs[0] = 'a';
processArgs[1] = 'D:\apps\flash builder 4.5\project1\bin-debug\MyZip.7z';
processArgs[2] = 'D:\docs\My Games\Some Game Title\Maps\The Map.map';
For some reason this spits out a zip file named: bin-debugMyZip.7z But the zip is empty.
Whatever AIR is doing it is fraking up path strings. I've tried adding quotes around those paths in various ways. Nothing works.
I thought I could fall back on calling a batch file from this example:
http://technodesk.wordpress.com/2010/04/15/air-2-0-native-process-batch-file/
But it fails as well because it still requires the path to be passed through arguments.
Anyone have any luck calling 7z or dealing with full paths in the NativeProcess? All these little happy tutorials don't deal with real windows folder structure.
Solution that works for me - set path_with_space as "nativeProcessStartupInfo.workingDirectory" property. See example below:
public function openPdf(pathToPdf:String):void
}
var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
var file:File = File.applicationDirectory.resolvePath("C:\\Windows\\System32\\cmd.exe");
nativeProcessStartupInfo.executable = file;
if (Capabilities.os.toLowerCase().indexOf("win") > -1)
{
nativeProcessStartupInfo.workingDirectory = File.applicationDirectory.resolvePath(pathToPdf).parent;
var processArgs:Vector.<String> = new Vector.<String>();
processArgs[0] = "/k";
processArgs[1] = "start";
processArgs[2] = "test.pdf";
nativeProcessStartupInfo.arguments = processArgs;
process = new NativeProcess();
process.start(nativeProcessStartupInfo);
process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData);
}
args.push( '"blah blah"' );
Command line after all supports spaces if they are nested whithin "".
So if lets say you have a file argument :
'test/folder with space/blah'
Convert it to the following
'test/"folder with space"/blah'
Optionally use a filter:
I once had a problem like this in AIR, i just simply filter the text before i push it into the array. My refrence use CASA lib though
import org.casalib.util.ArrayUtil;
http://casalib.org/
/**
* Filters a string input for 'safe handling', and returns it
**/
public function stringFilter(inString:String, addPermitArr:Array = null, permitedArr:Array = null):String {
var sourceArr:Array = inString.split(''); //Splits the string input up
var outArr:Array = new Array();
if(permitedArr == null) {
permitedArr = ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" as String).split('');
}
if( addPermitArr != null ) {
permitedArr = permitedArr.concat( addPermitArr );
}
for(var i:int = 0; i < sourceArr.length; i++) {
if( ArrayUtil.contains( permitedArr, sourceArr[i] ) != 0 ) { //it is allowed
outArr.push( sourceArr[i] );
}
}
return (outArr.join('') as String);
}
And just filter it via
args.push( stringFilter( 'blah blah', new Array('.') ) );
Besides, it is really bad practice to use spaces in file names / arguments, use '_' instead. This seems to be originating from linux though. (The question of spaces in file names)
This works for me on Windws7:
var Xargs:Array = String("/C#echo#a trully hacky way to do this :)#>#C:\\Users\\Benjo\\AppData\\Roaming\\com.eblagajna.eBlagajna.POS\\Local Store\\a.a").split("#");
var args:Vector.<String> = new Vector.<String>();
for (var i:int=0; i<Xargs.length; i++) {
trace("Pushing: "+Xargs[i]);
args.push(Xargs[i]);
};
NPI.arguments = args;
If your application path or parameter contains spaces, make sure to wrap it in quotes. For example path of the application has spaces C:\Program Files (x86)\Camera\Camera.exe use quotes like:
"C:\Program Files (x86)\Camera\Camera.exe"